3 * Copyright (C) 1999, 2000 Alex Zinin, Kunihiro Ishiguro, Toshiaki Takada
5 * This file is part of GNU Zebra.
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
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.
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
30 #include "ospfd/ospfd.h"
31 #include "ospfd/ospf_asbr.h"
32 #include "ospfd/ospf_lsa.h"
33 #include "ospfd/ospf_lsdb.h"
38 struct ospf_lsdb
*new;
40 new = XCALLOC (MTYPE_OSPF_LSDB
, sizeof (struct ospf_lsdb
));
47 ospf_lsdb_init (struct ospf_lsdb
*lsdb
)
51 for (i
= OSPF_MIN_LSA
; i
< OSPF_MAX_LSA
; i
++)
52 lsdb
->type
[i
].db
= route_table_init ();
56 ospf_lsdb_free (struct ospf_lsdb
*lsdb
)
58 ospf_lsdb_cleanup (lsdb
);
59 XFREE (MTYPE_OSPF_LSDB
, lsdb
);
63 ospf_lsdb_cleanup (struct ospf_lsdb
*lsdb
)
67 assert (lsdb
->total
== 0);
69 ospf_lsdb_delete_all (lsdb
);
71 for (i
= OSPF_MIN_LSA
; i
< OSPF_MAX_LSA
; i
++)
72 route_table_finish (lsdb
->type
[i
].db
);
76 lsdb_prefix_set (struct prefix_ls
*lp
, struct ospf_lsa
*lsa
)
78 memset (lp
, 0, sizeof (struct prefix_ls
));
81 lp
->id
= lsa
->data
->id
;
82 lp
->adv_router
= lsa
->data
->adv_router
;
86 ospf_lsdb_delete_entry (struct ospf_lsdb
*lsdb
, struct route_node
*rn
)
88 struct ospf_lsa
*lsa
= rn
->info
;
93 assert (rn
->table
== lsdb
->type
[lsa
->data
->type
].db
);
95 if (IS_LSA_SELF (lsa
))
96 lsdb
->type
[lsa
->data
->type
].count_self
--;
97 lsdb
->type
[lsa
->data
->type
].count
--;
98 lsdb
->type
[lsa
->data
->type
].checksum
-= ntohs(lsa
->data
->checksum
);
101 route_unlock_node (rn
);
102 #ifdef MONITOR_LSDB_CHANGE
103 if (lsdb
->del_lsa_hook
!= NULL
)
104 (* lsdb
->del_lsa_hook
)(lsa
);
105 #endif /* MONITOR_LSDB_CHANGE */
106 ospf_lsa_unlock (&lsa
); /* lsdb */
110 /* Add new LSA to lsdb. */
112 ospf_lsdb_add (struct ospf_lsdb
*lsdb
, struct ospf_lsa
*lsa
)
114 struct route_table
*table
;
116 struct route_node
*rn
;
118 table
= lsdb
->type
[lsa
->data
->type
].db
;
119 lsdb_prefix_set (&lp
, lsa
);
120 rn
= route_node_get (table
, (struct prefix
*)&lp
);
123 if (rn
->info
&& rn
->info
== lsa
)
126 /* purge old entry? */
128 ospf_lsdb_delete_entry (lsdb
, rn
);
130 if (IS_LSA_SELF (lsa
))
131 lsdb
->type
[lsa
->data
->type
].count_self
++;
132 lsdb
->type
[lsa
->data
->type
].count
++;
135 #ifdef MONITOR_LSDB_CHANGE
136 if (lsdb
->new_lsa_hook
!= NULL
)
137 (* lsdb
->new_lsa_hook
)(lsa
);
138 #endif /* MONITOR_LSDB_CHANGE */
139 lsdb
->type
[lsa
->data
->type
].checksum
+= ntohs(lsa
->data
->checksum
);
140 rn
->info
= ospf_lsa_lock (lsa
); /* lsdb */
144 ospf_lsdb_delete (struct ospf_lsdb
*lsdb
, struct ospf_lsa
*lsa
)
146 struct route_table
*table
;
148 struct route_node
*rn
;
152 zlog_warn ("%s: Called with NULL LSDB", __func__
);
154 zlog_warn ("LSA[Type%d:%s]: LSA %p, lsa->lsdb %p",
155 lsa
->data
->type
, inet_ntoa (lsa
->data
->id
),
162 zlog_warn ("%s: Called with NULL LSA", __func__
);
166 table
= lsdb
->type
[lsa
->data
->type
].db
;
167 lsdb_prefix_set (&lp
, lsa
);
168 rn
= route_node_lookup (table
, (struct prefix
*) &lp
);
169 if (rn
&& (rn
->info
== lsa
))
171 ospf_lsdb_delete_entry (lsdb
, rn
);
172 route_unlock_node (rn
); /* route_node_lookup */
177 ospf_lsdb_delete_all (struct ospf_lsdb
*lsdb
)
179 struct route_table
*table
;
180 struct route_node
*rn
;
183 for (i
= OSPF_MIN_LSA
; i
< OSPF_MAX_LSA
; i
++)
185 table
= lsdb
->type
[i
].db
;
186 for (rn
= route_top (table
); rn
; rn
= route_next (rn
))
187 if (rn
->info
!= NULL
)
188 ospf_lsdb_delete_entry (lsdb
, rn
);
193 ospf_lsdb_clean_stat (struct ospf_lsdb
*lsdb
)
195 struct route_table
*table
;
196 struct route_node
*rn
;
197 struct ospf_lsa
*lsa
;
200 for (i
= OSPF_MIN_LSA
; i
< OSPF_MAX_LSA
; i
++)
202 table
= lsdb
->type
[i
].db
;
203 for (rn
= route_top (table
); rn
; rn
= route_next (rn
))
204 if ((lsa
= (rn
->info
)) != NULL
)
205 lsa
->stat
= LSA_SPF_NOT_EXPLORED
;
210 ospf_lsdb_lookup (struct ospf_lsdb
*lsdb
, struct ospf_lsa
*lsa
)
212 struct route_table
*table
;
214 struct route_node
*rn
;
215 struct ospf_lsa
*find
;
217 table
= lsdb
->type
[lsa
->data
->type
].db
;
218 lsdb_prefix_set (&lp
, lsa
);
219 rn
= route_node_lookup (table
, (struct prefix
*) &lp
);
223 route_unlock_node (rn
);
230 ospf_lsdb_lookup_by_id (struct ospf_lsdb
*lsdb
, u_char type
,
231 struct in_addr id
, struct in_addr adv_router
)
233 struct route_table
*table
;
235 struct route_node
*rn
;
236 struct ospf_lsa
*find
;
238 table
= lsdb
->type
[type
].db
;
240 memset (&lp
, 0, sizeof (struct prefix_ls
));
244 lp
.adv_router
= adv_router
;
246 rn
= route_node_lookup (table
, (struct prefix
*) &lp
);
250 route_unlock_node (rn
);
257 ospf_lsdb_lookup_by_id_next (struct ospf_lsdb
*lsdb
, u_char type
,
258 struct in_addr id
, struct in_addr adv_router
,
261 struct route_table
*table
;
263 struct route_node
*rn
;
264 struct ospf_lsa
*find
;
266 table
= lsdb
->type
[type
].db
;
268 memset (&lp
, 0, sizeof (struct prefix_ls
));
272 lp
.adv_router
= adv_router
;
275 rn
= route_top (table
);
278 rn
= route_node_get (table
, (struct prefix
*) &lp
);
279 rn
= route_next (rn
);
282 for (; rn
; rn
= route_next (rn
))
289 route_unlock_node (rn
);
296 ospf_lsdb_count_all (struct ospf_lsdb
*lsdb
)
302 ospf_lsdb_count (struct ospf_lsdb
*lsdb
, int type
)
304 return lsdb
->type
[type
].count
;
308 ospf_lsdb_count_self (struct ospf_lsdb
*lsdb
, int type
)
310 return lsdb
->type
[type
].count_self
;
314 ospf_lsdb_checksum (struct ospf_lsdb
*lsdb
, int type
)
316 return lsdb
->type
[type
].checksum
;
320 ospf_lsdb_isempty (struct ospf_lsdb
*lsdb
)
322 return (lsdb
->total
== 0);