]>
git.proxmox.com Git - mirror_frr.git/blob - ospfd/ospf_lsdb.c
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 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
29 #include "ospfd/ospfd.h"
30 #include "ospfd/ospf_asbr.h"
31 #include "ospfd/ospf_lsa.h"
32 #include "ospfd/ospf_lsdb.h"
37 struct ospf_lsdb
*new;
39 new = XCALLOC (MTYPE_OSPF_LSDB
, sizeof (struct ospf_lsdb
));
46 ospf_lsdb_init (struct ospf_lsdb
*lsdb
)
50 for (i
= OSPF_MIN_LSA
; i
< OSPF_MAX_LSA
; i
++)
51 lsdb
->type
[i
].db
= route_table_init ();
55 ospf_lsdb_free (struct ospf_lsdb
*lsdb
)
57 ospf_lsdb_cleanup (lsdb
);
58 XFREE (MTYPE_OSPF_LSDB
, lsdb
);
62 ospf_lsdb_cleanup (struct ospf_lsdb
*lsdb
)
66 assert (lsdb
->total
== 0);
68 ospf_lsdb_delete_all (lsdb
);
70 for (i
= OSPF_MIN_LSA
; i
< OSPF_MAX_LSA
; i
++)
71 route_table_finish (lsdb
->type
[i
].db
);
75 ls_prefix_set (struct prefix_ls
*lp
, struct ospf_lsa
*lsa
)
77 if (lp
&& lsa
&& lsa
->data
)
81 lp
->id
= lsa
->data
->id
;
82 lp
->adv_router
= lsa
->data
->adv_router
;
87 ospf_lsdb_delete_entry (struct ospf_lsdb
*lsdb
, struct route_node
*rn
)
89 struct ospf_lsa
*lsa
= rn
->info
;
94 assert (rn
->table
== lsdb
->type
[lsa
->data
->type
].db
);
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
);
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 */
111 /* Add new LSA to lsdb. */
113 ospf_lsdb_add (struct ospf_lsdb
*lsdb
, struct ospf_lsa
*lsa
)
115 struct route_table
*table
;
117 struct route_node
*rn
;
119 table
= lsdb
->type
[lsa
->data
->type
].db
;
120 ls_prefix_set (&lp
, lsa
);
121 rn
= route_node_get (table
, (struct prefix
*)&lp
);
124 if (rn
->info
&& rn
->info
== lsa
)
126 route_unlock_node (rn
);
130 /* purge old entry? */
132 ospf_lsdb_delete_entry (lsdb
, rn
);
134 if (IS_LSA_SELF (lsa
))
135 lsdb
->type
[lsa
->data
->type
].count_self
++;
136 lsdb
->type
[lsa
->data
->type
].count
++;
139 #ifdef MONITOR_LSDB_CHANGE
140 if (lsdb
->new_lsa_hook
!= NULL
)
141 (* lsdb
->new_lsa_hook
)(lsa
);
142 #endif /* MONITOR_LSDB_CHANGE */
143 lsdb
->type
[lsa
->data
->type
].checksum
+= ntohs(lsa
->data
->checksum
);
144 rn
->info
= ospf_lsa_lock (lsa
); /* lsdb */
148 ospf_lsdb_delete (struct ospf_lsdb
*lsdb
, struct ospf_lsa
*lsa
)
150 struct route_table
*table
;
152 struct route_node
*rn
;
156 zlog_warn ("%s: Called with NULL LSDB", __func__
);
158 zlog_warn ("LSA[Type%d:%s]: LSA %p, lsa->lsdb %p",
159 lsa
->data
->type
, inet_ntoa (lsa
->data
->id
),
160 (void *)lsa
, (void *)lsa
->lsdb
);
166 zlog_warn ("%s: Called with NULL LSA", __func__
);
170 assert (lsa
->data
->type
< OSPF_MAX_LSA
);
171 table
= lsdb
->type
[lsa
->data
->type
].db
;
172 ls_prefix_set (&lp
, lsa
);
173 if ((rn
= route_node_lookup (table
, (struct prefix
*) &lp
)))
176 ospf_lsdb_delete_entry (lsdb
, rn
);
177 route_unlock_node (rn
); /* route_node_lookup */
182 ospf_lsdb_delete_all (struct ospf_lsdb
*lsdb
)
184 struct route_table
*table
;
185 struct route_node
*rn
;
188 for (i
= OSPF_MIN_LSA
; i
< OSPF_MAX_LSA
; i
++)
190 table
= lsdb
->type
[i
].db
;
191 for (rn
= route_top (table
); rn
; rn
= route_next (rn
))
192 if (rn
->info
!= NULL
)
193 ospf_lsdb_delete_entry (lsdb
, rn
);
198 ospf_lsdb_clean_stat (struct ospf_lsdb
*lsdb
)
200 struct route_table
*table
;
201 struct route_node
*rn
;
202 struct ospf_lsa
*lsa
;
205 for (i
= OSPF_MIN_LSA
; i
< OSPF_MAX_LSA
; i
++)
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
;
215 ospf_lsdb_lookup (struct ospf_lsdb
*lsdb
, struct ospf_lsa
*lsa
)
217 struct route_table
*table
;
219 struct route_node
*rn
;
220 struct ospf_lsa
*find
;
222 table
= lsdb
->type
[lsa
->data
->type
].db
;
223 ls_prefix_set (&lp
, lsa
);
224 rn
= route_node_lookup (table
, (struct prefix
*) &lp
);
228 route_unlock_node (rn
);
235 ospf_lsdb_lookup_by_id (struct ospf_lsdb
*lsdb
, u_char type
,
236 struct in_addr id
, struct in_addr adv_router
)
238 struct route_table
*table
;
240 struct route_node
*rn
;
241 struct ospf_lsa
*find
;
243 table
= lsdb
->type
[type
].db
;
245 memset (&lp
, 0, sizeof (struct prefix_ls
));
249 lp
.adv_router
= adv_router
;
251 rn
= route_node_lookup (table
, (struct prefix
*) &lp
);
255 route_unlock_node (rn
);
262 ospf_lsdb_lookup_by_id_next (struct ospf_lsdb
*lsdb
, u_char type
,
263 struct in_addr id
, struct in_addr adv_router
,
266 struct route_table
*table
;
268 struct route_node
*rn
;
269 struct ospf_lsa
*find
;
271 table
= lsdb
->type
[type
].db
;
273 memset (&lp
, 0, sizeof (struct prefix_ls
));
277 lp
.adv_router
= adv_router
;
280 rn
= route_top (table
);
283 if ((rn
= route_node_lookup (table
, (struct prefix
*) &lp
)) == NULL
)
285 rn
= route_next (rn
);
288 for (; rn
; rn
= route_next (rn
))
295 route_unlock_node (rn
);
302 ospf_lsdb_count_all (struct ospf_lsdb
*lsdb
)
308 ospf_lsdb_count (struct ospf_lsdb
*lsdb
, int type
)
310 return lsdb
->type
[type
].count
;
314 ospf_lsdb_count_self (struct ospf_lsdb
*lsdb
, int type
)
316 return lsdb
->type
[type
].count_self
;
320 ospf_lsdb_checksum (struct ospf_lsdb
*lsdb
, int type
)
322 return lsdb
->type
[type
].checksum
;
326 ospf_lsdb_isempty (struct ospf_lsdb
*lsdb
)
328 return (lsdb
->total
== 0);