ospf_lsdb.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  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. void
  63. ls_prefix_set (struct prefix_ls *lp, struct ospf_lsa *lsa)
  64. {
  65. if (lp && lsa && lsa->data)
  66. {
  67. lp->family = 0;
  68. lp->prefixlen = 64;
  69. lp->id = lsa->data->id;
  70. lp->adv_router = lsa->data->adv_router;
  71. }
  72. }
  73. static void
  74. ospf_lsdb_delete_entry (struct ospf_lsdb *lsdb, struct route_node *rn)
  75. {
  76. struct ospf_lsa *lsa = rn->info;
  77. if (!lsa)
  78. return;
  79. assert (rn->table == lsdb->type[lsa->data->type].db);
  80. if (IS_LSA_SELF (lsa))
  81. lsdb->type[lsa->data->type].count_self--;
  82. lsdb->type[lsa->data->type].count--;
  83. lsdb->type[lsa->data->type].checksum -= ntohs(lsa->data->checksum);
  84. lsdb->total--;
  85. rn->info = NULL;
  86. route_unlock_node (rn);
  87. #ifdef MONITOR_LSDB_CHANGE
  88. if (lsdb->del_lsa_hook != NULL)
  89. (* lsdb->del_lsa_hook)(lsa);
  90. #endif /* MONITOR_LSDB_CHANGE */
  91. ospf_lsa_unlock (&lsa); /* lsdb */
  92. return;
  93. }
  94. /* Add new LSA to lsdb. */
  95. void
  96. ospf_lsdb_add (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
  97. {
  98. struct route_table *table;
  99. struct prefix_ls lp;
  100. struct route_node *rn;
  101. table = lsdb->type[lsa->data->type].db;
  102. ls_prefix_set (&lp, lsa);
  103. rn = route_node_get (table, (struct prefix *)&lp);
  104. /* nothing to do? */
  105. if (rn->info && rn->info == lsa)
  106. {
  107. route_unlock_node (rn);
  108. return;
  109. }
  110. /* purge old entry? */
  111. if (rn->info)
  112. ospf_lsdb_delete_entry (lsdb, rn);
  113. if (IS_LSA_SELF (lsa))
  114. lsdb->type[lsa->data->type].count_self++;
  115. lsdb->type[lsa->data->type].count++;
  116. lsdb->total++;
  117. #ifdef MONITOR_LSDB_CHANGE
  118. if (lsdb->new_lsa_hook != NULL)
  119. (* lsdb->new_lsa_hook)(lsa);
  120. #endif /* MONITOR_LSDB_CHANGE */
  121. lsdb->type[lsa->data->type].checksum += ntohs(lsa->data->checksum);
  122. rn->info = ospf_lsa_lock (lsa); /* lsdb */
  123. }
  124. void
  125. ospf_lsdb_delete (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
  126. {
  127. struct route_table *table;
  128. struct prefix_ls lp;
  129. struct route_node *rn;
  130. if (!lsdb)
  131. {
  132. zlog_warn ("%s: Called with NULL LSDB", __func__);
  133. if (lsa)
  134. zlog_warn ("LSA[Type%d:%s]: LSA %p, lsa->lsdb %p",
  135. lsa->data->type, inet_ntoa (lsa->data->id),
  136. lsa, lsa->lsdb);
  137. return;
  138. }
  139. if (!lsa)
  140. {
  141. zlog_warn ("%s: Called with NULL LSA", __func__);
  142. return;
  143. }
  144. assert (lsa->data->type < OSPF_MAX_LSA);
  145. table = lsdb->type[lsa->data->type].db;
  146. ls_prefix_set (&lp, lsa);
  147. if ((rn = route_node_lookup (table, (struct prefix *) &lp)))
  148. {
  149. if (rn->info == lsa)
  150. ospf_lsdb_delete_entry (lsdb, rn);
  151. route_unlock_node (rn); /* route_node_lookup */
  152. }
  153. }
  154. void
  155. ospf_lsdb_delete_all (struct ospf_lsdb *lsdb)
  156. {
  157. struct route_table *table;
  158. struct route_node *rn;
  159. int i;
  160. for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
  161. {
  162. table = lsdb->type[i].db;
  163. for (rn = route_top (table); rn; rn = route_next (rn))
  164. if (rn->info != NULL)
  165. ospf_lsdb_delete_entry (lsdb, rn);
  166. }
  167. }
  168. void
  169. ospf_lsdb_clean_stat (struct ospf_lsdb *lsdb)
  170. {
  171. struct route_table *table;
  172. struct route_node *rn;
  173. struct ospf_lsa *lsa;
  174. int i;
  175. for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
  176. {
  177. table = lsdb->type[i].db;
  178. for (rn = route_top (table); rn; rn = route_next (rn))
  179. if ((lsa = (rn->info)) != NULL)
  180. lsa->stat = LSA_SPF_NOT_EXPLORED;
  181. }
  182. }
  183. struct ospf_lsa *
  184. ospf_lsdb_lookup (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
  185. {
  186. struct route_table *table;
  187. struct prefix_ls lp;
  188. struct route_node *rn;
  189. struct ospf_lsa *find;
  190. table = lsdb->type[lsa->data->type].db;
  191. ls_prefix_set (&lp, lsa);
  192. rn = route_node_lookup (table, (struct prefix *) &lp);
  193. if (rn)
  194. {
  195. find = rn->info;
  196. route_unlock_node (rn);
  197. return find;
  198. }
  199. return NULL;
  200. }
  201. struct ospf_lsa *
  202. ospf_lsdb_lookup_by_id (struct ospf_lsdb *lsdb, u_char type,
  203. struct in_addr id, struct in_addr adv_router)
  204. {
  205. struct route_table *table;
  206. struct prefix_ls lp;
  207. struct route_node *rn;
  208. struct ospf_lsa *find;
  209. table = lsdb->type[type].db;
  210. memset (&lp, 0, sizeof (struct prefix_ls));
  211. lp.family = 0;
  212. lp.prefixlen = 64;
  213. lp.id = id;
  214. lp.adv_router = adv_router;
  215. rn = route_node_lookup (table, (struct prefix *) &lp);
  216. if (rn)
  217. {
  218. find = rn->info;
  219. route_unlock_node (rn);
  220. return find;
  221. }
  222. return NULL;
  223. }
  224. struct ospf_lsa *
  225. ospf_lsdb_lookup_by_id_next (struct ospf_lsdb *lsdb, u_char type,
  226. struct in_addr id, struct in_addr adv_router,
  227. int first)
  228. {
  229. struct route_table *table;
  230. struct prefix_ls lp;
  231. struct route_node *rn;
  232. struct ospf_lsa *find;
  233. table = lsdb->type[type].db;
  234. memset (&lp, 0, sizeof (struct prefix_ls));
  235. lp.family = 0;
  236. lp.prefixlen = 64;
  237. lp.id = id;
  238. lp.adv_router = adv_router;
  239. if (first)
  240. rn = route_top (table);
  241. else
  242. {
  243. if ((rn = route_node_lookup (table, (struct prefix *) &lp)) == NULL)
  244. return NULL;
  245. rn = route_next (rn);
  246. }
  247. for (; rn; rn = route_next (rn))
  248. if (rn->info)
  249. break;
  250. if (rn && rn->info)
  251. {
  252. find = rn->info;
  253. route_unlock_node (rn);
  254. return find;
  255. }
  256. return NULL;
  257. }
  258. unsigned long
  259. ospf_lsdb_count_all (struct ospf_lsdb *lsdb)
  260. {
  261. return lsdb->total;
  262. }
  263. unsigned long
  264. ospf_lsdb_count (struct ospf_lsdb *lsdb, int type)
  265. {
  266. return lsdb->type[type].count;
  267. }
  268. unsigned long
  269. ospf_lsdb_count_self (struct ospf_lsdb *lsdb, int type)
  270. {
  271. return lsdb->type[type].count_self;
  272. }
  273. unsigned int
  274. ospf_lsdb_checksum (struct ospf_lsdb *lsdb, int type)
  275. {
  276. return lsdb->type[type].checksum;
  277. }
  278. unsigned long
  279. ospf_lsdb_isempty (struct ospf_lsdb *lsdb)
  280. {
  281. return (lsdb->total == 0);
  282. }