blob: b161b8067473ee01431ad6b74ffa0d1bee4280df [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
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
29#include "ospfd/ospfd.h"
30#include "ospfd/ospf_asbr.h"
31#include "ospfd/ospf_lsa.h"
32#include "ospfd/ospf_lsdb.h"
33
34struct ospf_lsdb *
35ospf_lsdb_new ()
36{
37 struct ospf_lsdb *new;
38
39 new = XCALLOC (MTYPE_OSPF_LSDB, sizeof (struct ospf_lsdb));
40 ospf_lsdb_init (new);
41
42 return new;
43}
44
45void
46ospf_lsdb_init (struct ospf_lsdb *lsdb)
47{
48 int i;
49
50 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
51 lsdb->type[i].db = route_table_init ();
52}
53
54void
55ospf_lsdb_free (struct ospf_lsdb *lsdb)
56{
57 ospf_lsdb_cleanup (lsdb);
58 XFREE (MTYPE_OSPF_LSDB, lsdb);
59}
60
61void
62ospf_lsdb_cleanup (struct ospf_lsdb *lsdb)
63{
64 int i;
65 assert (lsdb);
66 assert (lsdb->total == 0);
67
68 ospf_lsdb_delete_all (lsdb);
69
70 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
71 route_table_finish (lsdb->type[i].db);
72}
73
paul4dadc292005-05-06 21:37:42 +000074static void
paul718e3742002-12-13 20:15:29 +000075lsdb_prefix_set (struct prefix_ls *lp, struct ospf_lsa *lsa)
76{
77 memset (lp, 0, sizeof (struct prefix_ls));
78 lp->family = 0;
79 lp->prefixlen = 64;
80 lp->id = lsa->data->id;
81 lp->adv_router = lsa->data->adv_router;
82}
83
84/* Add new LSA to lsdb. */
85void
86ospf_lsdb_add (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
87{
88 struct route_table *table;
89 struct prefix_ls lp;
90 struct route_node *rn;
hasso082253f2005-02-11 08:31:54 +000091 struct ospf_lsa *old;
paul718e3742002-12-13 20:15:29 +000092
93 table = lsdb->type[lsa->data->type].db;
94 lsdb_prefix_set (&lp, lsa);
95 rn = route_node_get (table, (struct prefix *)&lp);
96 if (!rn->info)
97 {
98 if (IS_LSA_SELF (lsa))
99 lsdb->type[lsa->data->type].count_self++;
100 lsdb->type[lsa->data->type].count++;
101 lsdb->total++;
102 }
103 else
104 {
105 if (rn->info == lsa)
106 return;
107
hasso082253f2005-02-11 08:31:54 +0000108 old = rn->info;
109 lsdb->type[old->data->type].checksum -= ntohs(old->data->checksum);
110
paul718e3742002-12-13 20:15:29 +0000111 ospf_lsa_unlock (rn->info);
112 route_unlock_node (rn);
113 }
114
115#ifdef MONITOR_LSDB_CHANGE
116 if (lsdb->new_lsa_hook != NULL)
117 (* lsdb->new_lsa_hook)(lsa);
118#endif /* MONITOR_LSDB_CHANGE */
hasso082253f2005-02-11 08:31:54 +0000119 lsdb->type[lsa->data->type].checksum += ntohs(lsa->data->checksum);
paul718e3742002-12-13 20:15:29 +0000120 rn->info = ospf_lsa_lock (lsa);
121}
122
123void
124ospf_lsdb_delete (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
125{
126 struct route_table *table;
127 struct prefix_ls lp;
128 struct route_node *rn;
129
Paul Jakmaac904de2006-06-15 12:04:57 +0000130 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
140 if (!lsa)
141 {
142 zlog_warn ("%s: Called with NULL LSA", __func__);
143 return;
144 }
145
paul718e3742002-12-13 20:15:29 +0000146 table = lsdb->type[lsa->data->type].db;
147 lsdb_prefix_set (&lp, lsa);
148 rn = route_node_lookup (table, (struct prefix *) &lp);
149 if (rn)
150 if (rn->info == lsa)
151 {
152 if (IS_LSA_SELF (lsa))
153 lsdb->type[lsa->data->type].count_self--;
154 lsdb->type[lsa->data->type].count--;
hassofe71a972004-12-22 16:16:02 +0000155 lsdb->type[lsa->data->type].checksum -= ntohs(lsa->data->checksum);
paul718e3742002-12-13 20:15:29 +0000156 lsdb->total--;
157 rn->info = NULL;
158 route_unlock_node (rn);
159 route_unlock_node (rn);
160#ifdef MONITOR_LSDB_CHANGE
161 if (lsdb->del_lsa_hook != NULL)
162 (* lsdb->del_lsa_hook)(lsa);
163#endif /* MONITOR_LSDB_CHANGE */
164 ospf_lsa_unlock (lsa);
165 return;
166 }
167}
168
169void
170ospf_lsdb_delete_all (struct ospf_lsdb *lsdb)
171{
172 struct route_table *table;
173 struct route_node *rn;
174 struct ospf_lsa *lsa;
175 int i;
176
177 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
178 {
179 table = lsdb->type[i].db;
180 for (rn = route_top (table); rn; rn = route_next (rn))
181 if ((lsa = (rn->info)) != NULL)
182 {
183 if (IS_LSA_SELF (lsa))
184 lsdb->type[i].count_self--;
185 lsdb->type[i].count--;
hassofe71a972004-12-22 16:16:02 +0000186 lsdb->type[i].checksum -= ntohs(lsa->data->checksum);
paul718e3742002-12-13 20:15:29 +0000187 lsdb->total--;
188 rn->info = NULL;
189 route_unlock_node (rn);
190#ifdef MONITOR_LSDB_CHANGE
191 if (lsdb->del_lsa_hook != NULL)
192 (* lsdb->del_lsa_hook)(lsa);
193#endif /* MONITOR_LSDB_CHANGE */
194 ospf_lsa_unlock (lsa);
195 }
196 }
197}
198
hasso462f20d2005-02-23 11:29:02 +0000199void
200ospf_lsdb_clean_stat (struct ospf_lsdb *lsdb)
201{
202 struct route_table *table;
203 struct route_node *rn;
204 struct ospf_lsa *lsa;
205 int i;
206
207 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
208 {
209 table = lsdb->type[i].db;
210 for (rn = route_top (table); rn; rn = route_next (rn))
211 if ((lsa = (rn->info)) != NULL)
212 lsa->stat = LSA_SPF_NOT_EXPLORED;
213 }
214}
215
paul718e3742002-12-13 20:15:29 +0000216struct ospf_lsa *
217ospf_lsdb_lookup (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
218{
219 struct route_table *table;
220 struct prefix_ls lp;
221 struct route_node *rn;
222 struct ospf_lsa *find;
223
224 table = lsdb->type[lsa->data->type].db;
225 lsdb_prefix_set (&lp, lsa);
226 rn = route_node_lookup (table, (struct prefix *) &lp);
227 if (rn)
228 {
229 find = rn->info;
230 route_unlock_node (rn);
231 return find;
232 }
233 return NULL;
234}
235
236struct ospf_lsa *
237ospf_lsdb_lookup_by_id (struct ospf_lsdb *lsdb, u_char type,
238 struct in_addr id, struct in_addr adv_router)
239{
240 struct route_table *table;
241 struct prefix_ls lp;
242 struct route_node *rn;
243 struct ospf_lsa *find;
244
245 table = lsdb->type[type].db;
246
247 memset (&lp, 0, sizeof (struct prefix_ls));
248 lp.family = 0;
249 lp.prefixlen = 64;
250 lp.id = id;
251 lp.adv_router = adv_router;
252
253 rn = route_node_lookup (table, (struct prefix *) &lp);
254 if (rn)
255 {
256 find = rn->info;
257 route_unlock_node (rn);
258 return find;
259 }
260 return NULL;
261}
262
263struct ospf_lsa *
264ospf_lsdb_lookup_by_id_next (struct ospf_lsdb *lsdb, u_char type,
265 struct in_addr id, struct in_addr adv_router,
266 int first)
267{
268 struct route_table *table;
269 struct prefix_ls lp;
270 struct route_node *rn;
271 struct ospf_lsa *find;
272
273 table = lsdb->type[type].db;
274
275 memset (&lp, 0, sizeof (struct prefix_ls));
276 lp.family = 0;
277 lp.prefixlen = 64;
278 lp.id = id;
279 lp.adv_router = adv_router;
280
281 if (first)
282 rn = route_top (table);
283 else
284 {
285 rn = route_node_get (table, (struct prefix *) &lp);
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
302unsigned long
303ospf_lsdb_count_all (struct ospf_lsdb *lsdb)
304{
305 return lsdb->total;
306}
307
308unsigned long
309ospf_lsdb_count (struct ospf_lsdb *lsdb, int type)
310{
311 return lsdb->type[type].count;
312}
313
314unsigned long
315ospf_lsdb_count_self (struct ospf_lsdb *lsdb, int type)
316{
317 return lsdb->type[type].count_self;
318}
319
hassofe71a972004-12-22 16:16:02 +0000320unsigned int
321ospf_lsdb_checksum (struct ospf_lsdb *lsdb, int type)
322{
323 return lsdb->type[type].checksum;
324}
325
paul718e3742002-12-13 20:15:29 +0000326unsigned long
327ospf_lsdb_isempty (struct ospf_lsdb *lsdb)
328{
329 return (lsdb->total == 0);
330}