]>
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
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 ls_prefix_set (struct prefix_ls
*lp
, struct ospf_lsa
*lsa
)
78 if (lp
&& lsa
&& lsa
->data
)
82 lp
->id
= lsa
->data
->id
;
83 lp
->adv_router
= lsa
->data
->adv_router
;
88 ospf_lsdb_delete_entry (struct ospf_lsdb
*lsdb
, struct route_node
*rn
)
90 struct ospf_lsa
*lsa
= rn
->info
;
95 assert (rn
->table
== lsdb
->type
[lsa
->data
->type
].db
);
97 if (IS_LSA_SELF (lsa
))
98 lsdb
->type
[lsa
->data
->type
].count_self
--;
99 lsdb
->type
[lsa
->data
->type
].count
--;
100 lsdb
->type
[lsa
->data
->type
].checksum
-= ntohs(lsa
->data
->checksum
);
103 route_unlock_node (rn
);
104 #ifdef MONITOR_LSDB_CHANGE
105 if (lsdb
->del_lsa_hook
!= NULL
)
106 (* lsdb
->del_lsa_hook
)(lsa
);
107 #endif /* MONITOR_LSDB_CHANGE */
108 ospf_lsa_unlock (&lsa
); /* lsdb */
112 /* Add new LSA to lsdb. */
114 ospf_lsdb_add (struct ospf_lsdb
*lsdb
, struct ospf_lsa
*lsa
)
116 struct route_table
*table
;
118 struct route_node
*rn
;
120 table
= lsdb
->type
[lsa
->data
->type
].db
;
121 ls_prefix_set (&lp
, lsa
);
122 rn
= route_node_get (table
, (struct prefix
*)&lp
);
125 if (rn
->info
&& rn
->info
== lsa
)
127 route_unlock_node (rn
);
131 /* purge old entry? */
133 ospf_lsdb_delete_entry (lsdb
, rn
);
135 if (IS_LSA_SELF (lsa
))
136 lsdb
->type
[lsa
->data
->type
].count_self
++;
137 lsdb
->type
[lsa
->data
->type
].count
++;
140 #ifdef MONITOR_LSDB_CHANGE
141 if (lsdb
->new_lsa_hook
!= NULL
)
142 (* lsdb
->new_lsa_hook
)(lsa
);
143 #endif /* MONITOR_LSDB_CHANGE */
144 lsdb
->type
[lsa
->data
->type
].checksum
+= ntohs(lsa
->data
->checksum
);
145 rn
->info
= ospf_lsa_lock (lsa
); /* lsdb */
149 ospf_lsdb_delete (struct ospf_lsdb
*lsdb
, struct ospf_lsa
*lsa
)
151 struct route_table
*table
;
153 struct route_node
*rn
;
157 zlog_warn ("%s: Called with NULL LSDB", __func__
);
159 zlog_warn ("LSA[Type%d:%s]: LSA %p, lsa->lsdb %p",
160 lsa
->data
->type
, inet_ntoa (lsa
->data
->id
),
167 zlog_warn ("%s: Called with NULL LSA", __func__
);
171 assert (lsa
->data
->type
< OSPF_MAX_LSA
);
172 table
= lsdb
->type
[lsa
->data
->type
].db
;
173 ls_prefix_set (&lp
, lsa
);
174 if ((rn
= route_node_lookup (table
, (struct prefix
*) &lp
)))
177 ospf_lsdb_delete_entry (lsdb
, rn
);
178 route_unlock_node (rn
); /* route_node_lookup */
183 ospf_lsdb_delete_all (struct ospf_lsdb
*lsdb
)
185 struct route_table
*table
;
186 struct route_node
*rn
;
189 for (i
= OSPF_MIN_LSA
; i
< OSPF_MAX_LSA
; i
++)
191 table
= lsdb
->type
[i
].db
;
192 for (rn
= route_top (table
); rn
; rn
= route_next (rn
))
193 if (rn
->info
!= NULL
)
194 ospf_lsdb_delete_entry (lsdb
, rn
);
199 ospf_lsdb_clean_stat (struct ospf_lsdb
*lsdb
)
201 struct route_table
*table
;
202 struct route_node
*rn
;
203 struct ospf_lsa
*lsa
;
206 for (i
= OSPF_MIN_LSA
; i
< OSPF_MAX_LSA
; i
++)
208 table
= lsdb
->type
[i
].db
;
209 for (rn
= route_top (table
); rn
; rn
= route_next (rn
))
210 if ((lsa
= (rn
->info
)) != NULL
)
211 lsa
->stat
= LSA_SPF_NOT_EXPLORED
;
216 ospf_lsdb_lookup (struct ospf_lsdb
*lsdb
, struct ospf_lsa
*lsa
)
218 struct route_table
*table
;
220 struct route_node
*rn
;
221 struct ospf_lsa
*find
;
223 table
= lsdb
->type
[lsa
->data
->type
].db
;
224 ls_prefix_set (&lp
, lsa
);
225 rn
= route_node_lookup (table
, (struct prefix
*) &lp
);
229 route_unlock_node (rn
);
236 ospf_lsdb_lookup_by_id (struct ospf_lsdb
*lsdb
, u_char type
,
237 struct in_addr id
, struct in_addr adv_router
)
239 struct route_table
*table
;
241 struct route_node
*rn
;
242 struct ospf_lsa
*find
;
244 table
= lsdb
->type
[type
].db
;
246 memset (&lp
, 0, sizeof (struct prefix_ls
));
250 lp
.adv_router
= adv_router
;
252 rn
= route_node_lookup (table
, (struct prefix
*) &lp
);
256 route_unlock_node (rn
);
263 ospf_lsdb_lookup_by_id_next (struct ospf_lsdb
*lsdb
, u_char type
,
264 struct in_addr id
, struct in_addr adv_router
,
267 struct route_table
*table
;
269 struct route_node
*rn
;
270 struct ospf_lsa
*find
;
272 table
= lsdb
->type
[type
].db
;
274 memset (&lp
, 0, sizeof (struct prefix_ls
));
278 lp
.adv_router
= adv_router
;
281 rn
= route_top (table
);
284 if ((rn
= route_node_lookup (table
, (struct prefix
*) &lp
)) == NULL
)
286 rn
= route_next (rn
);
289 for (; rn
; rn
= route_next (rn
))
296 route_unlock_node (rn
);
303 ospf_lsdb_count_all (struct ospf_lsdb
*lsdb
)
309 ospf_lsdb_count (struct ospf_lsdb
*lsdb
, int type
)
311 return lsdb
->type
[type
].count
;
315 ospf_lsdb_count_self (struct ospf_lsdb
*lsdb
, int type
)
317 return lsdb
->type
[type
].count_self
;
321 ospf_lsdb_checksum (struct ospf_lsdb
*lsdb
, int type
)
323 return lsdb
->type
[type
].checksum
;
327 ospf_lsdb_isempty (struct ospf_lsdb
*lsdb
)
329 return (lsdb
->total
== 0);