2 * Copyright (C) 2003 Yasuhiro Ohara
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30 #include "ospf6_proto.h"
31 #include "ospf6_lsa.h"
32 #include "ospf6_lsdb.h"
33 #include "ospf6_route.h"
38 ospf6_lsdb_create (void *data
)
40 struct ospf6_lsdb
*lsdb
;
42 lsdb
= XCALLOC (MTYPE_OSPF6_LSDB
, sizeof (struct ospf6_lsdb
));
45 zlog_warn ("Can't malloc lsdb");
48 memset (lsdb
, 0, sizeof (struct ospf6_lsdb
));
51 lsdb
->table
= route_table_init ();
56 ospf6_lsdb_delete (struct ospf6_lsdb
*lsdb
)
60 ospf6_lsdb_remove_all (lsdb
);
61 route_table_finish (lsdb
->table
);
62 XFREE (MTYPE_OSPF6_LSDB
, lsdb
);
67 ospf6_lsdb_set_key (struct prefix_ipv6
*key
, const void *value
, int len
)
69 assert (key
->prefixlen
% 8 == 0);
71 memcpy ((caddr_t
) &key
->prefix
+ key
->prefixlen
/ 8,
72 (caddr_t
) value
, len
);
73 key
->family
= AF_INET6
;
74 key
->prefixlen
+= len
* 8;
79 _lsdb_count_assert (struct ospf6_lsdb
*lsdb
)
81 struct ospf6_lsa
*debug
;
83 for (ALL_LSDB(lsdb
, debug
))
86 if (num
== lsdb
->count
)
89 zlog_debug ("PANIC !! lsdb[%p]->count = %d, real = %d",
90 lsdb
, lsdb
->count
, num
);
91 for (ALL_LSDB(lsdb
, debug
))
92 zlog_debug ("%p %p %s lsdb[%p]", debug
->prev
, debug
->next
, debug
->name
,
94 zlog_debug ("DUMP END");
96 assert (num
== lsdb
->count
);
98 #define ospf6_lsdb_count_assert(t) (_lsdb_count_assert (t))
100 #define ospf6_lsdb_count_assert(t) ((void) 0)
104 ospf6_lsdb_add (struct ospf6_lsa
*lsa
, struct ospf6_lsdb
*lsdb
)
106 struct prefix_ipv6 key
;
107 struct route_node
*current
;
108 struct ospf6_lsa
*old
= NULL
;
110 memset (&key
, 0, sizeof (key
));
111 ospf6_lsdb_set_key (&key
, &lsa
->header
->type
, sizeof (lsa
->header
->type
));
112 ospf6_lsdb_set_key (&key
, &lsa
->header
->adv_router
,
113 sizeof (lsa
->header
->adv_router
));
114 ospf6_lsdb_set_key (&key
, &lsa
->header
->id
, sizeof (lsa
->header
->id
));
116 current
= route_node_get (lsdb
->table
, (struct prefix
*) &key
);
120 ospf6_lsa_lock (lsa
);
126 if (OSPF6_LSA_IS_MAXAGE (lsa
))
128 if (lsdb
->hook_remove
)
129 (*lsdb
->hook_remove
) (lsa
);
134 (*lsdb
->hook_add
) (lsa
);
139 if (OSPF6_LSA_IS_CHANGED (old
, lsa
))
141 if (OSPF6_LSA_IS_MAXAGE (lsa
))
143 if (lsdb
->hook_remove
)
145 (*lsdb
->hook_remove
) (old
);
146 (*lsdb
->hook_remove
) (lsa
);
149 else if (OSPF6_LSA_IS_MAXAGE (old
))
152 (*lsdb
->hook_add
) (lsa
);
156 if (lsdb
->hook_remove
)
157 (*lsdb
->hook_remove
) (old
);
159 (*lsdb
->hook_add
) (lsa
);
162 ospf6_lsa_unlock (old
);
165 ospf6_lsdb_count_assert (lsdb
);
169 ospf6_lsdb_remove (struct ospf6_lsa
*lsa
, struct ospf6_lsdb
*lsdb
)
171 struct route_node
*node
;
172 struct prefix_ipv6 key
;
174 memset (&key
, 0, sizeof (key
));
175 ospf6_lsdb_set_key (&key
, &lsa
->header
->type
, sizeof (lsa
->header
->type
));
176 ospf6_lsdb_set_key (&key
, &lsa
->header
->adv_router
,
177 sizeof (lsa
->header
->adv_router
));
178 ospf6_lsdb_set_key (&key
, &lsa
->header
->id
, sizeof (lsa
->header
->id
));
180 node
= route_node_lookup (lsdb
->table
, (struct prefix
*) &key
);
181 assert (node
&& node
->info
== lsa
);
186 if (lsdb
->hook_remove
)
187 (*lsdb
->hook_remove
) (lsa
);
189 route_unlock_node (node
); /* to free the lookup lock */
190 route_unlock_node (node
); /* to free the original lock */
191 ospf6_lsa_unlock (lsa
);
193 ospf6_lsdb_count_assert (lsdb
);
197 ospf6_lsdb_lookup (u_int16_t type
, u_int32_t id
, u_int32_t adv_router
,
198 struct ospf6_lsdb
*lsdb
)
200 struct route_node
*node
;
201 struct prefix_ipv6 key
;
206 memset (&key
, 0, sizeof (key
));
207 ospf6_lsdb_set_key (&key
, &type
, sizeof (type
));
208 ospf6_lsdb_set_key (&key
, &adv_router
, sizeof (adv_router
));
209 ospf6_lsdb_set_key (&key
, &id
, sizeof (id
));
211 node
= route_node_lookup (lsdb
->table
, (struct prefix
*) &key
);
212 if (node
== NULL
|| node
->info
== NULL
)
215 route_unlock_node (node
);
216 return (struct ospf6_lsa
*) node
->info
;
220 ospf6_lsdb_lookup_next (u_int16_t type
, u_int32_t id
, u_int32_t adv_router
,
221 struct ospf6_lsdb
*lsdb
)
223 struct route_node
*node
;
224 struct prefix_ipv6 key
;
229 memset (&key
, 0, sizeof (key
));
230 ospf6_lsdb_set_key (&key
, &type
, sizeof (type
));
231 ospf6_lsdb_set_key (&key
, &adv_router
, sizeof (adv_router
));
232 ospf6_lsdb_set_key (&key
, &id
, sizeof (id
));
235 char buf
[PREFIX2STR_BUFFER
];
236 prefix2str (&key
, buf
, sizeof (buf
));
237 zlog_debug ("lsdb_lookup_next: key: %s", buf
);
240 node
= route_table_get_next (lsdb
->table
, &key
);
242 /* skip to real existing entry */
243 while (node
&& node
->info
== NULL
)
244 node
= route_next (node
);
249 route_unlock_node (node
);
253 return (struct ospf6_lsa
*) node
->info
;
256 const struct route_node
*
257 ospf6_lsdb_head (struct ospf6_lsdb
*lsdb
,
258 int argmode
, uint16_t type
, uint32_t adv_router
,
259 struct ospf6_lsa
**lsa
)
261 struct route_node
*node
, *end
;
267 struct prefix_ipv6 key
= { .family
= AF_INET6
, .prefixlen
= 0 };
269 ospf6_lsdb_set_key (&key
, &type
, sizeof (type
));
271 ospf6_lsdb_set_key (&key
, &adv_router
, sizeof (adv_router
));
273 node
= route_table_get_next (lsdb
->table
, &key
);
274 if (!node
|| !prefix_match((struct prefix
*)&key
, &node
->p
))
278 end
&& end
->parent
&& end
->parent
->p
.prefixlen
>= key
.prefixlen
;
284 node
= route_top (lsdb
->table
);
288 while (node
&& !node
->info
)
289 node
= route_next_until(node
, end
);
295 route_unlock_node(node
);
300 ospf6_lsa_lock (*lsa
);
306 ospf6_lsdb_next (const struct route_node
*iterend
,
307 struct ospf6_lsa
*lsa
)
309 struct route_node
*node
= lsa
->rn
;
311 ospf6_lsa_unlock(lsa
);
314 node
= route_next_until(node
, iterend
);
315 while (node
&& !node
->info
);
317 if (node
&& node
->info
)
319 struct ospf6_lsa
*next
= node
->info
;
320 ospf6_lsa_lock (next
);
325 route_unlock_node (node
);
330 ospf6_lsdb_remove_all (struct ospf6_lsdb
*lsdb
)
332 struct ospf6_lsa
*lsa
;
337 for (ALL_LSDB(lsdb
, lsa
))
338 ospf6_lsdb_remove (lsa
, lsdb
);
342 ospf6_lsdb_lsa_unlock (struct ospf6_lsa
*lsa
)
347 route_unlock_node (lsa
->rn
);
348 ospf6_lsa_unlock (lsa
);
353 ospf6_lsdb_maxage_remover (struct ospf6_lsdb
*lsdb
)
356 struct ospf6_lsa
*lsa
;
358 for (ALL_LSDB(lsdb
, lsa
))
360 if (! OSPF6_LSA_IS_MAXAGE (lsa
))
362 if (lsa
->retrans_count
!= 0)
367 if (IS_OSPF6_DEBUG_LSA_TYPE (lsa
->header
->type
))
368 zlog_debug ("Remove MaxAge %s", lsa
->name
);
369 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_SEQWRAPPED
))
371 UNSET_FLAG(lsa
->flag
, OSPF6_LSA_SEQWRAPPED
);
373 * lsa->header->age = 0;
375 lsa
->header
->seqnum
= htonl(OSPF_MAX_SEQUENCE_NUMBER
+ 1);
376 ospf6_lsa_checksum (lsa
->header
);
378 THREAD_OFF(lsa
->refresh
);
379 thread_execute (master
, ospf6_lsa_refresh
, lsa
, 0);
381 ospf6_lsdb_remove (lsa
, lsdb
);
389 ospf6_lsdb_show (struct vty
*vty
, enum ospf_lsdb_show_level level
,
390 u_int16_t
*type
, u_int32_t
*id
, u_int32_t
*adv_router
,
391 struct ospf6_lsdb
*lsdb
)
393 struct ospf6_lsa
*lsa
;
394 const struct route_node
*end
= NULL
;
395 void (*showfunc
) (struct vty
*, struct ospf6_lsa
*) = NULL
;
399 case OSPF6_LSDB_SHOW_LEVEL_DETAIL
:
400 showfunc
= ospf6_lsa_show
;
402 case OSPF6_LSDB_SHOW_LEVEL_INTERNAL
:
403 showfunc
= ospf6_lsa_show_internal
;
405 case OSPF6_LSDB_SHOW_LEVEL_DUMP
:
406 showfunc
= ospf6_lsa_show_dump
;
408 case OSPF6_LSDB_SHOW_LEVEL_NORMAL
:
410 showfunc
= ospf6_lsa_show_summary
;
413 if (type
&& id
&& adv_router
)
415 lsa
= ospf6_lsdb_lookup (*type
, *id
, *adv_router
, lsdb
);
418 if (level
== OSPF6_LSDB_SHOW_LEVEL_NORMAL
)
419 ospf6_lsa_show (vty
, lsa
);
421 (*showfunc
) (vty
, lsa
);
426 if (level
== OSPF6_LSDB_SHOW_LEVEL_NORMAL
)
427 ospf6_lsa_show_summary_header (vty
);
429 end
= ospf6_lsdb_head(lsdb
, !!type
+ !!(type
&& adv_router
),
430 *type
, *adv_router
, &lsa
);
433 if ((! adv_router
|| lsa
->header
->adv_router
== *adv_router
) &&
434 (! id
|| lsa
->header
->id
== *id
))
435 (*showfunc
) (vty
, lsa
);
437 lsa
= ospf6_lsdb_next (end
, lsa
);
442 ospf6_new_ls_id (u_int16_t type
, u_int32_t adv_router
,
443 struct ospf6_lsdb
*lsdb
)
445 struct ospf6_lsa
*lsa
;
446 u_int32_t id
= 1, tmp_id
;
448 /* This routine is curently invoked only for Inter-Prefix LSAs for
449 * non-summarized routes (no area/range).
451 for (ALL_LSDB_TYPED_ADVRTR(lsdb
, type
, adv_router
, lsa
))
453 tmp_id
= ntohl (lsa
->header
->id
);
459 ospf6_lsdb_lsa_unlock (lsa
);
465 return ((u_int32_t
) htonl (id
));
468 /* Decide new LS sequence number to originate.
469 note return value is network byte order */
471 ospf6_new_ls_seqnum (u_int16_t type
, u_int32_t id
, u_int32_t adv_router
,
472 struct ospf6_lsdb
*lsdb
)
474 struct ospf6_lsa
*lsa
;
475 signed long seqnum
= 0;
477 /* if current database copy not found, return InitialSequenceNumber */
478 lsa
= ospf6_lsdb_lookup (type
, id
, adv_router
, lsdb
);
480 seqnum
= OSPF_INITIAL_SEQUENCE_NUMBER
;
482 seqnum
= (signed long) ntohl (lsa
->header
->seqnum
) + 1;
484 return ((u_int32_t
) htonl (seqnum
));