blob: 4c6ed64ebe0a8e0012ebde73e71b8d64ceaba0f1 [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
74void
75lsdb_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;
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++;
hassofe71a972004-12-22 16:16:02 +0000100 lsdb->type[lsa->data->type].checksum += ntohs(lsa->data->checksum);
paul718e3742002-12-13 20:15:29 +0000101 lsdb->total++;
102 }
103 else
104 {
105 if (rn->info == lsa)
106 return;
107
108 ospf_lsa_unlock (rn->info);
109 route_unlock_node (rn);
110 }
111
112#ifdef MONITOR_LSDB_CHANGE
113 if (lsdb->new_lsa_hook != NULL)
114 (* lsdb->new_lsa_hook)(lsa);
115#endif /* MONITOR_LSDB_CHANGE */
116 rn->info = ospf_lsa_lock (lsa);
117}
118
119void
120ospf_lsdb_delete (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
121{
122 struct route_table *table;
123 struct prefix_ls lp;
124 struct route_node *rn;
125
126 table = lsdb->type[lsa->data->type].db;
127 lsdb_prefix_set (&lp, lsa);
128 rn = route_node_lookup (table, (struct prefix *) &lp);
129 if (rn)
130 if (rn->info == lsa)
131 {
132 if (IS_LSA_SELF (lsa))
133 lsdb->type[lsa->data->type].count_self--;
134 lsdb->type[lsa->data->type].count--;
hassofe71a972004-12-22 16:16:02 +0000135 lsdb->type[lsa->data->type].checksum -= ntohs(lsa->data->checksum);
paul718e3742002-12-13 20:15:29 +0000136 lsdb->total--;
137 rn->info = NULL;
138 route_unlock_node (rn);
139 route_unlock_node (rn);
140#ifdef MONITOR_LSDB_CHANGE
141 if (lsdb->del_lsa_hook != NULL)
142 (* lsdb->del_lsa_hook)(lsa);
143#endif /* MONITOR_LSDB_CHANGE */
144 ospf_lsa_unlock (lsa);
145 return;
146 }
147}
148
149void
150ospf_lsdb_delete_all (struct ospf_lsdb *lsdb)
151{
152 struct route_table *table;
153 struct route_node *rn;
154 struct ospf_lsa *lsa;
155 int i;
156
157 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
158 {
159 table = lsdb->type[i].db;
160 for (rn = route_top (table); rn; rn = route_next (rn))
161 if ((lsa = (rn->info)) != NULL)
162 {
163 if (IS_LSA_SELF (lsa))
164 lsdb->type[i].count_self--;
165 lsdb->type[i].count--;
hassofe71a972004-12-22 16:16:02 +0000166 lsdb->type[i].checksum -= ntohs(lsa->data->checksum);
paul718e3742002-12-13 20:15:29 +0000167 lsdb->total--;
168 rn->info = NULL;
169 route_unlock_node (rn);
170#ifdef MONITOR_LSDB_CHANGE
171 if (lsdb->del_lsa_hook != NULL)
172 (* lsdb->del_lsa_hook)(lsa);
173#endif /* MONITOR_LSDB_CHANGE */
174 ospf_lsa_unlock (lsa);
175 }
176 }
177}
178
179struct ospf_lsa *
180ospf_lsdb_lookup (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
181{
182 struct route_table *table;
183 struct prefix_ls lp;
184 struct route_node *rn;
185 struct ospf_lsa *find;
186
187 table = lsdb->type[lsa->data->type].db;
188 lsdb_prefix_set (&lp, lsa);
189 rn = route_node_lookup (table, (struct prefix *) &lp);
190 if (rn)
191 {
192 find = rn->info;
193 route_unlock_node (rn);
194 return find;
195 }
196 return NULL;
197}
198
199struct ospf_lsa *
200ospf_lsdb_lookup_by_id (struct ospf_lsdb *lsdb, u_char type,
201 struct in_addr id, struct in_addr adv_router)
202{
203 struct route_table *table;
204 struct prefix_ls lp;
205 struct route_node *rn;
206 struct ospf_lsa *find;
207
208 table = lsdb->type[type].db;
209
210 memset (&lp, 0, sizeof (struct prefix_ls));
211 lp.family = 0;
212 lp.prefixlen = 64;
213 lp.id = id;
214 lp.adv_router = adv_router;
215
216 rn = route_node_lookup (table, (struct prefix *) &lp);
217 if (rn)
218 {
219 find = rn->info;
220 route_unlock_node (rn);
221 return find;
222 }
223 return NULL;
224}
225
226struct ospf_lsa *
227ospf_lsdb_lookup_by_id_next (struct ospf_lsdb *lsdb, u_char type,
228 struct in_addr id, struct in_addr adv_router,
229 int first)
230{
231 struct route_table *table;
232 struct prefix_ls lp;
233 struct route_node *rn;
234 struct ospf_lsa *find;
235
236 table = lsdb->type[type].db;
237
238 memset (&lp, 0, sizeof (struct prefix_ls));
239 lp.family = 0;
240 lp.prefixlen = 64;
241 lp.id = id;
242 lp.adv_router = adv_router;
243
244 if (first)
245 rn = route_top (table);
246 else
247 {
248 rn = route_node_get (table, (struct prefix *) &lp);
249 rn = route_next (rn);
250 }
251
252 for (; rn; rn = route_next (rn))
253 if (rn->info)
254 break;
255
256 if (rn && rn->info)
257 {
258 find = rn->info;
259 route_unlock_node (rn);
260 return find;
261 }
262 return NULL;
263}
264
265unsigned long
266ospf_lsdb_count_all (struct ospf_lsdb *lsdb)
267{
268 return lsdb->total;
269}
270
271unsigned long
272ospf_lsdb_count (struct ospf_lsdb *lsdb, int type)
273{
274 return lsdb->type[type].count;
275}
276
277unsigned long
278ospf_lsdb_count_self (struct ospf_lsdb *lsdb, int type)
279{
280 return lsdb->type[type].count_self;
281}
282
hassofe71a972004-12-22 16:16:02 +0000283unsigned int
284ospf_lsdb_checksum (struct ospf_lsdb *lsdb, int type)
285{
286 return lsdb->type[type].checksum;
287}
288
paul718e3742002-12-13 20:15:29 +0000289unsigned long
290ospf_lsdb_isempty (struct ospf_lsdb *lsdb)
291{
292 return (lsdb->total == 0);
293}