Annotation of embedaddon/quagga/ospfd/ospf_lsdb.c, revision 1.1.1.2
1.1 misho 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:
23: #include <zebra.h>
24:
25: #include "prefix.h"
26: #include "table.h"
27: #include "memory.h"
28: #include "log.h"
29:
30: #include "ospfd/ospfd.h"
31: #include "ospfd/ospf_asbr.h"
32: #include "ospfd/ospf_lsa.h"
33: #include "ospfd/ospf_lsdb.h"
34:
35: struct ospf_lsdb *
36: ospf_lsdb_new ()
37: {
38: struct ospf_lsdb *new;
39:
40: new = XCALLOC (MTYPE_OSPF_LSDB, sizeof (struct ospf_lsdb));
41: ospf_lsdb_init (new);
42:
43: return new;
44: }
45:
46: void
47: ospf_lsdb_init (struct ospf_lsdb *lsdb)
48: {
49: int i;
50:
51: for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
52: lsdb->type[i].db = route_table_init ();
53: }
54:
55: void
56: ospf_lsdb_free (struct ospf_lsdb *lsdb)
57: {
58: ospf_lsdb_cleanup (lsdb);
59: XFREE (MTYPE_OSPF_LSDB, lsdb);
60: }
61:
62: void
63: ospf_lsdb_cleanup (struct ospf_lsdb *lsdb)
64: {
65: int i;
66: assert (lsdb);
67: assert (lsdb->total == 0);
68:
69: ospf_lsdb_delete_all (lsdb);
70:
71: for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
72: route_table_finish (lsdb->type[i].db);
73: }
74:
1.1.1.2 ! misho 75: void
! 76: ls_prefix_set (struct prefix_ls *lp, struct ospf_lsa *lsa)
1.1 misho 77: {
1.1.1.2 ! misho 78: if (lp && lsa && lsa->data)
! 79: {
! 80: lp->family = 0;
! 81: lp->prefixlen = 64;
! 82: lp->id = lsa->data->id;
! 83: lp->adv_router = lsa->data->adv_router;
! 84: }
1.1 misho 85: }
86:
87: static void
88: ospf_lsdb_delete_entry (struct ospf_lsdb *lsdb, struct route_node *rn)
89: {
90: struct ospf_lsa *lsa = rn->info;
91:
92: if (!lsa)
93: return;
94:
95: assert (rn->table == lsdb->type[lsa->data->type].db);
96:
97: if (IS_LSA_SELF (lsa))
98: lsdb->type[lsa->data->type].count_self--;
99: lsdb->type[lsa->data->type].count--;
100: lsdb->type[lsa->data->type].checksum -= ntohs(lsa->data->checksum);
101: lsdb->total--;
102: rn->info = NULL;
103: route_unlock_node (rn);
104: #ifdef MONITOR_LSDB_CHANGE
105: if (lsdb->del_lsa_hook != NULL)
106: (* lsdb->del_lsa_hook)(lsa);
107: #endif /* MONITOR_LSDB_CHANGE */
108: ospf_lsa_unlock (&lsa); /* lsdb */
109: return;
110: }
111:
112: /* Add new LSA to lsdb. */
113: void
114: ospf_lsdb_add (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
115: {
116: struct route_table *table;
117: struct prefix_ls lp;
118: struct route_node *rn;
119:
120: table = lsdb->type[lsa->data->type].db;
1.1.1.2 ! misho 121: ls_prefix_set (&lp, lsa);
1.1 misho 122: rn = route_node_get (table, (struct prefix *)&lp);
123:
124: /* nothing to do? */
125: if (rn->info && rn->info == lsa)
126: {
127: route_unlock_node (rn);
128: return;
129: }
130:
131: /* purge old entry? */
132: if (rn->info)
133: ospf_lsdb_delete_entry (lsdb, rn);
134:
135: if (IS_LSA_SELF (lsa))
136: lsdb->type[lsa->data->type].count_self++;
137: lsdb->type[lsa->data->type].count++;
138: lsdb->total++;
139:
140: #ifdef MONITOR_LSDB_CHANGE
141: if (lsdb->new_lsa_hook != NULL)
142: (* lsdb->new_lsa_hook)(lsa);
143: #endif /* MONITOR_LSDB_CHANGE */
144: lsdb->type[lsa->data->type].checksum += ntohs(lsa->data->checksum);
145: rn->info = ospf_lsa_lock (lsa); /* lsdb */
146: }
147:
148: void
149: ospf_lsdb_delete (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
150: {
151: struct route_table *table;
152: struct prefix_ls lp;
153: struct route_node *rn;
154:
155: if (!lsdb)
156: {
157: zlog_warn ("%s: Called with NULL LSDB", __func__);
158: if (lsa)
159: zlog_warn ("LSA[Type%d:%s]: LSA %p, lsa->lsdb %p",
160: lsa->data->type, inet_ntoa (lsa->data->id),
161: lsa, lsa->lsdb);
162: return;
163: }
164:
165: if (!lsa)
166: {
167: zlog_warn ("%s: Called with NULL LSA", __func__);
168: return;
169: }
170:
171: assert (lsa->data->type < OSPF_MAX_LSA);
172: table = lsdb->type[lsa->data->type].db;
1.1.1.2 ! misho 173: ls_prefix_set (&lp, lsa);
1.1 misho 174: if ((rn = route_node_lookup (table, (struct prefix *) &lp)))
175: {
176: if (rn->info == lsa)
177: ospf_lsdb_delete_entry (lsdb, rn);
178: route_unlock_node (rn); /* route_node_lookup */
179: }
180: }
181:
182: void
183: ospf_lsdb_delete_all (struct ospf_lsdb *lsdb)
184: {
185: struct route_table *table;
186: struct route_node *rn;
187: int i;
188:
189: for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
190: {
191: table = lsdb->type[i].db;
192: for (rn = route_top (table); rn; rn = route_next (rn))
193: if (rn->info != NULL)
194: ospf_lsdb_delete_entry (lsdb, rn);
195: }
196: }
197:
198: void
199: ospf_lsdb_clean_stat (struct ospf_lsdb *lsdb)
200: {
201: struct route_table *table;
202: struct route_node *rn;
203: struct ospf_lsa *lsa;
204: int i;
205:
206: for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
207: {
208: table = lsdb->type[i].db;
209: for (rn = route_top (table); rn; rn = route_next (rn))
210: if ((lsa = (rn->info)) != NULL)
211: lsa->stat = LSA_SPF_NOT_EXPLORED;
212: }
213: }
214:
215: struct ospf_lsa *
216: ospf_lsdb_lookup (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
217: {
218: struct route_table *table;
219: struct prefix_ls lp;
220: struct route_node *rn;
221: struct ospf_lsa *find;
222:
223: table = lsdb->type[lsa->data->type].db;
1.1.1.2 ! misho 224: ls_prefix_set (&lp, lsa);
1.1 misho 225: rn = route_node_lookup (table, (struct prefix *) &lp);
226: if (rn)
227: {
228: find = rn->info;
229: route_unlock_node (rn);
230: return find;
231: }
232: return NULL;
233: }
234:
235: struct ospf_lsa *
236: ospf_lsdb_lookup_by_id (struct ospf_lsdb *lsdb, u_char type,
237: struct in_addr id, struct in_addr adv_router)
238: {
239: struct route_table *table;
240: struct prefix_ls lp;
241: struct route_node *rn;
242: struct ospf_lsa *find;
243:
244: table = lsdb->type[type].db;
245:
246: memset (&lp, 0, sizeof (struct prefix_ls));
247: lp.family = 0;
248: lp.prefixlen = 64;
249: lp.id = id;
250: lp.adv_router = adv_router;
251:
252: rn = route_node_lookup (table, (struct prefix *) &lp);
253: if (rn)
254: {
255: find = rn->info;
256: route_unlock_node (rn);
257: return find;
258: }
259: return NULL;
260: }
261:
262: struct ospf_lsa *
263: ospf_lsdb_lookup_by_id_next (struct ospf_lsdb *lsdb, u_char type,
264: struct in_addr id, struct in_addr adv_router,
265: int first)
266: {
267: struct route_table *table;
268: struct prefix_ls lp;
269: struct route_node *rn;
270: struct ospf_lsa *find;
271:
272: table = lsdb->type[type].db;
273:
274: memset (&lp, 0, sizeof (struct prefix_ls));
275: lp.family = 0;
276: lp.prefixlen = 64;
277: lp.id = id;
278: lp.adv_router = adv_router;
279:
280: if (first)
281: rn = route_top (table);
282: else
283: {
284: if ((rn = route_node_lookup (table, (struct prefix *) &lp)) == NULL)
285: return NULL;
286: rn = route_next (rn);
287: }
288:
289: for (; rn; rn = route_next (rn))
290: if (rn->info)
291: break;
292:
293: if (rn && rn->info)
294: {
295: find = rn->info;
296: route_unlock_node (rn);
297: return find;
298: }
299: return NULL;
300: }
301:
302: unsigned long
303: ospf_lsdb_count_all (struct ospf_lsdb *lsdb)
304: {
305: return lsdb->total;
306: }
307:
308: unsigned long
309: ospf_lsdb_count (struct ospf_lsdb *lsdb, int type)
310: {
311: return lsdb->type[type].count;
312: }
313:
314: unsigned long
315: ospf_lsdb_count_self (struct ospf_lsdb *lsdb, int type)
316: {
317: return lsdb->type[type].count_self;
318: }
319:
320: unsigned int
321: ospf_lsdb_checksum (struct ospf_lsdb *lsdb, int type)
322: {
323: return lsdb->type[type].checksum;
324: }
325:
326: unsigned long
327: ospf_lsdb_isempty (struct ospf_lsdb *lsdb)
328: {
329: return (lsdb->total == 0);
330: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>