]> git.proxmox.com Git - mirror_frr.git/blame - ospf6d/ospf6_lsdb.c
pimd: Add missing yang callbacks for route-maps
[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{
0f9f74ba
DS
301 struct ospf6_lsa *lsa, *lsa_next;
302 const struct route_node *iterend;
a765eb93 303
d62a17ae 304 if (lsdb == NULL)
305 return;
a765eb93 306
0f9f74ba
DS
307 for (iterend = ospf6_lsdb_head(lsdb, 0, 0, 0, &lsa); lsa;
308 lsa = lsa_next) {
309 lsa_next = ospf6_lsdb_next(iterend, lsa);
d62a17ae 310 ospf6_lsdb_remove(lsa, lsdb);
0f9f74ba 311 }
718e3744 312}
313
d62a17ae 314void ospf6_lsdb_lsa_unlock(struct ospf6_lsa *lsa)
a765eb93 315{
d62a17ae 316 if (lsa != NULL) {
317 if (lsa->rn != NULL)
318 route_unlock_node(lsa->rn);
319 ospf6_lsa_unlock(lsa);
320 }
a765eb93
DD
321}
322
d62a17ae 323int ospf6_lsdb_maxage_remover(struct ospf6_lsdb *lsdb)
2449fcd6 324{
d62a17ae 325 int reschedule = 0;
0f9f74ba
DS
326 struct ospf6_lsa *lsa, *lsa_next;
327 const struct route_node *iterend;
d62a17ae 328
0f9f74ba
DS
329 for (iterend = ospf6_lsdb_head(lsdb, 0, 0, 0, &lsa); lsa;
330 lsa = lsa_next) {
331 lsa_next = ospf6_lsdb_next(iterend, lsa);
d62a17ae 332 if (!OSPF6_LSA_IS_MAXAGE(lsa))
333 continue;
334 if (lsa->retrans_count != 0) {
335 reschedule = 1;
336 continue;
337 }
338 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type))
339 zlog_debug("Remove MaxAge %s", lsa->name);
76249532 340
d62a17ae 341 if (CHECK_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED)) {
342 UNSET_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED);
343 /*
344 * lsa->header->age = 0;
345 */
346 lsa->header->seqnum =
347 htonl(OSPF_MAX_SEQUENCE_NUMBER + 1);
348 ospf6_lsa_checksum(lsa->header);
349
350 THREAD_OFF(lsa->refresh);
351 thread_execute(master, ospf6_lsa_refresh, lsa, 0);
352 } else {
353 ospf6_lsdb_remove(lsa, lsdb);
354 }
2449fcd6 355 }
d62a17ae 356
357 return (reschedule);
2449fcd6
DD
358}
359
d62a17ae 360void ospf6_lsdb_show(struct vty *vty, enum ospf_lsdb_show_level level,
d7c0a89a 361 uint16_t *type, uint32_t *id, uint32_t *adv_router,
d62a17ae 362 struct ospf6_lsdb *lsdb)
049207c3 363{
d62a17ae 364 struct ospf6_lsa *lsa;
365 const struct route_node *end = NULL;
366 void (*showfunc)(struct vty *, struct ospf6_lsa *) = NULL;
367
368 switch (level) {
369 case OSPF6_LSDB_SHOW_LEVEL_DETAIL:
370 showfunc = ospf6_lsa_show;
371 break;
372 case OSPF6_LSDB_SHOW_LEVEL_INTERNAL:
373 showfunc = ospf6_lsa_show_internal;
374 break;
375 case OSPF6_LSDB_SHOW_LEVEL_DUMP:
376 showfunc = ospf6_lsa_show_dump;
377 break;
378 case OSPF6_LSDB_SHOW_LEVEL_NORMAL:
379 default:
380 showfunc = ospf6_lsa_show_summary;
381 }
382
383 if (type && id && adv_router) {
384 lsa = ospf6_lsdb_lookup(*type, *id, *adv_router, lsdb);
385 if (lsa) {
386 if (level == OSPF6_LSDB_SHOW_LEVEL_NORMAL)
387 ospf6_lsa_show(vty, lsa);
388 else
389 (*showfunc)(vty, lsa);
390 }
391 return;
392 }
393
394 if (level == OSPF6_LSDB_SHOW_LEVEL_NORMAL)
395 ospf6_lsa_show_summary_header(vty);
396
62d86b87 397 end = ospf6_lsdb_head(lsdb, !!type + !!(type && adv_router),
996c9314 398 type ? *type : 0, adv_router ? *adv_router : 0,
62d86b87 399 &lsa);
d62a17ae 400 while (lsa) {
401 if ((!adv_router || lsa->header->adv_router == *adv_router)
402 && (!id || lsa->header->id == *id))
403 (*showfunc)(vty, lsa);
404
405 lsa = ospf6_lsdb_next(end, lsa);
406 }
049207c3 407}
408
d7c0a89a
QY
409uint32_t ospf6_new_ls_id(uint16_t type, uint32_t adv_router,
410 struct ospf6_lsdb *lsdb)
049207c3 411{
d62a17ae 412 struct ospf6_lsa *lsa;
d7c0a89a 413 uint32_t id = 1, tmp_id;
d62a17ae 414
415 /* This routine is curently invoked only for Inter-Prefix LSAs for
416 * non-summarized routes (no area/range).
417 */
418 for (ALL_LSDB_TYPED_ADVRTR(lsdb, type, adv_router, lsa)) {
419 tmp_id = ntohl(lsa->header->id);
420 if (tmp_id < id)
421 continue;
422
423 if (tmp_id > id) {
424 ospf6_lsdb_lsa_unlock(lsa);
425 break;
426 }
427 id++;
428 }
429
d7c0a89a 430 return ((uint32_t)htonl(id));
049207c3 431}
432
433/* Decide new LS sequence number to originate.
434 note return value is network byte order */
d7c0a89a
QY
435uint32_t ospf6_new_ls_seqnum(uint16_t type, uint32_t id, uint32_t adv_router,
436 struct ospf6_lsdb *lsdb)
049207c3 437{
d62a17ae 438 struct ospf6_lsa *lsa;
439 signed long seqnum = 0;
049207c3 440
d62a17ae 441 /* if current database copy not found, return InitialSequenceNumber */
442 lsa = ospf6_lsdb_lookup(type, id, adv_router, lsdb);
443 if (lsa == NULL)
444 seqnum = OSPF_INITIAL_SEQUENCE_NUMBER;
445 else
446 seqnum = (signed long)ntohl(lsa->header->seqnum) + 1;
049207c3 447
d7c0a89a 448 return ((uint32_t)htonl(seqnum));
049207c3 449}