]> git.proxmox.com Git - mirror_frr.git/blame - ospf6d/ospf6_lsdb.c
isisd: The RFC states that v6 addresses are limited to 16 in a hello packet
[mirror_frr.git] / ospf6d / ospf6_lsdb.c
CommitLineData
718e3744 1/*
508e53e2 2 * Copyright (C) 2003 Yasuhiro Ohara
718e3744 3 *
4 * This file is part of GNU Zebra.
5 *
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
9 * later version.
10 *
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.
15 *
896014f4
DL
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
718e3744 19 */
20
21#include <zebra.h>
22
23#include "memory.h"
24#include "log.h"
25#include "command.h"
508e53e2 26#include "prefix.h"
27#include "table.h"
049207c3 28#include "vty.h"
718e3744 29
508e53e2 30#include "ospf6_proto.h"
31#include "ospf6_lsa.h"
718e3744 32#include "ospf6_lsdb.h"
c3c0ac83 33#include "ospf6_route.h"
049207c3 34#include "ospf6d.h"
c3c0ac83 35#include "bitfield.h"
718e3744 36
d62a17ae 37struct ospf6_lsdb *ospf6_lsdb_create(void *data)
718e3744 38{
d62a17ae 39 struct ospf6_lsdb *lsdb;
40
41 lsdb = XCALLOC(MTYPE_OSPF6_LSDB, sizeof(struct ospf6_lsdb));
d62a17ae 42 memset(lsdb, 0, sizeof(struct ospf6_lsdb));
43
44 lsdb->data = data;
45 lsdb->table = route_table_init();
46 return lsdb;
718e3744 47}
48
d62a17ae 49void ospf6_lsdb_delete(struct ospf6_lsdb *lsdb)
718e3744 50{
d62a17ae 51 if (lsdb != NULL) {
52 ospf6_lsdb_remove_all(lsdb);
53 route_table_finish(lsdb->table);
54 XFREE(MTYPE_OSPF6_LSDB, lsdb);
55 }
718e3744 56}
57
d62a17ae 58static void ospf6_lsdb_set_key(struct prefix_ipv6 *key, const void *value,
59 int len)
718e3744 60{
d62a17ae 61 assert(key->prefixlen % 8 == 0);
718e3744 62
d62a17ae 63 memcpy((caddr_t)&key->prefix + key->prefixlen / 8, (caddr_t)value, len);
64 key->family = AF_INET6;
65 key->prefixlen += len * 8;
508e53e2 66}
718e3744 67
e39d0538 68#ifdef DEBUG
d62a17ae 69static void _lsdb_count_assert(struct ospf6_lsdb *lsdb)
508e53e2 70{
d62a17ae 71 struct ospf6_lsa *debug;
72 unsigned int num = 0;
73 for (ALL_LSDB(lsdb, debug))
74 num++;
75
76 if (num == lsdb->count)
77 return;
78
79 zlog_debug("PANIC !! lsdb[%p]->count = %d, real = %d", lsdb,
80 lsdb->count, num);
81 for (ALL_LSDB(lsdb, debug))
c811f101 82 zlog_debug("%s lsdb[%p]", debug->name, debug->lsdb);
d62a17ae 83 zlog_debug("DUMP END");
84
85 assert(num == lsdb->count);
718e3744 86}
508e53e2 87#define ospf6_lsdb_count_assert(t) (_lsdb_count_assert (t))
d62a17ae 88#else /*DEBUG*/
508e53e2 89#define ospf6_lsdb_count_assert(t) ((void) 0)
e39d0538 90#endif /*DEBUG*/
718e3744 91
d62a17ae 92void ospf6_lsdb_add(struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb)
718e3744 93{
d62a17ae 94 struct prefix_ipv6 key;
95 struct route_node *current;
96 struct ospf6_lsa *old = NULL;
97
98 memset(&key, 0, sizeof(key));
99 ospf6_lsdb_set_key(&key, &lsa->header->type, sizeof(lsa->header->type));
100 ospf6_lsdb_set_key(&key, &lsa->header->adv_router,
101 sizeof(lsa->header->adv_router));
102 ospf6_lsdb_set_key(&key, &lsa->header->id, sizeof(lsa->header->id));
103
104 current = route_node_get(lsdb->table, (struct prefix *)&key);
105 old = current->info;
106 current->info = lsa;
107 lsa->rn = current;
108 ospf6_lsa_lock(lsa);
109
110 if (!old) {
111 lsdb->count++;
112
113 if (OSPF6_LSA_IS_MAXAGE(lsa)) {
114 if (lsdb->hook_remove)
115 (*lsdb->hook_remove)(lsa);
116 } else {
117 if (lsdb->hook_add)
118 (*lsdb->hook_add)(lsa);
119 }
120 } else {
121 if (OSPF6_LSA_IS_CHANGED(old, lsa)) {
122 if (OSPF6_LSA_IS_MAXAGE(lsa)) {
123 if (lsdb->hook_remove) {
124 (*lsdb->hook_remove)(old);
125 (*lsdb->hook_remove)(lsa);
126 }
127 } else if (OSPF6_LSA_IS_MAXAGE(old)) {
128 if (lsdb->hook_add)
129 (*lsdb->hook_add)(lsa);
130 } else {
131 if (lsdb->hook_remove)
132 (*lsdb->hook_remove)(old);
133 if (lsdb->hook_add)
134 (*lsdb->hook_add)(lsa);
135 }
136 }
d107621d
CS
137 /* to free the lookup lock in node get*/
138 route_unlock_node(current);
d62a17ae 139 ospf6_lsa_unlock(old);
a765eb93 140 }
d62a17ae 141
142 ospf6_lsdb_count_assert(lsdb);
718e3744 143}
144
d62a17ae 145void ospf6_lsdb_remove(struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb)
718e3744 146{
d62a17ae 147 struct route_node *node;
148 struct prefix_ipv6 key;
718e3744 149
d62a17ae 150 memset(&key, 0, sizeof(key));
151 ospf6_lsdb_set_key(&key, &lsa->header->type, sizeof(lsa->header->type));
152 ospf6_lsdb_set_key(&key, &lsa->header->adv_router,
153 sizeof(lsa->header->adv_router));
154 ospf6_lsdb_set_key(&key, &lsa->header->id, sizeof(lsa->header->id));
718e3744 155
d62a17ae 156 node = route_node_lookup(lsdb->table, (struct prefix *)&key);
157 assert(node && node->info == lsa);
718e3744 158
d62a17ae 159 node->info = NULL;
160 lsdb->count--;
718e3744 161
d62a17ae 162 if (lsdb->hook_remove)
163 (*lsdb->hook_remove)(lsa);
718e3744 164
d62a17ae 165 route_unlock_node(node); /* to free the lookup lock */
166 route_unlock_node(node); /* to free the original lock */
167 ospf6_lsa_unlock(lsa);
6452df09 168
d62a17ae 169 ospf6_lsdb_count_assert(lsdb);
718e3744 170}
171
d7c0a89a
QY
172struct ospf6_lsa *ospf6_lsdb_lookup(uint16_t type, uint32_t id,
173 uint32_t adv_router,
d62a17ae 174 struct ospf6_lsdb *lsdb)
718e3744 175{
d62a17ae 176 struct route_node *node;
177 struct prefix_ipv6 key;
718e3744 178
d62a17ae 179 if (lsdb == NULL)
180 return NULL;
718e3744 181
d62a17ae 182 memset(&key, 0, sizeof(key));
183 ospf6_lsdb_set_key(&key, &type, sizeof(type));
184 ospf6_lsdb_set_key(&key, &adv_router, sizeof(adv_router));
185 ospf6_lsdb_set_key(&key, &id, sizeof(id));
718e3744 186
d62a17ae 187 node = route_node_lookup(lsdb->table, (struct prefix *)&key);
188 if (node == NULL || node->info == NULL)
189 return NULL;
a765eb93 190
d62a17ae 191 route_unlock_node(node);
192 return (struct ospf6_lsa *)node->info;
718e3744 193}
194
d7c0a89a
QY
195struct ospf6_lsa *ospf6_lsdb_lookup_next(uint16_t type, uint32_t id,
196 uint32_t adv_router,
d62a17ae 197 struct ospf6_lsdb *lsdb)
2680aa2b 198{
d62a17ae 199 struct route_node *node;
200 struct prefix_ipv6 key;
2680aa2b 201
d62a17ae 202 if (lsdb == NULL)
203 return NULL;
2680aa2b 204
d62a17ae 205 memset(&key, 0, sizeof(key));
206 ospf6_lsdb_set_key(&key, &type, sizeof(type));
207 ospf6_lsdb_set_key(&key, &adv_router, sizeof(adv_router));
208 ospf6_lsdb_set_key(&key, &id, sizeof(id));
2680aa2b 209
d62a17ae 210 {
211 char buf[PREFIX2STR_BUFFER];
212 prefix2str(&key, buf, sizeof(buf));
213 zlog_debug("lsdb_lookup_next: key: %s", buf);
214 }
2680aa2b 215
d62a17ae 216 node = route_table_get_next(lsdb->table, &key);
2680aa2b 217
d62a17ae 218 /* skip to real existing entry */
219 while (node && node->info == NULL)
220 node = route_next(node);
2680aa2b 221
d62a17ae 222 if (!node)
223 return NULL;
2680aa2b 224
d62a17ae 225 route_unlock_node(node);
226 if (!node->info)
227 return NULL;
2680aa2b 228
d62a17ae 229 return (struct ospf6_lsa *)node->info;
2680aa2b 230}
231
d62a17ae 232const struct route_node *ospf6_lsdb_head(struct ospf6_lsdb *lsdb, int argmode,
233 uint16_t type, uint32_t adv_router,
234 struct ospf6_lsa **lsa)
718e3744 235{
d62a17ae 236 struct route_node *node, *end;
237
238 *lsa = NULL;
239
240 if (argmode > 0) {
241 struct prefix_ipv6 key = {.family = AF_INET6, .prefixlen = 0};
242
243 ospf6_lsdb_set_key(&key, &type, sizeof(type));
244 if (argmode > 1)
245 ospf6_lsdb_set_key(&key, &adv_router,
246 sizeof(adv_router));
247
248 node = route_table_get_next(lsdb->table, &key);
249 if (!node || !prefix_match((struct prefix *)&key, &node->p))
250 return NULL;
251
252 for (end = node; end && end->parent
253 && end->parent->p.prefixlen >= key.prefixlen;
254 end = end->parent)
255 ;
256 } else {
257 node = route_top(lsdb->table);
258 end = NULL;
259 }
260
261 while (node && !node->info)
262 node = route_next_until(node, end);
263
264 if (!node)
265 return NULL;
266 if (!node->info) {
267 route_unlock_node(node);
268 return NULL;
269 }
270
271 *lsa = node->info;
272 ospf6_lsa_lock(*lsa);
273
274 return end;
718e3744 275}
276
d62a17ae 277struct ospf6_lsa *ospf6_lsdb_next(const struct route_node *iterend,
278 struct ospf6_lsa *lsa)
718e3744 279{
d62a17ae 280 struct route_node *node = lsa->rn;
718e3744 281
d62a17ae 282 ospf6_lsa_unlock(lsa);
718e3744 283
d62a17ae 284 do
285 node = route_next_until(node, iterend);
286 while (node && !node->info);
718e3744 287
d62a17ae 288 if (node && node->info) {
289 struct ospf6_lsa *next = node->info;
290 ospf6_lsa_lock(next);
291 return next;
292 }
718e3744 293
d62a17ae 294 if (node)
295 route_unlock_node(node);
296 return NULL;
718e3744 297}
298
d62a17ae 299void ospf6_lsdb_remove_all(struct ospf6_lsdb *lsdb)
718e3744 300{
d62a17ae 301 struct ospf6_lsa *lsa;
a765eb93 302
d62a17ae 303 if (lsdb == NULL)
304 return;
a765eb93 305
d62a17ae 306 for (ALL_LSDB(lsdb, lsa))
307 ospf6_lsdb_remove(lsa, lsdb);
718e3744 308}
309
d62a17ae 310void ospf6_lsdb_lsa_unlock(struct ospf6_lsa *lsa)
a765eb93 311{
d62a17ae 312 if (lsa != NULL) {
313 if (lsa->rn != NULL)
314 route_unlock_node(lsa->rn);
315 ospf6_lsa_unlock(lsa);
316 }
a765eb93
DD
317}
318
d62a17ae 319int ospf6_lsdb_maxage_remover(struct ospf6_lsdb *lsdb)
2449fcd6 320{
d62a17ae 321 int reschedule = 0;
322 struct ospf6_lsa *lsa;
323
324 for (ALL_LSDB(lsdb, lsa)) {
325 if (!OSPF6_LSA_IS_MAXAGE(lsa))
326 continue;
327 if (lsa->retrans_count != 0) {
328 reschedule = 1;
329 continue;
330 }
331 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type))
332 zlog_debug("Remove MaxAge %s", lsa->name);
76249532 333
d62a17ae 334 if (CHECK_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED)) {
335 UNSET_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED);
336 /*
337 * lsa->header->age = 0;
338 */
339 lsa->header->seqnum =
340 htonl(OSPF_MAX_SEQUENCE_NUMBER + 1);
341 ospf6_lsa_checksum(lsa->header);
342
343 THREAD_OFF(lsa->refresh);
344 thread_execute(master, ospf6_lsa_refresh, lsa, 0);
345 } else {
346 ospf6_lsdb_remove(lsa, lsdb);
347 }
2449fcd6 348 }
d62a17ae 349
350 return (reschedule);
2449fcd6
DD
351}
352
d62a17ae 353void ospf6_lsdb_show(struct vty *vty, enum ospf_lsdb_show_level level,
d7c0a89a 354 uint16_t *type, uint32_t *id, uint32_t *adv_router,
d62a17ae 355 struct ospf6_lsdb *lsdb)
049207c3 356{
d62a17ae 357 struct ospf6_lsa *lsa;
358 const struct route_node *end = NULL;
359 void (*showfunc)(struct vty *, struct ospf6_lsa *) = NULL;
360
361 switch (level) {
362 case OSPF6_LSDB_SHOW_LEVEL_DETAIL:
363 showfunc = ospf6_lsa_show;
364 break;
365 case OSPF6_LSDB_SHOW_LEVEL_INTERNAL:
366 showfunc = ospf6_lsa_show_internal;
367 break;
368 case OSPF6_LSDB_SHOW_LEVEL_DUMP:
369 showfunc = ospf6_lsa_show_dump;
370 break;
371 case OSPF6_LSDB_SHOW_LEVEL_NORMAL:
372 default:
373 showfunc = ospf6_lsa_show_summary;
374 }
375
376 if (type && id && adv_router) {
377 lsa = ospf6_lsdb_lookup(*type, *id, *adv_router, lsdb);
378 if (lsa) {
379 if (level == OSPF6_LSDB_SHOW_LEVEL_NORMAL)
380 ospf6_lsa_show(vty, lsa);
381 else
382 (*showfunc)(vty, lsa);
383 }
384 return;
385 }
386
387 if (level == OSPF6_LSDB_SHOW_LEVEL_NORMAL)
388 ospf6_lsa_show_summary_header(vty);
389
62d86b87 390 end = ospf6_lsdb_head(lsdb, !!type + !!(type && adv_router),
996c9314 391 type ? *type : 0, adv_router ? *adv_router : 0,
62d86b87 392 &lsa);
d62a17ae 393 while (lsa) {
394 if ((!adv_router || lsa->header->adv_router == *adv_router)
395 && (!id || lsa->header->id == *id))
396 (*showfunc)(vty, lsa);
397
398 lsa = ospf6_lsdb_next(end, lsa);
399 }
049207c3 400}
401
d7c0a89a
QY
402uint32_t ospf6_new_ls_id(uint16_t type, uint32_t adv_router,
403 struct ospf6_lsdb *lsdb)
049207c3 404{
d62a17ae 405 struct ospf6_lsa *lsa;
d7c0a89a 406 uint32_t id = 1, tmp_id;
d62a17ae 407
408 /* This routine is curently invoked only for Inter-Prefix LSAs for
409 * non-summarized routes (no area/range).
410 */
411 for (ALL_LSDB_TYPED_ADVRTR(lsdb, type, adv_router, lsa)) {
412 tmp_id = ntohl(lsa->header->id);
413 if (tmp_id < id)
414 continue;
415
416 if (tmp_id > id) {
417 ospf6_lsdb_lsa_unlock(lsa);
418 break;
419 }
420 id++;
421 }
422
d7c0a89a 423 return ((uint32_t)htonl(id));
049207c3 424}
425
426/* Decide new LS sequence number to originate.
427 note return value is network byte order */
d7c0a89a
QY
428uint32_t ospf6_new_ls_seqnum(uint16_t type, uint32_t id, uint32_t adv_router,
429 struct ospf6_lsdb *lsdb)
049207c3 430{
d62a17ae 431 struct ospf6_lsa *lsa;
432 signed long seqnum = 0;
049207c3 433
d62a17ae 434 /* if current database copy not found, return InitialSequenceNumber */
435 lsa = ospf6_lsdb_lookup(type, id, adv_router, lsdb);
436 if (lsa == NULL)
437 seqnum = OSPF_INITIAL_SEQUENCE_NUMBER;
438 else
439 seqnum = (signed long)ntohl(lsa->header->seqnum) + 1;
049207c3 440
d7c0a89a 441 return ((uint32_t)htonl(seqnum));
049207c3 442}