blob: ea9a35284439c44ce294129d3c340c1dd9dac63e [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"
Tomasz Pala3fc1eca2009-06-24 21:48:22 +010028#include "log.h"
paul718e3742002-12-13 20:15:29 +000029
30#include "ospfd/ospfd.h"
31#include "ospfd/ospf_asbr.h"
32#include "ospfd/ospf_lsa.h"
33#include "ospfd/ospf_lsdb.h"
34
35struct ospf_lsdb *
36ospf_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
46void
47ospf_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
55void
56ospf_lsdb_free (struct ospf_lsdb *lsdb)
57{
58 ospf_lsdb_cleanup (lsdb);
59 XFREE (MTYPE_OSPF_LSDB, lsdb);
60}
61
62void
63ospf_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
paul4dadc292005-05-06 21:37:42 +000075static void
paul718e3742002-12-13 20:15:29 +000076lsdb_prefix_set (struct prefix_ls *lp, struct ospf_lsa *lsa)
77{
paul718e3742002-12-13 20:15:29 +000078 lp->family = 0;
79 lp->prefixlen = 64;
80 lp->id = lsa->data->id;
81 lp->adv_router = lsa->data->adv_router;
82}
83
Paul Jakmaba122e72006-08-27 06:24:34 +000084static void
85ospf_lsdb_delete_entry (struct ospf_lsdb *lsdb, struct route_node *rn)
86{
87 struct ospf_lsa *lsa = rn->info;
88
89 if (!lsa)
90 return;
91
92 assert (rn->table == lsdb->type[lsa->data->type].db);
93
94 if (IS_LSA_SELF (lsa))
95 lsdb->type[lsa->data->type].count_self--;
96 lsdb->type[lsa->data->type].count--;
97 lsdb->type[lsa->data->type].checksum -= ntohs(lsa->data->checksum);
98 lsdb->total--;
99 rn->info = NULL;
100 route_unlock_node (rn);
101#ifdef MONITOR_LSDB_CHANGE
102 if (lsdb->del_lsa_hook != NULL)
103 (* lsdb->del_lsa_hook)(lsa);
104#endif /* MONITOR_LSDB_CHANGE */
105 ospf_lsa_unlock (&lsa); /* lsdb */
106 return;
107}
108
paul718e3742002-12-13 20:15:29 +0000109/* Add new LSA to lsdb. */
110void
111ospf_lsdb_add (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
112{
113 struct route_table *table;
114 struct prefix_ls lp;
115 struct route_node *rn;
116
117 table = lsdb->type[lsa->data->type].db;
118 lsdb_prefix_set (&lp, lsa);
119 rn = route_node_get (table, (struct prefix *)&lp);
Paul Jakmaba122e72006-08-27 06:24:34 +0000120
121 /* nothing to do? */
122 if (rn->info && rn->info == lsa)
Paul Jakmae8f22262010-04-13 22:43:34 +0100123 {
124 route_unlock_node (rn);
125 return;
126 }
Paul Jakmaba122e72006-08-27 06:24:34 +0000127
128 /* purge old entry? */
129 if (rn->info)
130 ospf_lsdb_delete_entry (lsdb, rn);
hasso082253f2005-02-11 08:31:54 +0000131
Paul Jakmaba122e72006-08-27 06:24:34 +0000132 if (IS_LSA_SELF (lsa))
133 lsdb->type[lsa->data->type].count_self++;
134 lsdb->type[lsa->data->type].count++;
135 lsdb->total++;
paul718e3742002-12-13 20:15:29 +0000136
137#ifdef MONITOR_LSDB_CHANGE
138 if (lsdb->new_lsa_hook != NULL)
139 (* lsdb->new_lsa_hook)(lsa);
140#endif /* MONITOR_LSDB_CHANGE */
hasso082253f2005-02-11 08:31:54 +0000141 lsdb->type[lsa->data->type].checksum += ntohs(lsa->data->checksum);
Paul Jakmaba122e72006-08-27 06:24:34 +0000142 rn->info = ospf_lsa_lock (lsa); /* lsdb */
paul718e3742002-12-13 20:15:29 +0000143}
144
145void
146ospf_lsdb_delete (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
147{
148 struct route_table *table;
149 struct prefix_ls lp;
150 struct route_node *rn;
151
Paul Jakmaac904de2006-06-15 12:04:57 +0000152 if (!lsdb)
153 {
154 zlog_warn ("%s: Called with NULL LSDB", __func__);
155 if (lsa)
156 zlog_warn ("LSA[Type%d:%s]: LSA %p, lsa->lsdb %p",
157 lsa->data->type, inet_ntoa (lsa->data->id),
158 lsa, lsa->lsdb);
159 return;
160 }
161
162 if (!lsa)
163 {
164 zlog_warn ("%s: Called with NULL LSA", __func__);
165 return;
166 }
167
Paul Jakmae8f22262010-04-13 22:43:34 +0100168 assert (lsa->data->type < OSPF_MAX_LSA);
paul718e3742002-12-13 20:15:29 +0000169 table = lsdb->type[lsa->data->type].db;
170 lsdb_prefix_set (&lp, lsa);
Paul Jakmae8f22262010-04-13 22:43:34 +0100171 if ((rn = route_node_lookup (table, (struct prefix *) &lp)))
Paul Jakmaba122e72006-08-27 06:24:34 +0000172 {
Paul Jakmae8f22262010-04-13 22:43:34 +0100173 if (rn->info == lsa)
174 ospf_lsdb_delete_entry (lsdb, rn);
Paul Jakmaba122e72006-08-27 06:24:34 +0000175 route_unlock_node (rn); /* route_node_lookup */
176 }
paul718e3742002-12-13 20:15:29 +0000177}
178
179void
180ospf_lsdb_delete_all (struct ospf_lsdb *lsdb)
181{
182 struct route_table *table;
183 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000184 int i;
185
186 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
187 {
188 table = lsdb->type[i].db;
189 for (rn = route_top (table); rn; rn = route_next (rn))
Paul Jakmaba122e72006-08-27 06:24:34 +0000190 if (rn->info != NULL)
191 ospf_lsdb_delete_entry (lsdb, rn);
paul718e3742002-12-13 20:15:29 +0000192 }
193}
194
hasso462f20d2005-02-23 11:29:02 +0000195void
196ospf_lsdb_clean_stat (struct ospf_lsdb *lsdb)
197{
198 struct route_table *table;
199 struct route_node *rn;
200 struct ospf_lsa *lsa;
201 int i;
202
203 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
204 {
205 table = lsdb->type[i].db;
206 for (rn = route_top (table); rn; rn = route_next (rn))
207 if ((lsa = (rn->info)) != NULL)
208 lsa->stat = LSA_SPF_NOT_EXPLORED;
209 }
210}
211
paul718e3742002-12-13 20:15:29 +0000212struct ospf_lsa *
213ospf_lsdb_lookup (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
214{
215 struct route_table *table;
216 struct prefix_ls lp;
217 struct route_node *rn;
218 struct ospf_lsa *find;
219
220 table = lsdb->type[lsa->data->type].db;
221 lsdb_prefix_set (&lp, lsa);
222 rn = route_node_lookup (table, (struct prefix *) &lp);
223 if (rn)
224 {
225 find = rn->info;
226 route_unlock_node (rn);
227 return find;
228 }
229 return NULL;
230}
231
232struct ospf_lsa *
233ospf_lsdb_lookup_by_id (struct ospf_lsdb *lsdb, u_char type,
234 struct in_addr id, struct in_addr adv_router)
235{
236 struct route_table *table;
237 struct prefix_ls lp;
238 struct route_node *rn;
239 struct ospf_lsa *find;
240
241 table = lsdb->type[type].db;
242
243 memset (&lp, 0, sizeof (struct prefix_ls));
244 lp.family = 0;
245 lp.prefixlen = 64;
246 lp.id = id;
247 lp.adv_router = adv_router;
248
249 rn = route_node_lookup (table, (struct prefix *) &lp);
250 if (rn)
251 {
252 find = rn->info;
253 route_unlock_node (rn);
254 return find;
255 }
256 return NULL;
257}
258
259struct ospf_lsa *
260ospf_lsdb_lookup_by_id_next (struct ospf_lsdb *lsdb, u_char type,
261 struct in_addr id, struct in_addr adv_router,
262 int first)
263{
264 struct route_table *table;
265 struct prefix_ls lp;
266 struct route_node *rn;
267 struct ospf_lsa *find;
268
269 table = lsdb->type[type].db;
270
271 memset (&lp, 0, sizeof (struct prefix_ls));
272 lp.family = 0;
273 lp.prefixlen = 64;
274 lp.id = id;
275 lp.adv_router = adv_router;
276
277 if (first)
278 rn = route_top (table);
279 else
280 {
Paul Jakmae8f22262010-04-13 22:43:34 +0100281 if ((rn = route_node_lookup (table, (struct prefix *) &lp)) == NULL)
282 return NULL;
paul718e3742002-12-13 20:15:29 +0000283 rn = route_next (rn);
284 }
285
286 for (; rn; rn = route_next (rn))
287 if (rn->info)
288 break;
289
290 if (rn && rn->info)
291 {
292 find = rn->info;
293 route_unlock_node (rn);
294 return find;
295 }
296 return NULL;
297}
298
299unsigned long
300ospf_lsdb_count_all (struct ospf_lsdb *lsdb)
301{
302 return lsdb->total;
303}
304
305unsigned long
306ospf_lsdb_count (struct ospf_lsdb *lsdb, int type)
307{
308 return lsdb->type[type].count;
309}
310
311unsigned long
312ospf_lsdb_count_self (struct ospf_lsdb *lsdb, int type)
313{
314 return lsdb->type[type].count_self;
315}
316
hassofe71a972004-12-22 16:16:02 +0000317unsigned int
318ospf_lsdb_checksum (struct ospf_lsdb *lsdb, int type)
319{
320 return lsdb->type[type].checksum;
321}
322
paul718e3742002-12-13 20:15:29 +0000323unsigned long
324ospf_lsdb_isempty (struct ospf_lsdb *lsdb)
325{
326 return (lsdb->total == 0);
327}