ospf_lsdb.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. /*
  2. * OSPF LSDB support.
  3. * Copyright (C) 1999, 2000 Alex Zinin, Kunihiro Ishiguro, Toshiaki Takada
  4. *
  5. * This file is part of GNU Zebra.
  6. *
  7. * GNU Zebra is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by the
  9. * Free Software Foundation; either version 2, or (at your option) any
  10. * later version.
  11. *
  12. * GNU Zebra is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with GNU Zebra; see the file COPYING. If not, write to the Free
  19. * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  20. * 02111-1307, USA.
  21. */
  22. #include <zebra.h>
  23. #include "prefix.h"
  24. #include "table.h"
  25. #include "memory.h"
  26. #include "log.h"
  27. #include "ospfd/ospfd.h"
  28. #include "ospfd/ospf_asbr.h"
  29. #include "ospfd/ospf_lsa.h"
  30. #include "ospfd/ospf_lsdb.h"
  31. struct ospf_lsdb *
  32. ospf_lsdb_new ()
  33. {
  34. struct ospf_lsdb *new;
  35. new = XCALLOC (MTYPE_OSPF_LSDB, sizeof (struct ospf_lsdb));
  36. ospf_lsdb_init (new);
  37. return new;
  38. }
  39. void
  40. ospf_lsdb_init (struct ospf_lsdb *lsdb)
  41. {
  42. int i;
  43. for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
  44. lsdb->type[i].db = route_table_init ();
  45. }
  46. void
  47. ospf_lsdb_free (struct ospf_lsdb *lsdb)
  48. {
  49. ospf_lsdb_cleanup (lsdb);
  50. XFREE (MTYPE_OSPF_LSDB, lsdb);
  51. }
  52. void
  53. ospf_lsdb_cleanup (struct ospf_lsdb *lsdb)
  54. {
  55. int i;
  56. assert (lsdb);
  57. assert (lsdb->total == 0);
  58. ospf_lsdb_delete_all (lsdb);
  59. for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
  60. route_table_finish (lsdb->type[i].db);
  61. }
  62. static void
  63. lsdb_prefix_set (struct prefix_ls *lp, struct ospf_lsa *lsa)
  64. {
  65. memset (lp, 0, sizeof (struct prefix_ls));
  66. lp->family = 0;
  67. lp->prefixlen = 64;
  68. lp->id = lsa->data->id;
  69. lp->adv_router = lsa->data->adv_router;
  70. }
  71. static void
  72. ospf_lsdb_delete_entry (struct ospf_lsdb *lsdb, struct route_node *rn)
  73. {
  74. struct ospf_lsa *lsa = rn->info;
  75. if (!lsa)
  76. return;
  77. assert (rn->table == lsdb->type[lsa->data->type].db);
  78. if (IS_LSA_SELF (lsa))
  79. lsdb->type[lsa->data->type].count_self--;
  80. lsdb->type[lsa->data->type].count--;
  81. lsdb->type[lsa->data->type].checksum -= ntohs(lsa->data->checksum);
  82. lsdb->total--;
  83. rn->info = NULL;
  84. route_unlock_node (rn);
  85. #ifdef MONITOR_LSDB_CHANGE
  86. if (lsdb->del_lsa_hook != NULL)
  87. (* lsdb->del_lsa_hook)(lsa);
  88. #endif /* MONITOR_LSDB_CHANGE */
  89. ospf_lsa_unlock (&lsa); /* lsdb */
  90. return;
  91. }
  92. /* Add new LSA to lsdb. */
  93. void
  94. ospf_lsdb_add (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
  95. {
  96. struct route_table *table;
  97. struct prefix_ls lp;
  98. struct route_node *rn;
  99. table = lsdb->type[lsa->data->type].db;
  100. lsdb_prefix_set (&lp, lsa);
  101. rn = route_node_get (table, (struct prefix *)&lp);
  102. /* nothing to do? */
  103. if (rn->info && rn->info == lsa)
  104. return;
  105. /* purge old entry? */
  106. if (rn->info)
  107. ospf_lsdb_delete_entry (lsdb, rn);
  108. if (IS_LSA_SELF (lsa))
  109. lsdb->type[lsa->data->type].count_self++;
  110. lsdb->type[lsa->data->type].count++;
  111. lsdb->total++;
  112. #ifdef MONITOR_LSDB_CHANGE
  113. if (lsdb->new_lsa_hook != NULL)
  114. (* lsdb->new_lsa_hook)(lsa);
  115. #endif /* MONITOR_LSDB_CHANGE */
  116. lsdb->type[lsa->data->type].checksum += ntohs(lsa->data->checksum);
  117. rn->info = ospf_lsa_lock (lsa); /* lsdb */
  118. }
  119. void
  120. ospf_lsdb_delete (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
  121. {
  122. struct route_table *table;
  123. struct prefix_ls lp;
  124. struct route_node *rn;
  125. if (!lsdb)
  126. {
  127. zlog_warn ("%s: Called with NULL LSDB", __func__);
  128. if (lsa)
  129. zlog_warn ("LSA[Type%d:%s]: LSA %p, lsa->lsdb %p",
  130. lsa->data->type, inet_ntoa (lsa->data->id),
  131. lsa, lsa->lsdb);
  132. return;
  133. }
  134. if (!lsa)
  135. {
  136. zlog_warn ("%s: Called with NULL LSA", __func__);
  137. return;
  138. }
  139. table = lsdb->type[lsa->data->type].db;
  140. lsdb_prefix_set (&lp, lsa);
  141. rn = route_node_lookup (table, (struct prefix *) &lp);
  142. if (rn && (rn->info == lsa))
  143. {
  144. ospf_lsdb_delete_entry (lsdb, rn);
  145. route_unlock_node (rn); /* route_node_lookup */
  146. }
  147. }
  148. void
  149. ospf_lsdb_delete_all (struct ospf_lsdb *lsdb)
  150. {
  151. struct route_table *table;
  152. struct route_node *rn;
  153. int i;
  154. for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
  155. {
  156. table = lsdb->type[i].db;
  157. for (rn = route_top (table); rn; rn = route_next (rn))
  158. if (rn->info != NULL)
  159. ospf_lsdb_delete_entry (lsdb, rn);
  160. }
  161. }
  162. void
  163. ospf_lsdb_clean_stat (struct ospf_lsdb *lsdb)
  164. {
  165. struct route_table *table;
  166. struct route_node *rn;
  167. struct ospf_lsa *lsa;
  168. int i;
  169. for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
  170. {
  171. table = lsdb->type[i].db;
  172. for (rn = route_top (table); rn; rn = route_next (rn))
  173. if ((lsa = (rn->info)) != NULL)
  174. lsa->stat = LSA_SPF_NOT_EXPLORED;
  175. }
  176. }
  177. struct ospf_lsa *
  178. ospf_lsdb_lookup (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
  179. {
  180. struct route_table *table;
  181. struct prefix_ls lp;
  182. struct route_node *rn;
  183. struct ospf_lsa *find;
  184. table = lsdb->type[lsa->data->type].db;
  185. lsdb_prefix_set (&lp, lsa);
  186. rn = route_node_lookup (table, (struct prefix *) &lp);
  187. if (rn)
  188. {
  189. find = rn->info;
  190. route_unlock_node (rn);
  191. return find;
  192. }
  193. return NULL;
  194. }
  195. struct ospf_lsa *
  196. ospf_lsdb_lookup_by_id (struct ospf_lsdb *lsdb, u_char type,
  197. struct in_addr id, struct in_addr adv_router)
  198. {
  199. struct route_table *table;
  200. struct prefix_ls lp;
  201. struct route_node *rn;
  202. struct ospf_lsa *find;
  203. table = lsdb->type[type].db;
  204. memset (&lp, 0, sizeof (struct prefix_ls));
  205. lp.family = 0;
  206. lp.prefixlen = 64;
  207. lp.id = id;
  208. lp.adv_router = adv_router;
  209. rn = route_node_lookup (table, (struct prefix *) &lp);
  210. if (rn)
  211. {
  212. find = rn->info;
  213. route_unlock_node (rn);
  214. return find;
  215. }
  216. return NULL;
  217. }
  218. struct ospf_lsa *
  219. ospf_lsdb_lookup_by_id_next (struct ospf_lsdb *lsdb, u_char type,
  220. struct in_addr id, struct in_addr adv_router,
  221. int first)
  222. {
  223. struct route_table *table;
  224. struct prefix_ls lp;
  225. struct route_node *rn;
  226. struct ospf_lsa *find;
  227. table = lsdb->type[type].db;
  228. memset (&lp, 0, sizeof (struct prefix_ls));
  229. lp.family = 0;
  230. lp.prefixlen = 64;
  231. lp.id = id;
  232. lp.adv_router = adv_router;
  233. if (first)
  234. rn = route_top (table);
  235. else
  236. {
  237. rn = route_node_get (table, (struct prefix *) &lp);
  238. rn = route_next (rn);
  239. }
  240. for (; rn; rn = route_next (rn))
  241. if (rn->info)
  242. break;
  243. if (rn && rn->info)
  244. {
  245. find = rn->info;
  246. route_unlock_node (rn);
  247. return find;
  248. }
  249. return NULL;
  250. }
  251. unsigned long
  252. ospf_lsdb_count_all (struct ospf_lsdb *lsdb)
  253. {
  254. return lsdb->total;
  255. }
  256. unsigned long
  257. ospf_lsdb_count (struct ospf_lsdb *lsdb, int type)
  258. {
  259. return lsdb->type[type].count;
  260. }
  261. unsigned long
  262. ospf_lsdb_count_self (struct ospf_lsdb *lsdb, int type)
  263. {
  264. return lsdb->type[type].count_self;
  265. }
  266. unsigned int
  267. ospf_lsdb_checksum (struct ospf_lsdb *lsdb, int type)
  268. {
  269. return lsdb->type[type].checksum;
  270. }
  271. unsigned long
  272. ospf_lsdb_isempty (struct ospf_lsdb *lsdb)
  273. {
  274. return (lsdb->total == 0);
  275. }