]> git.proxmox.com Git - mirror_frr.git/blob - ospfd/ospf_lsdb.c
spelling: s/supress/suppress/
[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
29 #include "ospfd/ospfd.h"
30 #include "ospfd/ospf_asbr.h"
31 #include "ospfd/ospf_lsa.h"
32 #include "ospfd/ospf_lsdb.h"
33 \f
34 struct ospf_lsdb *
35 ospf_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
45 void
46 ospf_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
54 void
55 ospf_lsdb_free (struct ospf_lsdb *lsdb)
56 {
57 ospf_lsdb_cleanup (lsdb);
58 XFREE (MTYPE_OSPF_LSDB, lsdb);
59 }
60
61 void
62 ospf_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
74 void
75 lsdb_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. */
85 void
86 ospf_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;
91
92 table = lsdb->type[lsa->data->type].db;
93 lsdb_prefix_set (&lp, lsa);
94 rn = route_node_get (table, (struct prefix *)&lp);
95 if (!rn->info)
96 {
97 if (IS_LSA_SELF (lsa))
98 lsdb->type[lsa->data->type].count_self++;
99 lsdb->type[lsa->data->type].count++;
100 lsdb->total++;
101 }
102 else
103 {
104 if (rn->info == lsa)
105 return;
106
107 ospf_lsa_unlock (rn->info);
108 route_unlock_node (rn);
109 }
110
111 #ifdef MONITOR_LSDB_CHANGE
112 if (lsdb->new_lsa_hook != NULL)
113 (* lsdb->new_lsa_hook)(lsa);
114 #endif /* MONITOR_LSDB_CHANGE */
115 rn->info = ospf_lsa_lock (lsa);
116 }
117
118 void
119 ospf_lsdb_delete (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
120 {
121 struct route_table *table;
122 struct prefix_ls lp;
123 struct route_node *rn;
124
125 table = lsdb->type[lsa->data->type].db;
126 lsdb_prefix_set (&lp, lsa);
127 rn = route_node_lookup (table, (struct prefix *) &lp);
128 if (rn)
129 if (rn->info == lsa)
130 {
131 if (IS_LSA_SELF (lsa))
132 lsdb->type[lsa->data->type].count_self--;
133 lsdb->type[lsa->data->type].count--;
134 lsdb->total--;
135 rn->info = NULL;
136 route_unlock_node (rn);
137 route_unlock_node (rn);
138 #ifdef MONITOR_LSDB_CHANGE
139 if (lsdb->del_lsa_hook != NULL)
140 (* lsdb->del_lsa_hook)(lsa);
141 #endif /* MONITOR_LSDB_CHANGE */
142 ospf_lsa_unlock (lsa);
143 return;
144 }
145 }
146
147 void
148 ospf_lsdb_delete_all (struct ospf_lsdb *lsdb)
149 {
150 struct route_table *table;
151 struct route_node *rn;
152 struct ospf_lsa *lsa;
153 int i;
154
155 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
156 {
157 table = lsdb->type[i].db;
158 for (rn = route_top (table); rn; rn = route_next (rn))
159 if ((lsa = (rn->info)) != NULL)
160 {
161 if (IS_LSA_SELF (lsa))
162 lsdb->type[i].count_self--;
163 lsdb->type[i].count--;
164 lsdb->total--;
165 rn->info = NULL;
166 route_unlock_node (rn);
167 #ifdef MONITOR_LSDB_CHANGE
168 if (lsdb->del_lsa_hook != NULL)
169 (* lsdb->del_lsa_hook)(lsa);
170 #endif /* MONITOR_LSDB_CHANGE */
171 ospf_lsa_unlock (lsa);
172 }
173 }
174 }
175
176 struct ospf_lsa *
177 ospf_lsdb_lookup (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
178 {
179 struct route_table *table;
180 struct prefix_ls lp;
181 struct route_node *rn;
182 struct ospf_lsa *find;
183
184 table = lsdb->type[lsa->data->type].db;
185 lsdb_prefix_set (&lp, lsa);
186 rn = route_node_lookup (table, (struct prefix *) &lp);
187 if (rn)
188 {
189 find = rn->info;
190 route_unlock_node (rn);
191 return find;
192 }
193 return NULL;
194 }
195
196 struct ospf_lsa *
197 ospf_lsdb_lookup_by_id (struct ospf_lsdb *lsdb, u_char type,
198 struct in_addr id, struct in_addr adv_router)
199 {
200 struct route_table *table;
201 struct prefix_ls lp;
202 struct route_node *rn;
203 struct ospf_lsa *find;
204
205 table = lsdb->type[type].db;
206
207 memset (&lp, 0, sizeof (struct prefix_ls));
208 lp.family = 0;
209 lp.prefixlen = 64;
210 lp.id = id;
211 lp.adv_router = adv_router;
212
213 rn = route_node_lookup (table, (struct prefix *) &lp);
214 if (rn)
215 {
216 find = rn->info;
217 route_unlock_node (rn);
218 return find;
219 }
220 return NULL;
221 }
222
223 struct ospf_lsa *
224 ospf_lsdb_lookup_by_id_next (struct ospf_lsdb *lsdb, u_char type,
225 struct in_addr id, struct in_addr adv_router,
226 int first)
227 {
228 struct route_table *table;
229 struct prefix_ls lp;
230 struct route_node *rn;
231 struct ospf_lsa *find;
232
233 table = lsdb->type[type].db;
234
235 memset (&lp, 0, sizeof (struct prefix_ls));
236 lp.family = 0;
237 lp.prefixlen = 64;
238 lp.id = id;
239 lp.adv_router = adv_router;
240
241 if (first)
242 rn = route_top (table);
243 else
244 {
245 rn = route_node_get (table, (struct prefix *) &lp);
246 rn = route_next (rn);
247 }
248
249 for (; rn; rn = route_next (rn))
250 if (rn->info)
251 break;
252
253 if (rn && rn->info)
254 {
255 find = rn->info;
256 route_unlock_node (rn);
257 return find;
258 }
259 return NULL;
260 }
261
262 unsigned long
263 ospf_lsdb_count_all (struct ospf_lsdb *lsdb)
264 {
265 return lsdb->total;
266 }
267
268 unsigned long
269 ospf_lsdb_count (struct ospf_lsdb *lsdb, int type)
270 {
271 return lsdb->type[type].count;
272 }
273
274 unsigned long
275 ospf_lsdb_count_self (struct ospf_lsdb *lsdb, int type)
276 {
277 return lsdb->type[type].count_self;
278 }
279
280 unsigned long
281 ospf_lsdb_isempty (struct ospf_lsdb *lsdb)
282 {
283 return (lsdb->total == 0);
284 }
285
286 struct ospf_lsa *
287 foreach_lsa (struct route_table *table, void *p_arg, int int_arg,
288 int (*callback) (struct ospf_lsa *, void *, int))
289 {
290 struct route_node *rn;
291 struct ospf_lsa *lsa;
292
293 for (rn = route_top (table); rn; rn = route_next (rn))
294 if ((lsa = rn->info) != NULL)
295 if (callback (lsa, p_arg, int_arg))
296 return lsa;
297
298 return NULL;
299 }