]> git.proxmox.com Git - mirror_frr.git/blob - ospfd/ospf_lsdb.c
*: use void * for printing pointers
[mirror_frr.git] / ospfd / ospf_lsdb.c
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
75 void
76 ls_prefix_set (struct prefix_ls *lp, struct ospf_lsa *lsa)
77 {
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 }
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;
121 ls_prefix_set (&lp, lsa);
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 (void *)lsa, (void *)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;
173 ls_prefix_set (&lp, lsa);
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;
224 ls_prefix_set (&lp, lsa);
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 }