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
)
80 lp
->id
= lsa
->data
->id
;
81 lp
->adv_router
= lsa
->data
->adv_router
;
85 ospf_lsdb_delete_entry (struct ospf_lsdb
*lsdb
, struct route_node
*rn
)
87 struct ospf_lsa
*lsa
= rn
->info
;
92 assert (rn
->table
== lsdb
->type
[lsa
->data
->type
].db
);
94 if (IS_LSA_SELF (lsa
))
95 lsdb
->type
[lsa
->data
->type
].count_self
--;
96 lsdb
->type
[lsa
->data
->type
].count
--;
97 lsdb
->type
[lsa
->data
->type
].checksum
-= ntohs(lsa
->data
->checksum
);
100 route_unlock_node (rn
);
101 #ifdef MONITOR_LSDB_CHANGE
102 if (lsdb
->del_lsa_hook
!= NULL
)
103 (* lsdb
->del_lsa_hook
)(lsa
);
104 #endif /* MONITOR_LSDB_CHANGE */
105 ospf_lsa_unlock (&lsa
); /* lsdb */
109 /* Add new LSA to lsdb. */
111 ospf_lsdb_add (struct ospf_lsdb
*lsdb
, struct ospf_lsa
*lsa
)
113 struct route_table
*table
;
115 struct route_node
*rn
;
117 table
= lsdb
->type
[lsa
->data
->type
].db
;
118 lsdb_prefix_set (&lp
, lsa
);
119 rn
= route_node_get (table
, (struct prefix
*)&lp
);
122 if (rn
->info
&& rn
->info
== lsa
)
125 /* purge old entry? */
127 ospf_lsdb_delete_entry (lsdb
, rn
);
129 if (IS_LSA_SELF (lsa
))
130 lsdb
->type
[lsa
->data
->type
].count_self
++;
131 lsdb
->type
[lsa
->data
->type
].count
++;
134 #ifdef MONITOR_LSDB_CHANGE
135 if (lsdb
->new_lsa_hook
!= NULL
)
136 (* lsdb
->new_lsa_hook
)(lsa
);
137 #endif /* MONITOR_LSDB_CHANGE */
138 lsdb
->type
[lsa
->data
->type
].checksum
+= ntohs(lsa
->data
->checksum
);
139 rn
->info
= ospf_lsa_lock (lsa
); /* lsdb */
143 ospf_lsdb_delete (struct ospf_lsdb
*lsdb
, struct ospf_lsa
*lsa
)
145 struct route_table
*table
;
147 struct route_node
*rn
;
151 zlog_warn ("%s: Called with NULL LSDB", __func__
);
153 zlog_warn ("LSA[Type%d:%s]: LSA %p, lsa->lsdb %p",
154 lsa
->data
->type
, inet_ntoa (lsa
->data
->id
),
161 zlog_warn ("%s: Called with NULL LSA", __func__
);
165 table
= lsdb
->type
[lsa
->data
->type
].db
;
166 lsdb_prefix_set (&lp
, lsa
);
167 rn
= route_node_lookup (table
, (struct prefix
*) &lp
);
168 if (rn
&& (rn
->info
== lsa
))
170 ospf_lsdb_delete_entry (lsdb
, rn
);
171 route_unlock_node (rn
); /* route_node_lookup */
176 ospf_lsdb_delete_all (struct ospf_lsdb
*lsdb
)
178 struct route_table
*table
;
179 struct route_node
*rn
;
182 for (i
= OSPF_MIN_LSA
; i
< OSPF_MAX_LSA
; i
++)
184 table
= lsdb
->type
[i
].db
;
185 for (rn
= route_top (table
); rn
; rn
= route_next (rn
))
186 if (rn
->info
!= NULL
)
187 ospf_lsdb_delete_entry (lsdb
, rn
);
192 ospf_lsdb_clean_stat (struct ospf_lsdb
*lsdb
)
194 struct route_table
*table
;
195 struct route_node
*rn
;
196 struct ospf_lsa
*lsa
;
199 for (i
= OSPF_MIN_LSA
; i
< OSPF_MAX_LSA
; i
++)
201 table
= lsdb
->type
[i
].db
;
202 for (rn
= route_top (table
); rn
; rn
= route_next (rn
))
203 if ((lsa
= (rn
->info
)) != NULL
)
204 lsa
->stat
= LSA_SPF_NOT_EXPLORED
;
209 ospf_lsdb_lookup (struct ospf_lsdb
*lsdb
, struct ospf_lsa
*lsa
)
211 struct route_table
*table
;
213 struct route_node
*rn
;
214 struct ospf_lsa
*find
;
216 table
= lsdb
->type
[lsa
->data
->type
].db
;
217 lsdb_prefix_set (&lp
, lsa
);
218 rn
= route_node_lookup (table
, (struct prefix
*) &lp
);
222 route_unlock_node (rn
);
229 ospf_lsdb_lookup_by_id (struct ospf_lsdb
*lsdb
, u_char type
,
230 struct in_addr id
, struct in_addr adv_router
)
232 struct route_table
*table
;
234 struct route_node
*rn
;
235 struct ospf_lsa
*find
;
237 table
= lsdb
->type
[type
].db
;
239 memset (&lp
, 0, sizeof (struct prefix_ls
));
243 lp
.adv_router
= adv_router
;
245 rn
= route_node_lookup (table
, (struct prefix
*) &lp
);
249 route_unlock_node (rn
);
256 ospf_lsdb_lookup_by_id_next (struct ospf_lsdb
*lsdb
, u_char type
,
257 struct in_addr id
, struct in_addr adv_router
,
260 struct route_table
*table
;
262 struct route_node
*rn
;
263 struct ospf_lsa
*find
;
265 table
= lsdb
->type
[type
].db
;
267 memset (&lp
, 0, sizeof (struct prefix_ls
));
271 lp
.adv_router
= adv_router
;
274 rn
= route_top (table
);
277 rn
= route_node_get (table
, (struct prefix
*) &lp
);
278 rn
= route_next (rn
);
281 for (; rn
; rn
= route_next (rn
))
288 route_unlock_node (rn
);
295 ospf_lsdb_count_all (struct ospf_lsdb
*lsdb
)
301 ospf_lsdb_count (struct ospf_lsdb
*lsdb
, int type
)
303 return lsdb
->type
[type
].count
;
307 ospf_lsdb_count_self (struct ospf_lsdb
*lsdb
, int type
)
309 return lsdb
->type
[type
].count_self
;
313 ospf_lsdb_checksum (struct ospf_lsdb
*lsdb
, int type
)
315 return lsdb
->type
[type
].checksum
;
319 ospf_lsdb_isempty (struct ospf_lsdb
*lsdb
)
321 return (lsdb
->total
== 0);