]> git.proxmox.com Git - mirror_frr.git/blame - ospfd/ospf_lsdb.c
*: add indent control files
[mirror_frr.git] / ospfd / ospf_lsdb.c
CommitLineData
718e3744 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 *
896014f4
DL
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
718e3744 20 */
21
22#include <zebra.h>
23
24#include "prefix.h"
25#include "table.h"
26#include "memory.h"
3fc1eca9 27#include "log.h"
718e3744 28
29#include "ospfd/ospfd.h"
30#include "ospfd/ospf_asbr.h"
31#include "ospfd/ospf_lsa.h"
32#include "ospfd/ospf_lsdb.h"
6b0655a2 33
718e3744 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
91e6a0e5
DD
74void
75ls_prefix_set (struct prefix_ls *lp, struct ospf_lsa *lsa)
718e3744 76{
91e6a0e5
DD
77 if (lp && lsa && lsa->data)
78 {
79 lp->family = 0;
80 lp->prefixlen = 64;
81 lp->id = lsa->data->id;
82 lp->adv_router = lsa->data->adv_router;
83 }
718e3744 84}
85
ba122e77
PJ
86static void
87ospf_lsdb_delete_entry (struct ospf_lsdb *lsdb, struct route_node *rn)
88{
89 struct ospf_lsa *lsa = rn->info;
90
91 if (!lsa)
92 return;
93
94 assert (rn->table == lsdb->type[lsa->data->type].db);
95
96 if (IS_LSA_SELF (lsa))
97 lsdb->type[lsa->data->type].count_self--;
98 lsdb->type[lsa->data->type].count--;
99 lsdb->type[lsa->data->type].checksum -= ntohs(lsa->data->checksum);
100 lsdb->total--;
101 rn->info = NULL;
102 route_unlock_node (rn);
103#ifdef MONITOR_LSDB_CHANGE
104 if (lsdb->del_lsa_hook != NULL)
105 (* lsdb->del_lsa_hook)(lsa);
106#endif /* MONITOR_LSDB_CHANGE */
107 ospf_lsa_unlock (&lsa); /* lsdb */
108 return;
109}
110
718e3744 111/* Add new LSA to lsdb. */
112void
113ospf_lsdb_add (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
114{
115 struct route_table *table;
116 struct prefix_ls lp;
117 struct route_node *rn;
118
119 table = lsdb->type[lsa->data->type].db;
91e6a0e5 120 ls_prefix_set (&lp, lsa);
718e3744 121 rn = route_node_get (table, (struct prefix *)&lp);
ba122e77
PJ
122
123 /* nothing to do? */
124 if (rn->info && rn->info == lsa)
e8f22261
PJ
125 {
126 route_unlock_node (rn);
127 return;
128 }
ba122e77
PJ
129
130 /* purge old entry? */
131 if (rn->info)
132 ospf_lsdb_delete_entry (lsdb, rn);
133
134 if (IS_LSA_SELF (lsa))
135 lsdb->type[lsa->data->type].count_self++;
136 lsdb->type[lsa->data->type].count++;
137 lsdb->total++;
718e3744 138
139#ifdef MONITOR_LSDB_CHANGE
140 if (lsdb->new_lsa_hook != NULL)
141 (* lsdb->new_lsa_hook)(lsa);
142#endif /* MONITOR_LSDB_CHANGE */
082253f5 143 lsdb->type[lsa->data->type].checksum += ntohs(lsa->data->checksum);
ba122e77 144 rn->info = ospf_lsa_lock (lsa); /* lsdb */
718e3744 145}
146
147void
148ospf_lsdb_delete (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
149{
150 struct route_table *table;
151 struct prefix_ls lp;
152 struct route_node *rn;
153
ac904dec
PJ
154 if (!lsdb)
155 {
156 zlog_warn ("%s: Called with NULL LSDB", __func__);
157 if (lsa)
158 zlog_warn ("LSA[Type%d:%s]: LSA %p, lsa->lsdb %p",
159 lsa->data->type, inet_ntoa (lsa->data->id),
6c4f4e6e 160 (void *)lsa, (void *)lsa->lsdb);
ac904dec
PJ
161 return;
162 }
163
164 if (!lsa)
165 {
166 zlog_warn ("%s: Called with NULL LSA", __func__);
167 return;
168 }
169
e8f22261 170 assert (lsa->data->type < OSPF_MAX_LSA);
718e3744 171 table = lsdb->type[lsa->data->type].db;
91e6a0e5 172 ls_prefix_set (&lp, lsa);
e8f22261 173 if ((rn = route_node_lookup (table, (struct prefix *) &lp)))
ba122e77 174 {
e8f22261
PJ
175 if (rn->info == lsa)
176 ospf_lsdb_delete_entry (lsdb, rn);
ba122e77
PJ
177 route_unlock_node (rn); /* route_node_lookup */
178 }
718e3744 179}
180
181void
182ospf_lsdb_delete_all (struct ospf_lsdb *lsdb)
183{
184 struct route_table *table;
185 struct route_node *rn;
718e3744 186 int i;
187
188 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
189 {
190 table = lsdb->type[i].db;
191 for (rn = route_top (table); rn; rn = route_next (rn))
ba122e77
PJ
192 if (rn->info != NULL)
193 ospf_lsdb_delete_entry (lsdb, rn);
718e3744 194 }
195}
196
462f20d5 197void
198ospf_lsdb_clean_stat (struct ospf_lsdb *lsdb)
199{
200 struct route_table *table;
201 struct route_node *rn;
202 struct ospf_lsa *lsa;
203 int i;
204
205 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
206 {
207 table = lsdb->type[i].db;
208 for (rn = route_top (table); rn; rn = route_next (rn))
209 if ((lsa = (rn->info)) != NULL)
210 lsa->stat = LSA_SPF_NOT_EXPLORED;
211 }
212}
213
718e3744 214struct ospf_lsa *
215ospf_lsdb_lookup (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
216{
217 struct route_table *table;
218 struct prefix_ls lp;
219 struct route_node *rn;
220 struct ospf_lsa *find;
221
222 table = lsdb->type[lsa->data->type].db;
91e6a0e5 223 ls_prefix_set (&lp, lsa);
718e3744 224 rn = route_node_lookup (table, (struct prefix *) &lp);
225 if (rn)
226 {
227 find = rn->info;
228 route_unlock_node (rn);
229 return find;
230 }
231 return NULL;
232}
233
234struct ospf_lsa *
235ospf_lsdb_lookup_by_id (struct ospf_lsdb *lsdb, u_char type,
236 struct in_addr id, struct in_addr adv_router)
237{
238 struct route_table *table;
239 struct prefix_ls lp;
240 struct route_node *rn;
241 struct ospf_lsa *find;
242
243 table = lsdb->type[type].db;
244
245 memset (&lp, 0, sizeof (struct prefix_ls));
246 lp.family = 0;
247 lp.prefixlen = 64;
248 lp.id = id;
249 lp.adv_router = adv_router;
250
251 rn = route_node_lookup (table, (struct prefix *) &lp);
252 if (rn)
253 {
254 find = rn->info;
255 route_unlock_node (rn);
256 return find;
257 }
258 return NULL;
259}
260
261struct ospf_lsa *
262ospf_lsdb_lookup_by_id_next (struct ospf_lsdb *lsdb, u_char type,
263 struct in_addr id, struct in_addr adv_router,
264 int first)
265{
266 struct route_table *table;
267 struct prefix_ls lp;
268 struct route_node *rn;
269 struct ospf_lsa *find;
270
271 table = lsdb->type[type].db;
272
273 memset (&lp, 0, sizeof (struct prefix_ls));
274 lp.family = 0;
275 lp.prefixlen = 64;
276 lp.id = id;
277 lp.adv_router = adv_router;
278
279 if (first)
280 rn = route_top (table);
281 else
282 {
e8f22261
PJ
283 if ((rn = route_node_lookup (table, (struct prefix *) &lp)) == NULL)
284 return NULL;
718e3744 285 rn = route_next (rn);
286 }
287
288 for (; rn; rn = route_next (rn))
289 if (rn->info)
290 break;
291
292 if (rn && rn->info)
293 {
294 find = rn->info;
295 route_unlock_node (rn);
296 return find;
297 }
298 return NULL;
299}
300
301unsigned long
302ospf_lsdb_count_all (struct ospf_lsdb *lsdb)
303{
304 return lsdb->total;
305}
306
307unsigned long
308ospf_lsdb_count (struct ospf_lsdb *lsdb, int type)
309{
310 return lsdb->type[type].count;
311}
312
313unsigned long
314ospf_lsdb_count_self (struct ospf_lsdb *lsdb, int type)
315{
316 return lsdb->type[type].count_self;
317}
318
fe71a97d 319unsigned int
320ospf_lsdb_checksum (struct ospf_lsdb *lsdb, int type)
718e3744 321{
fe71a97d 322 return lsdb->type[type].checksum;
718e3744 323}
324
fe71a97d 325unsigned long
326ospf_lsdb_isempty (struct ospf_lsdb *lsdb)
718e3744 327{
fe71a97d 328 return (lsdb->total == 0);
718e3744 329}