]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_rib.c
zebra: return route_node from rib_match_ipv4_safi
[mirror_frr.git] / zebra / zebra_rib.c
CommitLineData
718e3744 1/* Routing Information Base.
2 * Copyright (C) 1997, 98, 99, 2001 Kunihiro Ishiguro
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 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "prefix.h"
25#include "table.h"
26#include "memory.h"
27#include "str.h"
28#include "command.h"
29#include "if.h"
30#include "log.h"
31#include "sockunion.h"
4d38fdb4 32#include "linklist.h"
33#include "thread.h"
34#include "workqueue.h"
7514fb77
PJ
35#include "prefix.h"
36#include "routemap.h"
fb018d25 37#include "nexthop.h"
b72ede27 38#include "vrf.h"
718e3744 39
40#include "zebra/rib.h"
41#include "zebra/rt.h"
7c551956 42#include "zebra/zebra_ns.h"
718e3744 43#include "zebra/zserv.h"
7c551956 44#include "zebra/zebra_vrf.h"
718e3744 45#include "zebra/redistribute.h"
8902474b 46#include "zebra/zebra_routemap.h"
718e3744 47#include "zebra/debug.h"
5adc2528 48#include "zebra/zebra_fpm.h"
fb018d25 49#include "zebra/zebra_rnh.h"
88177fe3 50#include "zebra/interface.h"
d44ca835 51#include "zebra/connected.h"
718e3744 52
6baf7bb8
DS
53/* Should we allow non Quagga processes to delete our routes */
54extern int allow_delete;
55
457eb9af
PJ
56/* Hold time for RIB process, should be very minimal.
57 * it is useful to able to set it otherwise for testing, hence exported
58 * as global here for test-rig code.
59 */
60int rib_process_hold_time = 10;
61
718e3744 62/* Each route type's string and default distance value. */
d145bc00 63static const struct
718e3744 64{
65 int key;
66 int distance;
5734509c 67} route_info[ZEBRA_ROUTE_MAX] =
718e3744 68{
5734509c
PJ
69 [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0},
70 [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0},
71 [ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0},
72 [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1},
73 [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120},
74 [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120},
75 [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110},
76 [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110},
77 [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115},
78 [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */},
7052f228 79 /* no entry/default: 150 */
718e3744 80};
6b0655a2 81
2263a412
DL
82static void
83_rnode_zlog(const char *_func, vrf_id_t vrf_id, struct route_node *rn, int priority,
84 const char *msgfmt, ...)
85{
86 char buf[INET6_ADDRSTRLEN + 4], *bptr;
87 char msgbuf[512];
88 va_list ap;
89
90 va_start(ap, msgfmt);
91 vsnprintf(msgbuf, sizeof(msgbuf), msgfmt, ap);
92 va_end(ap);
93
94 if (rn)
95 {
cb653491
DL
96 rib_table_info_t *info = rn->table->info;
97
2263a412
DL
98 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
99 bptr = buf + strlen(buf);
cb653491
DL
100 snprintf(bptr, buf + sizeof(buf) - bptr, "/%d%s", rn->p.prefixlen,
101 info->safi == SAFI_MULTICAST ? " (MRIB)" : "");
2263a412
DL
102 }
103 else
104 {
105 snprintf(buf, sizeof(buf), "{(route_node *) NULL}");
106 }
107
108 zlog (NULL, priority, "%s: %d:%s: %s", _func, vrf_id, buf, msgbuf);
109}
110
111#define rnode_debug(node, vrf_id, ...) \
112 _rnode_zlog(__func__, vrf_id, node, LOG_DEBUG, __VA_ARGS__)
113#define rnode_info(node, ...) \
114 _rnode_zlog(__func__, vrf_id, node, LOG_INFO, __VA_ARGS__)
115
7a4bb9c5
DS
116int
117is_zebra_valid_kernel_table(u_int32_t table_id)
118{
119 if ((table_id > ZEBRA_KERNEL_TABLE_MAX) ||
120 (table_id == RT_TABLE_UNSPEC) ||
121 (table_id == RT_TABLE_LOCAL) ||
122 (table_id == RT_TABLE_COMPAT))
123 return 0;
124 else
125 return 1;
126}
127
128int
129is_zebra_main_routing_table(u_int32_t table_id)
130{
131 if ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default))
132 return 1;
133 return 0;
134}
135
0aabccc0
DD
136int
137zebra_check_addr (struct prefix *p)
138{
139 if (p->family == AF_INET)
140 {
141 u_int32_t addr;
142
143 addr = p->u.prefix4.s_addr;
144 addr = ntohl (addr);
145
146 if (IPV4_NET127 (addr)
147 || IN_CLASSD (addr)
148 || IPV4_LINKLOCAL(addr))
149 return 0;
150 }
0aabccc0
DD
151 if (p->family == AF_INET6)
152 {
153 if (IN6_IS_ADDR_LOOPBACK (&p->u.prefix6))
154 return 0;
155 if (IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6))
156 return 0;
157 }
0aabccc0
DD
158 return 1;
159}
160
fa713d9e 161/* Add nexthop to the end of a rib node's nexthop list */
fb018d25 162void
a399694f 163rib_nexthop_add (struct rib *rib, struct nexthop *nexthop)
fa713d9e 164{
a399694f 165 nexthop_add(&rib->nexthop, nexthop);
718e3744 166 rib->nexthop_num++;
167}
168
6e26278c 169
6e26278c
DS
170
171/**
172 * copy_nexthop - copy a nexthop to the rib structure.
173 */
174void
a399694f 175rib_copy_nexthops (struct rib *rib, struct nexthop *nh)
6e26278c
DS
176{
177 struct nexthop *nexthop;
178
179 nexthop = nexthop_new();
180 nexthop->flags = nh->flags;
181 nexthop->type = nh->type;
182 nexthop->ifindex = nh->ifindex;
6e26278c
DS
183 memcpy(&(nexthop->gate), &(nh->gate), sizeof(union g_addr));
184 memcpy(&(nexthop->src), &(nh->src), sizeof(union g_addr));
a399694f 185 rib_nexthop_add(rib, nexthop);
6e26278c 186 if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_RECURSIVE))
a399694f 187 copy_nexthops(&nexthop->resolved, nh->resolved);
6e26278c
DS
188}
189
718e3744 190/* Delete specified nexthop from the list. */
a1ac18c4 191static void
a399694f 192rib_nexthop_delete (struct rib *rib, struct nexthop *nexthop)
718e3744 193{
194 if (nexthop->next)
195 nexthop->next->prev = nexthop->prev;
196 if (nexthop->prev)
197 nexthop->prev->next = nexthop->next;
198 else
199 rib->nexthop = nexthop->next;
200 rib->nexthop_num--;
201}
202
fa713d9e 203
fa713d9e 204
718e3744 205struct nexthop *
a399694f 206rib_nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
718e3744 207{
208 struct nexthop *nexthop;
209
a399694f 210 nexthop = nexthop_new();
718e3744 211 nexthop->type = NEXTHOP_TYPE_IFINDEX;
212 nexthop->ifindex = ifindex;
213
a399694f 214 rib_nexthop_add (rib, nexthop);
718e3744 215
216 return nexthop;
217}
218
718e3744 219struct nexthop *
a399694f 220rib_nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src)
718e3744 221{
222 struct nexthop *nexthop;
223
a399694f 224 nexthop = nexthop_new();
718e3744 225 nexthop->type = NEXTHOP_TYPE_IPV4;
226 nexthop->gate.ipv4 = *ipv4;
7514fb77
PJ
227 if (src)
228 nexthop->src.ipv4 = *src;
718e3744 229
a399694f 230 rib_nexthop_add (rib, nexthop);
718e3744 231
232 return nexthop;
233}
234
26e2ae36 235struct nexthop *
a399694f
DS
236rib_nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
237 struct in_addr *src, unsigned int ifindex)
718e3744 238{
239 struct nexthop *nexthop;
d44ca835 240 struct interface *ifp;
718e3744 241
a399694f 242 nexthop = nexthop_new();
718e3744 243 nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
244 nexthop->gate.ipv4 = *ipv4;
7514fb77
PJ
245 if (src)
246 nexthop->src.ipv4 = *src;
718e3744 247 nexthop->ifindex = ifindex;
d44ca835 248 ifp = if_lookup_by_index (nexthop->ifindex);
12f6fb97
DS
249 /*Pending: need to think if null ifp here is ok during bootup?
250 There was a crash because ifp here was coming to be NULL */
251 if (ifp)
d44ca835
DS
252 if (connected_is_unnumbered(ifp)) {
253 SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK);
254 }
718e3744 255
a399694f 256 rib_nexthop_add (rib, nexthop);
718e3744 257
258 return nexthop;
259}
260
718e3744 261struct nexthop *
a399694f 262rib_nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
718e3744 263{
264 struct nexthop *nexthop;
265
a399694f 266 nexthop = nexthop_new();
718e3744 267 nexthop->type = NEXTHOP_TYPE_IPV6;
268 nexthop->gate.ipv6 = *ipv6;
269
a399694f 270 rib_nexthop_add (rib, nexthop);
718e3744 271
272 return nexthop;
273}
274
41fc2714 275struct nexthop *
a399694f
DS
276rib_nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
277 unsigned int ifindex)
718e3744 278{
279 struct nexthop *nexthop;
280
393deb9b 281 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
718e3744 282 nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
283 nexthop->gate.ipv6 = *ipv6;
284 nexthop->ifindex = ifindex;
285
a399694f 286 rib_nexthop_add (rib, nexthop);
718e3744 287
288 return nexthop;
289}
718e3744 290
595db7f1 291struct nexthop *
a399694f 292rib_nexthop_blackhole_add (struct rib *rib)
595db7f1 293{
294 struct nexthop *nexthop;
295
a399694f 296 nexthop = nexthop_new();
595db7f1 297 nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
298 SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
299
a399694f 300 rib_nexthop_add (rib, nexthop);
595db7f1 301
302 return nexthop;
303}
304
fa713d9e
CF
305/* This method checks whether a recursive nexthop has at
306 * least one resolved nexthop in the fib.
307 */
308int
309nexthop_has_fib_child(struct nexthop *nexthop)
310{
311 struct nexthop *nh;
312
313 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
314 return 0;
315
316 for (nh = nexthop->resolved; nh; nh = nh->next)
317 if (CHECK_FLAG (nh->flags, NEXTHOP_FLAG_FIB))
318 return 1;
319
320 return 0;
321}
322
718e3744 323/* If force flag is not set, do not modify falgs at all for uninstall
324 the route from FIB. */
a1ac18c4 325static int
718e3744 326nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
327 struct route_node *top)
328{
329 struct prefix_ipv4 p;
330 struct route_table *table;
331 struct route_node *rn;
332 struct rib *match;
fa713d9e 333 int resolved;
6e26278c 334 struct nexthop *newhop, *tnewhop;
fa713d9e 335 struct nexthop *resolved_hop;
6e26278c 336 int recursing = 0;
c8a1cb5c 337 struct interface *ifp;
718e3744 338
339 if (nexthop->type == NEXTHOP_TYPE_IPV4)
340 nexthop->ifindex = 0;
341
342 if (set)
fa713d9e
CF
343 {
344 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
d82ae0de 345 zebra_deregister_rnh_static_nexthops(rib->vrf_id, nexthop->resolved, top);
a399694f 346 nexthops_free(nexthop->resolved);
fa713d9e
CF
347 nexthop->resolved = NULL;
348 }
718e3744 349
6e26278c
DS
350 /* Skip nexthops that have been filtered out due to route-map */
351 /* The nexthops are specific to this route and so the same */
352 /* nexthop for a different route may not have this flag set */
353 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FILTERED))
354 return 0;
355
d44ca835
DS
356 /*
357 * Check to see if we should trust the passed in information
358 * for UNNUMBERED interfaces as that we won't find the GW
359 * address in the routing table.
c8a1cb5c
DS
360 */
361 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
362 {
363 ifp = if_lookup_by_index (nexthop->ifindex);
d44ca835
DS
364 if (ifp && connected_is_unnumbered(ifp))
365 {
366 if (if_is_operative(ifp))
367 return 1;
368 else
369 return 0;
370 }
c8a1cb5c
DS
371 else
372 return 0;
373 }
374
718e3744 375 /* Make lookup prefix. */
376 memset (&p, 0, sizeof (struct prefix_ipv4));
377 p.family = AF_INET;
378 p.prefixlen = IPV4_MAX_PREFIXLEN;
379 p.prefix = nexthop->gate.ipv4;
380
381 /* Lookup table. */
78104b9b 382 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, rib->vrf_id);
718e3744 383 if (! table)
384 return 0;
385
386 rn = route_node_match (table, (struct prefix *) &p);
387 while (rn)
388 {
389 route_unlock_node (rn);
390
a50c107e 391 /* If lookup self prefix return immediately. */
718e3744 392 if (rn == top)
393 return 0;
394
395 /* Pick up selected route. */
18ff3edd
DS
396 /* However, do not resolve over default route unless explicitly allowed. */
397 if (is_default_prefix (&rn->p) &&
398 !nh_resolve_via_default (p.family))
399 return 0;
400
9fd92e3c 401 RNODE_FOREACH_RIB (rn, match)
16814f96
SH
402 {
403 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
404 continue;
405 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
406 break;
407 }
718e3744 408
409 /* If there is no selected route or matched route is EGP, go up
410 tree. */
6e26278c 411 if (! match)
718e3744 412 {
413 do {
414 rn = rn->parent;
415 } while (rn && rn->info == NULL);
416 if (rn)
417 route_lock_node (rn);
418 }
419 else
420 {
48a53dc7
CF
421 /* If the longest prefix match for the nexthop yields
422 * a blackhole, mark it as inactive. */
423 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE)
424 || CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT))
425 return 0;
426
718e3744 427 if (match->type == ZEBRA_ROUTE_CONNECT)
428 {
429 /* Directly point connected route. */
430 newhop = match->nexthop;
431 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
432 nexthop->ifindex = newhop->ifindex;
433
434 return 1;
435 }
436 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
437 {
fa713d9e 438 resolved = 0;
718e3744 439 for (newhop = match->nexthop; newhop; newhop = newhop->next)
440 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
441 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
442 {
443 if (set)
444 {
445 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
6e26278c 446 SET_FLAG(rib->status, RIB_ENTRY_NEXTHOPS_CHANGED);
fa713d9e
CF
447
448 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
449 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
c3e6b595
CF
450 /* If the resolving route specifies a gateway, use it */
451 if (newhop->type == NEXTHOP_TYPE_IPV4
3ee39b5b 452 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
c3e6b595
CF
453 {
454 resolved_hop->type = newhop->type;
455 resolved_hop->gate.ipv4 = newhop->gate.ipv4;
456
457 if (newhop->ifindex)
458 {
459 resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
460 resolved_hop->ifindex = newhop->ifindex;
f44f6668
DS
461 if (newhop->flags & NEXTHOP_FLAG_ONLINK)
462 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
c3e6b595
CF
463 }
464 }
465
466 /* If the resolving route is an interface route,
467 * it means the gateway we are looking up is connected
468 * to that interface. (The actual network is _not_ onlink).
469 * Therefore, the resolved route should have the original
470 * gateway as nexthop as it is directly connected.
471 *
472 * On Linux, we have to set the onlink netlink flag because
473 * otherwise, the kernel won't accept the route. */
3ee39b5b 474 if (newhop->type == NEXTHOP_TYPE_IFINDEX)
c3e6b595
CF
475 {
476 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
477 resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
478 resolved_hop->gate.ipv4 = nexthop->gate.ipv4;
479 resolved_hop->ifindex = newhop->ifindex;
480 }
fa713d9e 481
a399694f 482 nexthop_add(&nexthop->resolved, resolved_hop);
6e26278c
DS
483 }
484 resolved = 1;
485 }
486 return resolved;
487 }
488 else if (rib->type == ZEBRA_ROUTE_STATIC)
489 {
490 resolved = 0;
491 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
492 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
493 {
494 if (set)
495 {
496 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
497
498 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
499 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
500 /* If the resolving route specifies a gateway, use it */
501 if (newhop->type == NEXTHOP_TYPE_IPV4
3ee39b5b 502 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
6e26278c
DS
503 {
504 resolved_hop->type = newhop->type;
505 resolved_hop->gate.ipv4 = newhop->gate.ipv4;
506
507 if (newhop->ifindex)
508 {
509 resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
510 resolved_hop->ifindex = newhop->ifindex;
f44f6668
DS
511 if (newhop->flags & NEXTHOP_FLAG_ONLINK)
512 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
6e26278c
DS
513 }
514 }
515
516 /* If the resolving route is an interface route,
517 * it means the gateway we are looking up is connected
518 * to that interface. (The actual network is _not_ onlink).
519 * Therefore, the resolved route should have the original
520 * gateway as nexthop as it is directly connected.
521 *
522 * On Linux, we have to set the onlink netlink flag because
523 * otherwise, the kernel won't accept the route.
524 */
3ee39b5b 525 if (newhop->type == NEXTHOP_TYPE_IFINDEX)
6e26278c
DS
526 {
527 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
528 resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
529 resolved_hop->gate.ipv4 = nexthop->gate.ipv4;
530 resolved_hop->ifindex = newhop->ifindex;
531 }
532
a399694f 533 nexthop_add(&nexthop->resolved, resolved_hop);
718e3744 534 }
fa713d9e 535 resolved = 1;
718e3744 536 }
fa713d9e 537 return resolved;
718e3744 538 }
539 else
540 {
541 return 0;
542 }
543 }
544 }
545 return 0;
546}
547
718e3744 548/* If force flag is not set, do not modify falgs at all for uninstall
549 the route from FIB. */
a1ac18c4 550static int
718e3744 551nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
552 struct route_node *top)
553{
554 struct prefix_ipv6 p;
555 struct route_table *table;
556 struct route_node *rn;
557 struct rib *match;
fa713d9e 558 int resolved;
6e26278c
DS
559 struct nexthop *newhop, *tnewhop;
560 int recursing = 0;
fa713d9e 561 struct nexthop *resolved_hop;
718e3744 562
563 if (nexthop->type == NEXTHOP_TYPE_IPV6)
564 nexthop->ifindex = 0;
565
566 if (set)
fa713d9e
CF
567 {
568 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
d82ae0de 569 zebra_deregister_rnh_static_nexthops (rib->vrf_id, nexthop->resolved, top);
a399694f 570 nexthops_free(nexthop->resolved);
fa713d9e
CF
571 nexthop->resolved = NULL;
572 }
718e3744 573
6e26278c
DS
574 /* Skip nexthops that have been filtered out due to route-map */
575 /* The nexthops are specific to this route and so the same */
576 /* nexthop for a different route may not have this flag set */
577 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FILTERED))
578 return 0;
579
718e3744 580 /* Make lookup prefix. */
581 memset (&p, 0, sizeof (struct prefix_ipv6));
582 p.family = AF_INET6;
583 p.prefixlen = IPV6_MAX_PREFIXLEN;
584 p.prefix = nexthop->gate.ipv6;
585
586 /* Lookup table. */
78104b9b 587 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, rib->vrf_id);
718e3744 588 if (! table)
589 return 0;
590
591 rn = route_node_match (table, (struct prefix *) &p);
592 while (rn)
593 {
594 route_unlock_node (rn);
595
a50c107e 596 /* If lookup self prefix return immediately. */
718e3744 597 if (rn == top)
598 return 0;
599
600 /* Pick up selected route. */
18ff3edd
DS
601 /* However, do not resolve over default route unless explicitly allowed. */
602 if (is_default_prefix (&rn->p) &&
603 !nh_resolve_via_default (p.family))
604 return 0;
605
9fd92e3c 606 RNODE_FOREACH_RIB (rn, match)
16814f96
SH
607 {
608 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
609 continue;
610 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
611 break;
612 }
718e3744 613
614 /* If there is no selected route or matched route is EGP, go up
615 tree. */
6e26278c 616 if (! match)
718e3744 617 {
618 do {
619 rn = rn->parent;
620 } while (rn && rn->info == NULL);
621 if (rn)
622 route_lock_node (rn);
623 }
624 else
625 {
48a53dc7
CF
626 /* If the longest prefix match for the nexthop yields
627 * a blackhole, mark it as inactive. */
628 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE)
629 || CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT))
630 return 0;
631
718e3744 632 if (match->type == ZEBRA_ROUTE_CONNECT)
633 {
634 /* Directly point connected route. */
635 newhop = match->nexthop;
636
637 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
638 nexthop->ifindex = newhop->ifindex;
639
640 return 1;
641 }
642 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
643 {
fa713d9e 644 resolved = 0;
718e3744 645 for (newhop = match->nexthop; newhop; newhop = newhop->next)
646 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
647 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
6e26278c
DS
648 {
649 if (set)
650 {
651 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
652 SET_FLAG(rib->status, RIB_ENTRY_NEXTHOPS_CHANGED);
653
654 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
655 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
656 /* See nexthop_active_ipv4 for a description how the
657 * resolved nexthop is constructed. */
658 if (newhop->type == NEXTHOP_TYPE_IPV6
3ee39b5b 659 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
6e26278c
DS
660 {
661 resolved_hop->type = newhop->type;
662 resolved_hop->gate.ipv6 = newhop->gate.ipv6;
663
664 if (newhop->ifindex)
665 {
666 resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
667 resolved_hop->ifindex = newhop->ifindex;
668 }
669 }
670
3ee39b5b 671 if (newhop->type == NEXTHOP_TYPE_IFINDEX)
6e26278c
DS
672 {
673 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
674 resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
675 resolved_hop->gate.ipv6 = nexthop->gate.ipv6;
676 resolved_hop->ifindex = newhop->ifindex;
677 }
678
a399694f 679 nexthop_add(&nexthop->resolved, resolved_hop);
6e26278c
DS
680 }
681 resolved = 1;
682 }
683 return resolved;
684 }
685 else if (rib->type == ZEBRA_ROUTE_STATIC)
686 {
687 resolved = 0;
688 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
689 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
718e3744 690 {
691 if (set)
692 {
693 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
fa713d9e
CF
694
695 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
696 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
c3e6b595
CF
697 /* See nexthop_active_ipv4 for a description how the
698 * resolved nexthop is constructed. */
718e3744 699 if (newhop->type == NEXTHOP_TYPE_IPV6
3ee39b5b 700 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
c3e6b595
CF
701 {
702 resolved_hop->type = newhop->type;
703 resolved_hop->gate.ipv6 = newhop->gate.ipv6;
704
705 if (newhop->ifindex)
706 {
707 resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
708 resolved_hop->ifindex = newhop->ifindex;
709 }
710 }
fa713d9e 711
3ee39b5b 712 if (newhop->type == NEXTHOP_TYPE_IFINDEX)
c3e6b595
CF
713 {
714 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
715 resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
716 resolved_hop->gate.ipv6 = nexthop->gate.ipv6;
717 resolved_hop->ifindex = newhop->ifindex;
718 }
fa713d9e 719
a399694f 720 nexthop_add(&nexthop->resolved, resolved_hop);
718e3744 721 }
fa713d9e 722 resolved = 1;
718e3744 723 }
fa713d9e 724 return resolved;
718e3744 725 }
726 else
727 {
728 return 0;
729 }
730 }
731 }
732 return 0;
733}
718e3744 734
735struct rib *
33550aa8
DL
736rib_match_ipv4 (struct in_addr addr, safi_t safi, vrf_id_t vrf_id,
737 struct route_node **rn_out)
718e3744 738{
739 struct prefix_ipv4 p;
740 struct route_table *table;
741 struct route_node *rn;
742 struct rib *match;
fa713d9e
CF
743 struct nexthop *newhop, *tnewhop;
744 int recursing;
718e3744 745
746 /* Lookup table. */
492dadb2 747 table = zebra_vrf_table (AFI_IP, safi, vrf_id);
718e3744 748 if (! table)
749 return 0;
750
751 memset (&p, 0, sizeof (struct prefix_ipv4));
752 p.family = AF_INET;
753 p.prefixlen = IPV4_MAX_PREFIXLEN;
754 p.prefix = addr;
755
756 rn = route_node_match (table, (struct prefix *) &p);
757
758 while (rn)
759 {
760 route_unlock_node (rn);
761
762 /* Pick up selected route. */
9fd92e3c 763 RNODE_FOREACH_RIB (rn, match)
16814f96
SH
764 {
765 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
766 continue;
767 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
768 break;
769 }
718e3744 770
771 /* If there is no selected route or matched route is EGP, go up
772 tree. */
6e26278c 773 if (! match)
718e3744 774 {
775 do {
776 rn = rn->parent;
777 } while (rn && rn->info == NULL);
778 if (rn)
779 route_lock_node (rn);
780 }
781 else
782 {
33550aa8 783 if (match->type != ZEBRA_ROUTE_CONNECT)
718e3744 784 {
33550aa8 785 int found = 0;
fa713d9e 786 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
718e3744 787 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
33550aa8
DL
788 {
789 found = 1;
790 break;
791 }
792 if (!found)
793 return NULL;
718e3744 794 }
33550aa8
DL
795
796 if (rn_out)
797 *rn_out = rn;
798 return match;
718e3744 799 }
800 }
801 return NULL;
802}
803
804struct rib *
78104b9b 805rib_lookup_ipv4 (struct prefix_ipv4 *p, vrf_id_t vrf_id)
718e3744 806{
807 struct route_table *table;
808 struct route_node *rn;
809 struct rib *match;
fa713d9e
CF
810 struct nexthop *nexthop, *tnexthop;
811 int recursing;
718e3744 812
813 /* Lookup table. */
78104b9b 814 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
718e3744 815 if (! table)
816 return 0;
817
818 rn = route_node_lookup (table, (struct prefix *) p);
819
820 /* No route for this prefix. */
821 if (! rn)
822 return NULL;
823
824 /* Unlock node. */
825 route_unlock_node (rn);
826
9fd92e3c 827 RNODE_FOREACH_RIB (rn, match)
16814f96
SH
828 {
829 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
830 continue;
831 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
832 break;
833 }
718e3744 834
6e26278c 835 if (! match)
718e3744 836 return NULL;
837
838 if (match->type == ZEBRA_ROUTE_CONNECT)
839 return match;
840
fa713d9e 841 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
718e3744 842 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
843 return match;
844
845 return NULL;
846}
847
dc95824a
DO
848/*
849 * This clone function, unlike its original rib_lookup_ipv4(), checks
850 * if specified IPv4 route record (prefix/mask -> gate) exists in
851 * the whole RIB and has ZEBRA_FLAG_SELECTED set.
852 *
853 * Return values:
854 * -1: error
855 * 0: exact match found
856 * 1: a match was found with a different gate
857 * 2: connected route found
858 * 3: no matches found
859 */
860int
78104b9b
FL
861rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate,
862 vrf_id_t vrf_id)
dc95824a
DO
863{
864 struct route_table *table;
865 struct route_node *rn;
866 struct rib *match;
fa713d9e
CF
867 struct nexthop *nexthop, *tnexthop;
868 int recursing;
869 int nexthops_active;
dc95824a
DO
870
871 /* Lookup table. */
78104b9b 872 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
dc95824a
DO
873 if (! table)
874 return ZEBRA_RIB_LOOKUP_ERROR;
875
876 /* Scan the RIB table for exactly matching RIB entry. */
877 rn = route_node_lookup (table, (struct prefix *) p);
878
879 /* No route for this prefix. */
880 if (! rn)
881 return ZEBRA_RIB_NOTFOUND;
882
883 /* Unlock node. */
884 route_unlock_node (rn);
885
886 /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
9fd92e3c 887 RNODE_FOREACH_RIB (rn, match)
16814f96
SH
888 {
889 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
890 continue;
891 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
892 break;
893 }
dc95824a
DO
894
895 /* None such found :( */
896 if (!match)
897 return ZEBRA_RIB_NOTFOUND;
898
899 if (match->type == ZEBRA_ROUTE_CONNECT)
900 return ZEBRA_RIB_FOUND_CONNECTED;
901
902 /* Ok, we have a cood candidate, let's check it's nexthop list... */
fa713d9e
CF
903 nexthops_active = 0;
904 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
dc95824a 905 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
dc95824a 906 {
fa713d9e
CF
907 nexthops_active = 1;
908 if (nexthop->gate.ipv4.s_addr == sockunion2ip (qgate))
909 return ZEBRA_RIB_FOUND_EXACT;
dc95824a 910 if (IS_ZEBRA_DEBUG_RIB)
fa713d9e
CF
911 {
912 char gate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
913 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
914 inet_ntop (AF_INET, &sockunion2ip(qgate), qgate_buf, INET_ADDRSTRLEN);
915 zlog_debug ("%s: qgate == %s, %s == %s", __func__,
916 qgate_buf, recursing ? "rgate" : "gate", gate_buf);
917 }
dc95824a 918 }
fa713d9e
CF
919
920 if (nexthops_active)
921 return ZEBRA_RIB_FOUND_NOGATE;
dc95824a
DO
922
923 return ZEBRA_RIB_NOTFOUND;
924}
925
718e3744 926struct rib *
78104b9b 927rib_match_ipv6 (struct in6_addr *addr, vrf_id_t vrf_id)
718e3744 928{
929 struct prefix_ipv6 p;
930 struct route_table *table;
931 struct route_node *rn;
932 struct rib *match;
fa713d9e
CF
933 struct nexthop *newhop, *tnewhop;
934 int recursing;
718e3744 935
936 /* Lookup table. */
78104b9b 937 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
718e3744 938 if (! table)
939 return 0;
940
941 memset (&p, 0, sizeof (struct prefix_ipv6));
942 p.family = AF_INET6;
943 p.prefixlen = IPV6_MAX_PREFIXLEN;
944 IPV6_ADDR_COPY (&p.prefix, addr);
945
946 rn = route_node_match (table, (struct prefix *) &p);
947
948 while (rn)
949 {
950 route_unlock_node (rn);
951
952 /* Pick up selected route. */
9fd92e3c 953 RNODE_FOREACH_RIB (rn, match)
16814f96
SH
954 {
955 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
956 continue;
957 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
958 break;
959 }
718e3744 960
961 /* If there is no selected route or matched route is EGP, go up
962 tree. */
6e26278c 963 if (! match)
718e3744 964 {
965 do {
966 rn = rn->parent;
967 } while (rn && rn->info == NULL);
968 if (rn)
969 route_lock_node (rn);
970 }
971 else
972 {
973 if (match->type == ZEBRA_ROUTE_CONNECT)
974 /* Directly point connected route. */
975 return match;
976 else
977 {
fa713d9e 978 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
718e3744 979 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
980 return match;
981 return NULL;
982 }
983 }
984 }
985 return NULL;
986}
718e3744 987
7514fb77
PJ
988#define RIB_SYSTEM_ROUTE(R) \
989 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
990
dc95824a
DO
991/* This function verifies reachability of one given nexthop, which can be
992 * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
993 * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
994 * nexthop->ifindex will be updated appropriately as well.
995 * An existing route map can turn (otherwise active) nexthop into inactive, but
996 * not vice versa.
997 *
998 * The return value is the final value of 'ACTIVE' flag.
999 */
1000
d02c56cd 1001static unsigned
718e3744 1002nexthop_active_check (struct route_node *rn, struct rib *rib,
1003 struct nexthop *nexthop, int set)
1004{
f3a1732e 1005 rib_table_info_t *info = rn->table->info;
718e3744 1006 struct interface *ifp;
7514fb77 1007 route_map_result_t ret = RMAP_MATCH;
7514fb77 1008 int family;
518f0eb1 1009 char buf[INET6_ADDRSTRLEN+1];
718e3744 1010
7a4bb9c5
DS
1011 if (rn->p.family == AF_INET)
1012 family = AFI_IP;
1013 else if (rn->p.family == AF_INET6)
1014 family = AFI_IP6;
1015 else
1016 family = 0;
718e3744 1017 switch (nexthop->type)
1018 {
1019 case NEXTHOP_TYPE_IFINDEX:
78104b9b 1020 ifp = if_lookup_by_index_vrf (nexthop->ifindex, rib->vrf_id);
3f087670 1021 if (ifp && if_is_operative(ifp))
718e3744 1022 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1023 else
1024 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1025 break;
718e3744 1026 case NEXTHOP_TYPE_IPV4:
1027 case NEXTHOP_TYPE_IPV4_IFINDEX:
7514fb77 1028 family = AFI_IP;
718e3744 1029 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
1030 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1031 else
1032 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1033 break;
718e3744 1034 case NEXTHOP_TYPE_IPV6:
7514fb77 1035 family = AFI_IP6;
718e3744 1036 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
1037 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1038 else
1039 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1040 break;
1041 case NEXTHOP_TYPE_IPV6_IFINDEX:
fb5d585c 1042 /* RFC 5549, v4 prefix with v6 NH */
1043 if (rn->p.family != AF_INET)
1044 family = AFI_IP6;
718e3744 1045 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
1046 {
78104b9b 1047 ifp = if_lookup_by_index_vrf (nexthop->ifindex, rib->vrf_id);
3f087670 1048 if (ifp && if_is_operative(ifp))
718e3744 1049 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1050 else
1051 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1052 }
1053 else
1054 {
1055 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
1056 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1057 else
1058 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1059 }
1060 break;
595db7f1 1061 case NEXTHOP_TYPE_BLACKHOLE:
1062 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1063 break;
718e3744 1064 default:
1065 break;
1066 }
7514fb77
PJ
1067 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1068 return 0;
1069
f3a1732e
CF
1070 /* XXX: What exactly do those checks do? Do we support
1071 * e.g. IPv4 routes with IPv6 nexthops or vice versa? */
7514fb77
PJ
1072 if (RIB_SYSTEM_ROUTE(rib) ||
1073 (family == AFI_IP && rn->p.family != AF_INET) ||
1074 (family == AFI_IP6 && rn->p.family != AF_INET6))
1075 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1076
f3a1732e
CF
1077 /* The original code didn't determine the family correctly
1078 * e.g. for NEXTHOP_TYPE_IFINDEX. Retrieve the correct afi
1079 * from the rib_table_info in those cases.
1080 * Possibly it may be better to use only the rib_table_info
1081 * in every case.
1082 */
1083 if (!family)
1084 family = info->afi;
1085
c52ef59f 1086 memset(&nexthop->rmap_src.ipv6, 0, sizeof(union g_addr));
c52ef59f 1087
ca84c8ef 1088 /* It'll get set if required inside */
0032dd59
FL
1089 ret = zebra_route_map_check(family, rib->type, &rn->p, nexthop, rib->vrf_id,
1090 rib->tag);
7514fb77 1091 if (ret == RMAP_DENYMATCH)
518f0eb1
DS
1092 {
1093 if (IS_ZEBRA_DEBUG_RIB)
1094 {
1095 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, sizeof (buf));
41ec9222 1096 zlog_debug("%u:%s/%d: Filtering out with NH out %s due to route map",
3ee39b5b
DS
1097 rib->vrf_id, buf, rn->p.prefixlen,
1098 ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
518f0eb1
DS
1099 }
1100 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1101 }
718e3744 1102 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1103}
1104
03e232a4
DO
1105/* Iterate over all nexthops of the given RIB entry and refresh their
1106 * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
1107 * nexthop is found to toggle the ACTIVE flag, the whole rib structure
1108 * is flagged with ZEBRA_FLAG_CHANGED. The 4th 'set' argument is
1109 * transparently passed to nexthop_active_check().
1110 *
1111 * Return value is the new number of active nexthops.
1112 */
1113
a1ac18c4 1114static int
718e3744 1115nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
1116{
1117 struct nexthop *nexthop;
c52ef59f 1118 union g_addr prev_src;
6e26278c
DS
1119 unsigned int prev_active, prev_index, new_active, old_num_nh;
1120
1121 old_num_nh = rib->nexthop_active_num;
718e3744 1122
1123 rib->nexthop_active_num = 0;
1124 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1125
1126 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
03e232a4 1127 {
c52ef59f
DS
1128 /* No protocol daemon provides src and so we're skipping tracking it */
1129 prev_src = nexthop->rmap_src;
03e232a4 1130 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
c3a56063 1131 prev_index = nexthop->ifindex;
03e232a4
DO
1132 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
1133 rib->nexthop_active_num++;
c52ef59f 1134 /* Don't allow src setting on IPv6 addr for now */
c3a56063 1135 if (prev_active != new_active ||
c52ef59f
DS
1136 prev_index != nexthop->ifindex ||
1137 ((nexthop->type >= NEXTHOP_TYPE_IFINDEX &&
1138 nexthop->type < NEXTHOP_TYPE_IPV6) &&
0aabccc0
DD
1139 prev_src.ipv4.s_addr != nexthop->rmap_src.ipv4.s_addr) ||
1140 ((nexthop->type >= NEXTHOP_TYPE_IPV6 &&
1141 nexthop->type < NEXTHOP_TYPE_BLACKHOLE) &&
1142 !(IPV6_ADDR_SAME (&prev_src.ipv6, &nexthop->rmap_src.ipv6))))
6e26278c
DS
1143 {
1144 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1145 SET_FLAG (rib->status, RIB_ENTRY_NEXTHOPS_CHANGED);
1146 }
03e232a4 1147 }
6e26278c
DS
1148
1149 if (old_num_nh != rib->nexthop_active_num)
1150 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1151
1152 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_CHANGED))
1153 {
1154 SET_FLAG (rib->status, RIB_ENTRY_NEXTHOPS_CHANGED);
1155 }
1156
718e3744 1157 return rib->nexthop_active_num;
1158}
6baeb988 1159
6b0655a2 1160
718e3744 1161
6ae24471
DS
1162/* Update flag indicates whether this is a "replace" or not. Currently, this
1163 * is only used for IPv4.
1164 */
3e5c6e00 1165static int
6ae24471 1166rib_install_kernel (struct route_node *rn, struct rib *rib, int update)
718e3744 1167{
1168 int ret = 0;
fa713d9e 1169 struct nexthop *nexthop, *tnexthop;
416ec78d 1170 rib_table_info_t *info = rn->table->info;
fa713d9e 1171 int recursing;
718e3744 1172
416ec78d
DL
1173 if (info->safi != SAFI_UNICAST)
1174 {
1175 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1176 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1177 return ret;
1178 }
1179
5adc2528
AS
1180 /*
1181 * Make sure we update the FPM any time we send new information to
1182 * the kernel.
1183 */
1184 zfpm_trigger_update (rn, "installing in kernel");
718e3744 1185 switch (PREFIX_FAMILY (&rn->p))
1186 {
1187 case AF_INET:
6ae24471
DS
1188 if (update)
1189 ret = kernel_update_ipv4 (&rn->p, rib);
1190 else
1191 ret = kernel_add_ipv4 (&rn->p, rib);
718e3744 1192 break;
718e3744 1193 case AF_INET6:
dccc5225 1194 if (update)
1195 ret = kernel_update_ipv6 (&rn->p, rib);
1196 else
1197 ret = kernel_add_ipv6 (&rn->p, rib);
718e3744 1198 break;
718e3744 1199 }
1200
3e5c6e00 1201 /* If install succeeds, update FIB flag for nexthops. */
1202 if (!ret)
718e3744 1203 {
fa713d9e 1204 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
3e5c6e00 1205 {
1206 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1207 continue;
1208
1209 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1210 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1211 else
1212 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1213 }
718e3744 1214 }
3e5c6e00 1215
1216 return ret;
718e3744 1217}
1218
1219/* Uninstall the route from kernel. */
a1ac18c4 1220static int
718e3744 1221rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
1222{
1223 int ret = 0;
fa713d9e 1224 struct nexthop *nexthop, *tnexthop;
416ec78d 1225 rib_table_info_t *info = rn->table->info;
fa713d9e 1226 int recursing;
718e3744 1227
416ec78d
DL
1228 if (info->safi != SAFI_UNICAST)
1229 {
1230 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1231 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1232 return ret;
1233 }
1234
5adc2528
AS
1235 /*
1236 * Make sure we update the FPM any time we send new information to
1237 * the kernel.
1238 */
1239 zfpm_trigger_update (rn, "uninstalling from kernel");
1240
718e3744 1241 switch (PREFIX_FAMILY (&rn->p))
1242 {
1243 case AF_INET:
1244 ret = kernel_delete_ipv4 (&rn->p, rib);
1245 break;
718e3744 1246 case AF_INET6:
1247 ret = kernel_delete_ipv6 (&rn->p, rib);
1248 break;
718e3744 1249 }
1250
fa713d9e 1251 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
718e3744 1252 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1253
1254 return ret;
1255}
1256
1257/* Uninstall the route from kernel. */
a1ac18c4 1258static void
718e3744 1259rib_uninstall (struct route_node *rn, struct rib *rib)
1260{
416ec78d
DL
1261 rib_table_info_t *info = rn->table->info;
1262
718e3744 1263 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1264 {
416ec78d
DL
1265 if (info->safi == SAFI_UNICAST)
1266 zfpm_trigger_update (rn, "rib_uninstall");
5adc2528 1267
718e3744 1268 redistribute_delete (&rn->p, rib);
1269 if (! RIB_SYSTEM_ROUTE (rib))
1270 rib_uninstall_kernel (rn, rib);
1271 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
1272 }
1273}
1274
6d691129
PJ
1275static void rib_unlink (struct route_node *, struct rib *);
1276
9fd92e3c
AS
1277/*
1278 * rib_can_delete_dest
1279 *
1280 * Returns TRUE if the given dest can be deleted from the table.
1281 */
1282static int
1283rib_can_delete_dest (rib_dest_t *dest)
1284{
1285 if (dest->routes)
1286 {
1287 return 0;
1288 }
1289
5adc2528
AS
1290 /*
1291 * Don't delete the dest if we have to update the FPM about this
1292 * prefix.
1293 */
1294 if (CHECK_FLAG (dest->flags, RIB_DEST_UPDATE_FPM) ||
1295 CHECK_FLAG (dest->flags, RIB_DEST_SENT_TO_FPM))
1296 return 0;
1297
9fd92e3c
AS
1298 return 1;
1299}
1300
1301/*
1302 * rib_gc_dest
1303 *
1304 * Garbage collect the rib dest corresponding to the given route node
1305 * if appropriate.
1306 *
1307 * Returns TRUE if the dest was deleted, FALSE otherwise.
1308 */
1309int
1310rib_gc_dest (struct route_node *rn)
1311{
1312 rib_dest_t *dest;
41ec9222 1313 struct zebra_vrf *zvrf;
9fd92e3c
AS
1314
1315 dest = rib_dest_from_rnode (rn);
1316 if (!dest)
1317 return 0;
1318
1319 if (!rib_can_delete_dest (dest))
1320 return 0;
1321
41ec9222 1322 zvrf = rib_dest_vrf (dest);
2263a412
DL
1323 if (IS_ZEBRA_DEBUG_RIB)
1324 rnode_debug (rn, zvrf->vrf_id, "removing dest from table");
9fd92e3c
AS
1325
1326 dest->rnode = NULL;
1327 XFREE (MTYPE_RIB_DEST, dest);
1328 rn->info = NULL;
1329
1330 /*
1331 * Release the one reference that we keep on the route node.
1332 */
1333 route_unlock_node (rn);
1334 return 1;
1335}
1336
3e5c6e00 1337static void
1338rib_process_add_route (struct zebra_vrf *zvrf, struct route_node *rn,
1339 struct rib *select)
1340{
1341 char buf[INET6_ADDRSTRLEN];
1342 int installed = 1;
1343
1344 zfpm_trigger_update (rn, "new route selected");
1345
1346 /* Update real nexthop. This may actually determine if nexthop is active or not. */
1347 if (!nexthop_active_update (rn, select, 1))
1348 {
1349 UNSET_FLAG(select->flags, ZEBRA_FLAG_CHANGED);
1350 return;
1351 }
1352
1353 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1354 if (IS_ZEBRA_DEBUG_RIB)
1355 {
1356 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
1357 zlog_debug ("%u:%s/%d: Adding route rn %p, rib %p (type %d)",
1358 zvrf->vrf_id, buf, rn->p.prefixlen, rn, select, select->type);
1359 }
1360
1361 if (!RIB_SYSTEM_ROUTE (select))
1362 {
1363 if (rib_install_kernel (rn, select, 0))
1364 {
1365 installed = 0;
fb02523b
DS
1366 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
1367 zlog_warn ("%u:%s/%d: Route install failed",
1368 zvrf->vrf_id, buf, rn->p.prefixlen);
3e5c6e00 1369 }
1370 }
1371
1372 /* Update for redistribution. */
1373 if (installed)
1374 redistribute_update (&rn->p, select, NULL);
1375 UNSET_FLAG(select->flags, ZEBRA_FLAG_CHANGED);
1376}
1377
1378static void
1379rib_process_del_route (struct zebra_vrf *zvrf, struct route_node *rn,
1380 struct rib *fib)
1381{
1382 char buf[INET6_ADDRSTRLEN];
1383
1384 zfpm_trigger_update (rn, "removing existing route");
1385
1386 /* Withdraw redistribute and uninstall from kernel. */
1387 if (IS_ZEBRA_DEBUG_RIB)
1388 {
1389 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
1390 zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d)",
1391 zvrf->vrf_id, buf, rn->p.prefixlen, rn, fib, fib->type);
1392 }
1393
1394 redistribute_delete(&rn->p, fib);
1395 if (!RIB_SYSTEM_ROUTE (fib))
1396 rib_uninstall_kernel (rn, fib);
1397
1398 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1399
1400 /* Update nexthop for route, reset changed flag. */
1401 nexthop_active_update (rn, fib, 1);
1402 UNSET_FLAG(fib->flags, ZEBRA_FLAG_CHANGED);
1403}
1404
1405static void
1406rib_process_update_route (struct zebra_vrf *zvrf, struct route_node *rn,
1407 struct rib *select, struct rib *fib)
1408{
1409 char buf[INET6_ADDRSTRLEN];
1410 struct nexthop *nexthop = NULL, *tnexthop;
1411 int recursing;
1412 int nh_active = 0;
1413 int installed = 1;
1414
1415 if (IS_ZEBRA_DEBUG_RIB)
1416 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
1417
1418 /*
1419 * We have to install or update if a new route has been selected or
1420 * something has changed.
1421 */
1422 if (select != fib ||
1423 CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
1424 {
1425 zfpm_trigger_update (rn, "updating existing route");
1426
1427 /* Update the nexthop; we could determine here that nexthop is inactive. */
1428 if (nexthop_active_update (rn, select, 1))
1429 nh_active = 1;
1430
1431 /* If nexthop is active, install the selected route, if appropriate. If
1432 * the install succeeds, cleanup flags for prior route, if different from
1433 * newly selected.
1434 */
1435 if (nh_active)
1436 {
1437 if (IS_ZEBRA_DEBUG_RIB)
1438 {
1439 if (select != fib)
1440 zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d) "
1441 "old %p (type %d)", zvrf->vrf_id, buf, rn->p.prefixlen,
1442 rn, select, select->type, fib, fib->type);
1443 else
1444 zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d)",
1445 zvrf->vrf_id, buf, rn->p.prefixlen, rn, select, select->type);
1446 }
1447 /* Non-system route should be installed. */
1448 if (!RIB_SYSTEM_ROUTE (select))
1449 {
1450 if (rib_install_kernel (rn, select, 1))
1451 {
1452 installed = 0;
fb02523b
DS
1453 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
1454 zlog_warn ("%u:%s/%d: Route install failed",
1455 zvrf->vrf_id, buf, rn->p.prefixlen);
3e5c6e00 1456 }
1457 }
1458
1459 /* If install succeeded or system route, cleanup flags for prior route. */
1460 if (installed && select != fib)
1461 {
1462 if (RIB_SYSTEM_ROUTE(select))
1463 {
1464 if (!RIB_SYSTEM_ROUTE (fib))
1465 rib_uninstall_kernel (rn, fib);
1466 }
1467 else
1468 {
1469 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1470 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1471 }
1472
1473 }
1474
1475 /* Update for redistribution. */
1476 if (installed)
1477 {
1478 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1479 redistribute_update (&rn->p, select, (select == fib) ? NULL : fib);
1480 }
1481 }
1482
1483 /*
1484 * If nexthop for selected route is not active or install failed, we
1485 * may need to uninstall and delete for redistribution.
1486 */
1487 if (!nh_active || !installed)
1488 {
1489 struct rib *del;
1490
1491 if (IS_ZEBRA_DEBUG_RIB)
1492 {
1493 if (select != fib)
1494 zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) "
1495 "old %p (type %d) - %s", zvrf->vrf_id, buf, rn->p.prefixlen,
1496 rn, select, select->type, fib, fib->type,
1497 nh_active ? "install failed" : "nexthop inactive");
1498 else
1499 zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) - %s",
1500 zvrf->vrf_id, buf, rn->p.prefixlen, rn, select, select->type,
1501 nh_active ? "install failed" : "nexthop inactive");
1502 }
1503
1504 del = (select == fib) ? select : fib;
1505
1506 redistribute_delete(&rn->p, del);
1507
1508 if (!RIB_SYSTEM_ROUTE (del))
1509 rib_uninstall_kernel (rn, del);
1510 UNSET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1511 }
1512 }
1513 else
1514 {
1515 /*
1516 * Same route selected; check if in the FIB and if not, re-install. This
1517 * is housekeeping code to deal with race conditions in kernel with linux
1518 * netlink reporting interface up before IPv4 or IPv6 protocol is ready
1519 * to add routes.
1520 */
1521 if (!RIB_SYSTEM_ROUTE (select))
1522 {
1523 int in_fib = 0;
1524
1525 for (ALL_NEXTHOPS_RO(select->nexthop, nexthop, tnexthop, recursing))
1526 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1527 {
1528 in_fib = 1;
1529 break;
1530 }
1531 if (!in_fib)
1532 rib_install_kernel (rn, select, 0);
1533 }
1534 }
1535
1536 /* Update prior route. */
1537 if (select != fib)
1538 {
1539 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1540
1541 /* Set real nexthop. */
1542 nexthop_active_update (rn, fib, 1);
1543 UNSET_FLAG(fib->flags, ZEBRA_FLAG_CHANGED);
1544 }
1545
1546 /* Clear changed flag. */
1547 UNSET_FLAG(select->flags, ZEBRA_FLAG_CHANGED);
1548}
1549
718e3744 1550/* Core function for processing routing information base. */
e96f9203
DO
1551static void
1552rib_process (struct route_node *rn)
718e3744 1553{
1554 struct rib *rib;
1555 struct rib *next;
1556 struct rib *fib = NULL;
1557 struct rib *select = NULL;
6d691129 1558 struct rib *del = NULL;
f304cb48 1559 char buf[INET6_ADDRSTRLEN];
41ec9222 1560 rib_dest_t *dest;
1561 struct zebra_vrf *zvrf = NULL;
58255d34 1562 vrf_id_t vrf_id = VRF_UNKNOWN;
41ec9222 1563
4d38fdb4 1564 assert (rn);
1565
41ec9222 1566 dest = rib_dest_from_rnode (rn);
1567 if (dest)
1568 {
1569 zvrf = rib_dest_vrf (dest);
1570 vrf_id = zvrf->vrf_id;
1571 }
1572
1573 if (IS_ZEBRA_DEBUG_RIB)
f304cb48 1574 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
93bdadae 1575
41ec9222 1576 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
1577 zlog_debug ("%u:%s/%d: Processing rn %p", vrf_id, buf, rn->p.prefixlen, rn);
1578
9fd92e3c 1579 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
718e3744 1580 {
41ec9222 1581 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
1582 zlog_debug ("%u:%s/%d: Examine rib %p (type %d) status %x flags %x "
1583 "dist %d metric %d",
1584 vrf_id, buf, rn->p.prefixlen, rib, rib->type, rib->status,
1585 rib->flags, rib->distance, rib->metric);
1586
6e26278c
DS
1587 UNSET_FLAG(rib->status, RIB_ENTRY_NEXTHOPS_CHANGED);
1588
718e3744 1589 /* Currently installed rib. */
1590 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
6d691129
PJ
1591 {
1592 assert (fib == NULL);
1593 fib = rib;
1594 }
ca657c65 1595
6d691129
PJ
1596 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1597 * which we need to do do further work with below.
1598 */
1599 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1600 {
1601 if (rib != fib)
1602 {
1603 if (IS_ZEBRA_DEBUG_RIB)
2263a412 1604 rnode_debug (rn, vrf_id, "rn %p, removing rib %p", rn, rib);
9fd92e3c 1605 rib_unlink (rn, rib);
6d691129
PJ
1606 }
1607 else
1608 del = rib;
1609
1610 continue;
1611 }
4d38fdb4 1612
718e3744 1613 /* Skip unreachable nexthop. */
ca657c65
DS
1614 /* This first call to nexthop_active_update is merely to determine if
1615 * there's any change to nexthops associated with this RIB entry. Now,
1616 * rib_process() can be invoked due to an external event such as link
1617 * down or due to next-hop-tracking evaluation. In the latter case,
1618 * a decision has already been made that the NHs have changed. So, no
1619 * need to invoke a potentially expensive call again. Further, since
1620 * the change might be in a recursive NH which is not caught in
1621 * the nexthop_active_update() code. Thus, we might miss changes to
1622 * recursive NHs.
6e26278c 1623 */
ca657c65 1624 if (!CHECK_FLAG(rib->flags, ZEBRA_FLAG_CHANGED) &&
f857321e
DW
1625 ! nexthop_active_update (rn, rib, 0))
1626 {
1627 if (rib->type == ZEBRA_ROUTE_TABLE)
1628 {
1629 /* This entry was denied by the 'ip protocol table' route-map, we
1630 * need to delete it */
1631 if (rib != fib)
1632 {
1633 if (IS_ZEBRA_DEBUG_RIB)
1634 zlog_debug ("%s: %s/%d: imported via import-table but denied "
1635 "by the ip protocol table route-map",
1636 __func__, buf, rn->p.prefixlen);
1637 rib_unlink (rn, rib);
1638 }
1639 else
1640 del = rib;
1641 }
1642
1643 continue;
1644 }
718e3744 1645
f857321e 1646 /* Infinite distance. */
718e3744 1647 if (rib->distance == DISTANCE_INFINITY)
8733ba72
DS
1648 {
1649 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1650 continue;
1651 }
718e3744 1652
af887b51 1653 /* Newly selected rib, the common case. */
1654 if (!select)
1655 {
1656 select = rib;
1657 continue;
1658 }
1659
1660 /* filter route selection in following order:
af887b51 1661 * - connected beats other types
a8d9c1f9 1662 * - lower distance beats higher
af887b51 1663 * - lower metric beats higher for equal distance
1664 * - last, hence oldest, route wins tie break.
1665 */
a1038a15 1666
1667 /* Connected routes. Pick the last connected
1668 * route of the set of lowest metric connected routes.
1669 */
a8d9c1f9 1670 if (rib->type == ZEBRA_ROUTE_CONNECT)
1671 {
a1038a15 1672 if (select->type != ZEBRA_ROUTE_CONNECT
a8d9c1f9 1673 || rib->metric <= select->metric)
8733ba72
DS
1674 {
1675 UNSET_FLAG (select->flags, ZEBRA_FLAG_CHANGED);
1676 select = rib;
1677 }
1678 else
1679 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
a1038a15 1680 continue;
a8d9c1f9 1681 }
1682 else if (select->type == ZEBRA_ROUTE_CONNECT)
8733ba72
DS
1683 {
1684 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1685 continue;
1686 }
a8d9c1f9 1687
1688 /* higher distance loses */
1689 if (rib->distance > select->distance)
8733ba72
DS
1690 {
1691 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1692 continue;
1693 }
a8d9c1f9 1694
1695 /* lower wins */
1696 if (rib->distance < select->distance)
1697 {
8733ba72 1698 UNSET_FLAG (select->flags, ZEBRA_FLAG_CHANGED);
af887b51 1699 select = rib;
a8d9c1f9 1700 continue;
1701 }
1702
1703 /* metric tie-breaks equal distance */
1704 if (rib->metric <= select->metric)
8733ba72
DS
1705 {
1706 UNSET_FLAG (select->flags, ZEBRA_FLAG_CHANGED);
1707 select = rib;
1708 }
9fd92e3c 1709 } /* RNODE_FOREACH_RIB_SAFE */
dc95824a
DO
1710
1711 /* After the cycle is finished, the following pointers will be set:
1712 * select --- the winner RIB entry, if any was found, otherwise NULL
1713 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1714 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1715 * rib --- NULL
1716 */
41ec9222 1717 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
1718 zlog_debug ("%u:%s/%d: After processing: select %p fib %p del %p",
1719 vrf_id, buf, rn->p.prefixlen, select, fib, del);
dc95824a
DO
1720
1721 /* Same RIB entry is selected. Update FIB and finish. */
3e5c6e00 1722 if (select && select == fib)
1723 rib_process_update_route (zvrf, rn, select, select);
1724 else if (select && fib)
1725 rib_process_update_route (zvrf, rn, select, fib);
1726 else if (select)
1727 rib_process_add_route (zvrf, rn, select);
1728 else if (fib)
1729 rib_process_del_route (zvrf, rn, fib);
1730
1731#if 0
718e3744 1732 if (select && select == fib)
1733 {
2263a412
DL
1734 if (IS_ZEBRA_DEBUG_RIB)
1735 rnode_debug (rn, vrf_id, "Updating existing route, select %p, fib %p",
1736 select, fib);
718e3744 1737 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
4d38fdb4 1738 {
416ec78d
DL
1739 if (info->safi == SAFI_UNICAST)
1740 zfpm_trigger_update (rn, "updating existing route");
5adc2528 1741
4d38fdb4 1742 /* Set real nexthop. */
6e26278c
DS
1743 /* Need to check if any NHs are active to clear the
1744 * the selected flag
1745 */
1746 if (nexthop_active_update (rn, select, 1))
1747 {
41ec9222 1748 if (IS_ZEBRA_DEBUG_RIB)
1749 zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d)",
1750 vrf_id, buf, rn->p.prefixlen, rn, select, select->type);
dccc5225 1751 if (! RIB_SYSTEM_ROUTE (select))
6ae24471 1752 {
dccc5225 1753 /* Clear FIB flag if performing a replace, will get set again
1754 * as part of install.
1755 */
6ae24471
DS
1756 for (nexthop = select->nexthop; nexthop; nexthop = nexthop->next)
1757 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
dccc5225 1758 rib_install_kernel (rn, select, 1);
6ae24471 1759 }
5048fe14 1760
1761 /* assuming that the receiver knows how to dedup */
c41fc67b 1762 redistribute_update (&rn->p, select, NULL);
6e26278c
DS
1763 }
1764 else
1765 {
41ec9222 1766 if (IS_ZEBRA_DEBUG_RIB)
1767 zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) "
1768 "- nexthop inactive",
1769 vrf_id, buf, rn->p.prefixlen, rn, select, select->type);
1770
5048fe14 1771 /* Withdraw unreachable redistribute route */
1772 redistribute_delete(&rn->p, select);
1773
dccc5225 1774 /* Do the uninstall here, if not done earlier. */
1775 if (! RIB_SYSTEM_ROUTE (select))
6ae24471 1776 rib_uninstall_kernel (rn, select);
6e26278c
DS
1777 UNSET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1778 }
ca657c65 1779 UNSET_FLAG (select->flags, ZEBRA_FLAG_CHANGED);
6e26278c 1780 }
d753e9ee 1781 else if (! RIB_SYSTEM_ROUTE (select))
4d38fdb4 1782 {
1783 /* Housekeeping code to deal with
1784 race conditions in kernel with linux
1785 netlink reporting interface up before IPv4 or IPv6 protocol
1786 is ready to add routes.
1787 This makes sure the routes are IN the kernel.
1788 */
1789
fa713d9e 1790 for (ALL_NEXTHOPS_RO(select->nexthop, nexthop, tnexthop, recursing))
a3aaf5b0 1791 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
4d38fdb4 1792 {
a3aaf5b0
DO
1793 installed = 1;
1794 break;
4d38fdb4 1795 }
1796 if (! installed)
6ae24471 1797 rib_install_kernel (rn, select, 0);
4d38fdb4 1798 }
6d691129 1799 goto end;
718e3744 1800 }
1801
dc95824a
DO
1802 /* At this point we either haven't found the best RIB entry or it is
1803 * different from what we currently intend to flag with SELECTED. In both
1804 * cases, if a RIB block is present in FIB, it should be withdrawn.
1805 */
718e3744 1806 if (fib)
1807 {
2263a412
DL
1808 if (IS_ZEBRA_DEBUG_RIB)
1809 rnode_debug (rn, vrf_id, "Removing existing route, fib %p", fib);
1810
416ec78d
DL
1811 if (info->safi == SAFI_UNICAST)
1812 zfpm_trigger_update (rn, "removing existing route");
5adc2528 1813
dccc5225 1814 /* If there's no route to replace this with, withdraw redistribute and
1815 * uninstall from kernel.
1816 */
5048fe14 1817 if (!select)
6ae24471 1818 {
41ec9222 1819 if (IS_ZEBRA_DEBUG_RIB)
1820 zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d)",
1821 vrf_id, buf, rn->p.prefixlen, rn, fib, fib->type);
1822
dccc5225 1823 redistribute_delete(&rn->p, fib);
1824 if (! RIB_SYSTEM_ROUTE (fib))
1825 rib_uninstall_kernel (rn, fib);
6ae24471 1826 }
dccc5225 1827
718e3744 1828 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1829
1830 /* Set real nexthop. */
1831 nexthop_active_update (rn, fib, 1);
ca657c65 1832 UNSET_FLAG(fib->flags, ZEBRA_FLAG_CHANGED);
718e3744 1833 }
1834
dc95824a
DO
1835 /* Regardless of some RIB entry being SELECTED or not before, now we can
1836 * tell, that if a new winner exists, FIB is still not updated with this
1837 * data, but ready to be.
1838 */
718e3744 1839 if (select)
1840 {
2263a412
DL
1841 if (IS_ZEBRA_DEBUG_RIB)
1842 rnode_debug (rn, "Adding route, select %p", select);
1843
416ec78d
DL
1844 if (info->safi == SAFI_UNICAST)
1845 zfpm_trigger_update (rn, "new route selected");
5adc2528 1846
718e3744 1847 /* Set real nexthop. */
6e26278c
DS
1848 if (nexthop_active_update (rn, select, 1))
1849 {
41ec9222 1850 if (IS_ZEBRA_DEBUG_RIB)
1851 {
1852 if (fib)
1853 zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d) "
1854 "old %p (type %d)", vrf_id, buf, rn->p.prefixlen, rn,
1855 select, select->type, fib, fib->type);
1856 else
1857 zlog_debug ("%u:%s/%d: Adding route rn %p, rib %p (type %d)",
1858 vrf_id, buf, rn->p.prefixlen, rn, select, select->type);
1859 }
1860
dccc5225 1861 if (! RIB_SYSTEM_ROUTE (select))
6ae24471 1862 {
dccc5225 1863 /* Clear FIB flag if performing a replace, will get set again
1864 * as part of install.
1865 */
1866 if (fib)
1867 {
1868 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1869 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1870 }
1871 rib_install_kernel (rn, select, fib? 1 : 0);
6ae24471 1872 }
0b560feb 1873 else
1874 {
1875 /* Uninstall prior route here, if needed. */
1876 if (fib && !RIB_SYSTEM_ROUTE (fib))
1877 rib_uninstall_kernel (rn, fib);
1878 }
dccc5225 1879
6e26278c 1880 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
5048fe14 1881 /* Unconditionally announce, this part is exercised by new routes */
c41fc67b 1882 /* If we cannot add, for example route added is learnt by the */
1883 /* protocol we're trying to redistribute to, delete the redist */
1884 /* This is notified by setting the is_update to 1 */
1885 redistribute_update (&rn->p, select, fib);
6e26278c 1886 }
6ae24471
DS
1887 else
1888 {
41ec9222 1889 /* Uninstall prior route here and do redist delete, if needed. */
a219b295 1890 if (fib)
41ec9222 1891 {
1892 if (IS_ZEBRA_DEBUG_RIB)
1893 zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) "
1894 "- nexthop inactive",
1895 vrf_id, buf, rn->p.prefixlen, rn, fib, fib->type);
1896
1897 if (!RIB_SYSTEM_ROUTE (fib))
1898 rib_uninstall_kernel (rn, fib);
1899 redistribute_delete(&rn->p, fib);
1900 }
6ae24471 1901 }
ca657c65 1902 UNSET_FLAG(select->flags, ZEBRA_FLAG_CHANGED);
718e3744 1903 }
3e5c6e00 1904#endif
4d38fdb4 1905
6d691129
PJ
1906 /* FIB route was removed, should be deleted */
1907 if (del)
1908 {
1909 if (IS_ZEBRA_DEBUG_RIB)
2263a412 1910 rnode_debug (rn, vrf_id, "Deleting fib %p, rn %p", del, rn);
6d691129
PJ
1911 rib_unlink (rn, del);
1912 }
4d38fdb4 1913
9fd92e3c
AS
1914 /*
1915 * Check if the dest can be deleted now.
1916 */
1917 rib_gc_dest (rn);
e96f9203
DO
1918}
1919
5110a0c6
SH
1920/* Take a list of route_node structs and return 1, if there was a record
1921 * picked from it and processed by rib_process(). Don't process more,
1922 * than one RN record; operate only in the specified sub-queue.
e96f9203 1923 */
ef9b113e 1924static unsigned int
e96f9203
DO
1925process_subq (struct list * subq, u_char qindex)
1926{
5110a0c6 1927 struct listnode *lnode = listhead (subq);
e96f9203 1928 struct route_node *rnode;
41ec9222 1929 char buf[INET6_ADDRSTRLEN];
1930 rib_dest_t *dest;
1931 struct zebra_vrf *zvrf = NULL;
5110a0c6
SH
1932
1933 if (!lnode)
e96f9203 1934 return 0;
5110a0c6 1935
e96f9203 1936 rnode = listgetdata (lnode);
41ec9222 1937 dest = rib_dest_from_rnode (rnode);
1938 if (dest)
1939 zvrf = rib_dest_vrf (dest);
1940
e96f9203 1941 rib_process (rnode);
5110a0c6 1942
41ec9222 1943 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
1944 {
1945 inet_ntop (rnode->p.family, &rnode->p.u.prefix, buf, INET6_ADDRSTRLEN);
1946 zlog_debug ("%u:%s/%d: rn %p dequeued from sub-queue %u",
1947 zvrf ? zvrf->vrf_id : 0, buf, rnode->p.prefixlen, rnode, qindex);
1948 }
1949
9fd92e3c
AS
1950 if (rnode->info)
1951 UNSET_FLAG (rib_dest_from_rnode (rnode)->flags, RIB_ROUTE_QUEUED (qindex));
1952
67b9467f 1953#if 0
5110a0c6
SH
1954 else
1955 {
1956 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1957 __func__, rnode, rnode->lock);
1958 zlog_backtrace(LOG_DEBUG);
1959 }
67b9467f 1960#endif
e96f9203
DO
1961 route_unlock_node (rnode);
1962 list_delete_node (subq, lnode);
1963 return 1;
1964}
1965
fb018d25
DS
1966/*
1967 * All meta queues have been processed. Trigger next-hop evaluation.
1968 */
1969static void
1970meta_queue_process_complete (struct work_queue *dummy)
1971{
9ec6b0bb 1972 vrf_iter_t iter;
1973 struct zebra_vrf *zvrf;
1974
1975 /* Evaluate nexthops for those VRFs which underwent route processing. This
1976 * should limit the evaluation to the necessary VRFs in most common
1977 * situations.
1978 */
1979 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1980 {
1981 if (((zvrf = vrf_iter2info (iter)) != NULL) &&
1982 (zvrf->flags & ZEBRA_VRF_RIB_SCHEDULED))
1983 {
1984 zvrf->flags &= ~ZEBRA_VRF_RIB_SCHEDULED;
1985 zebra_evaluate_rnh(zvrf->vrf_id, AF_INET, 0, RNH_NEXTHOP_TYPE, NULL);
1986 zebra_evaluate_rnh(zvrf->vrf_id, AF_INET, 0, RNH_IMPORT_CHECK_TYPE, NULL);
1987 zebra_evaluate_rnh(zvrf->vrf_id, AF_INET6, 0, RNH_NEXTHOP_TYPE, NULL);
1988 zebra_evaluate_rnh(zvrf->vrf_id, AF_INET6, 0, RNH_IMPORT_CHECK_TYPE, NULL);
1989 }
1990 }
fb018d25
DS
1991}
1992
e96f9203
DO
1993/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1994 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1995 * is pointed to the meta queue structure.
1996 */
1997static wq_item_status
1998meta_queue_process (struct work_queue *dummy, void *data)
1999{
2000 struct meta_queue * mq = data;
5110a0c6
SH
2001 unsigned i;
2002
e96f9203
DO
2003 for (i = 0; i < MQ_SIZE; i++)
2004 if (process_subq (mq->subq[i], i))
5110a0c6
SH
2005 {
2006 mq->size--;
2007 break;
2008 }
e96f9203
DO
2009 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
2010}
2011
9fd92e3c
AS
2012/*
2013 * Map from rib types to queue type (priority) in meta queue
2014 */
5110a0c6
SH
2015static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
2016 [ZEBRA_ROUTE_SYSTEM] = 4,
2017 [ZEBRA_ROUTE_KERNEL] = 0,
2018 [ZEBRA_ROUTE_CONNECT] = 0,
2019 [ZEBRA_ROUTE_STATIC] = 1,
2020 [ZEBRA_ROUTE_RIP] = 2,
2021 [ZEBRA_ROUTE_RIPNG] = 2,
2022 [ZEBRA_ROUTE_OSPF] = 2,
2023 [ZEBRA_ROUTE_OSPF6] = 2,
2024 [ZEBRA_ROUTE_ISIS] = 2,
2025 [ZEBRA_ROUTE_BGP] = 3,
2026 [ZEBRA_ROUTE_HSLS] = 4,
7a4bb9c5 2027 [ZEBRA_ROUTE_TABLE] = 1,
5110a0c6
SH
2028};
2029
2030/* Look into the RN and queue it into one or more priority queues,
2031 * increasing the size for each data push done.
e96f9203 2032 */
ef9b113e
SH
2033static void
2034rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
e96f9203 2035{
e96f9203 2036 struct rib *rib;
5110a0c6 2037
9fd92e3c 2038 RNODE_FOREACH_RIB (rn, rib)
e96f9203 2039 {
5110a0c6 2040 u_char qindex = meta_queue_map[rib->type];
9ec6b0bb 2041 struct zebra_vrf *zvrf;
5110a0c6
SH
2042
2043 /* Invariant: at this point we always have rn->info set. */
9fd92e3c
AS
2044 if (CHECK_FLAG (rib_dest_from_rnode (rn)->flags,
2045 RIB_ROUTE_QUEUED (qindex)))
2263a412
DL
2046 {
2047 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
2048 rnode_debug (rn, rib->vrf_id, "rn %p is already queued in sub-queue %u",
2049 rn, qindex);
2050 continue;
2051 }
5110a0c6 2052
9fd92e3c 2053 SET_FLAG (rib_dest_from_rnode (rn)->flags, RIB_ROUTE_QUEUED (qindex));
5110a0c6
SH
2054 listnode_add (mq->subq[qindex], rn);
2055 route_lock_node (rn);
2056 mq->size++;
2057
41ec9222 2058 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
2263a412
DL
2059 rnode_debug (rn, rib->vrf_id, "queued rn %p into sub-queue %u",
2060 rn, qindex);
9ec6b0bb 2061
2062 zvrf = zebra_vrf_lookup (rib->vrf_id);
2063 if (zvrf)
2064 zvrf->flags |= ZEBRA_VRF_RIB_SCHEDULED;
e96f9203 2065 }
4d38fdb4 2066}
2067
6d691129 2068/* Add route_node to work queue and schedule processing */
6e26278c 2069void
44e9909d 2070rib_queue_add (struct route_node *rn)
4d38fdb4 2071{
44e9909d 2072 assert (rn);
4d38fdb4 2073
fc328ac9 2074 /* Pointless to queue a route_node with no RIB entries to add or remove */
9fd92e3c 2075 if (!rnode_to_ribs (rn))
6d691129 2076 {
fc328ac9
SV
2077 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
2078 __func__, rn, rn->lock);
2079 zlog_backtrace(LOG_DEBUG);
2080 return;
2081 }
2082
44e9909d 2083 if (zebrad.ribq == NULL)
fc328ac9
SV
2084 {
2085 zlog_err ("%s: work_queue does not exist!", __func__);
2086 return;
4d38fdb4 2087 }
4d38fdb4 2088
cc2dd928
SH
2089 /*
2090 * The RIB queue should normally be either empty or holding the only
2091 * work_queue_item element. In the latter case this element would
2092 * hold a pointer to the meta queue structure, which must be used to
2093 * actually queue the route nodes to process. So create the MQ
2094 * holder, if necessary, then push the work into it in any case.
e96f9203
DO
2095 * This semantics was introduced after 0.99.9 release.
2096 */
44e9909d
DS
2097 if (!zebrad.ribq->items->count)
2098 work_queue_add (zebrad.ribq, zebrad.mq);
e96f9203 2099
44e9909d 2100 rib_meta_queue_add (zebrad.mq, rn);
fc328ac9 2101
fc328ac9 2102 return;
4d38fdb4 2103}
2104
5110a0c6
SH
2105/* Create new meta queue.
2106 A destructor function doesn't seem to be necessary here.
2107 */
ef9b113e
SH
2108static struct meta_queue *
2109meta_queue_new (void)
e96f9203
DO
2110{
2111 struct meta_queue *new;
5110a0c6
SH
2112 unsigned i;
2113
2114 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
2115 assert(new);
e96f9203 2116
e96f9203 2117 for (i = 0; i < MQ_SIZE; i++)
5110a0c6
SH
2118 {
2119 new->subq[i] = list_new ();
2120 assert(new->subq[i]);
2121 }
2122
e96f9203
DO
2123 return new;
2124}
2125
4d38fdb4 2126/* initialise zebra rib work queue */
a1ac18c4 2127static void
4d38fdb4 2128rib_queue_init (struct zebra_t *zebra)
2129{
fc328ac9
SV
2130 assert (zebra);
2131
4d38fdb4 2132 if (! (zebra->ribq = work_queue_new (zebra->master,
6d691129 2133 "route_node processing")))
4d38fdb4 2134 {
6d691129 2135 zlog_err ("%s: could not initialise work queue!", __func__);
4d38fdb4 2136 return;
2137 }
2138
2139 /* fill in the work queue spec */
e96f9203 2140 zebra->ribq->spec.workfunc = &meta_queue_process;
4d38fdb4 2141 zebra->ribq->spec.errorfunc = NULL;
fb018d25 2142 zebra->ribq->spec.completion_func = &meta_queue_process_complete;
4d38fdb4 2143 /* XXX: TODO: These should be runtime configurable via vty */
2144 zebra->ribq->spec.max_retries = 3;
457eb9af 2145 zebra->ribq->spec.hold = rib_process_hold_time;
4d38fdb4 2146
e96f9203 2147 if (!(zebra->mq = meta_queue_new ()))
fc328ac9 2148 {
e96f9203 2149 zlog_err ("%s: could not initialise meta queue!", __func__);
fc328ac9
SV
2150 return;
2151 }
2152 return;
718e3744 2153}
2154
6d691129
PJ
2155/* RIB updates are processed via a queue of pointers to route_nodes.
2156 *
2157 * The queue length is bounded by the maximal size of the routing table,
2158 * as a route_node will not be requeued, if already queued.
2159 *
3c0755dc 2160 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
bcd548ff 2161 * state, or static_install_route (when an existing RIB is updated)
3c0755dc
PJ
2162 * and then submit route_node to queue for best-path selection later.
2163 * Order of add/delete state changes are preserved for any given RIB.
6d691129
PJ
2164 *
2165 * Deleted RIBs are reaped during best-path selection.
2166 *
2167 * rib_addnode
2168 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
3c0755dc
PJ
2169 * |-------->| | best RIB, if required
2170 * | |
2171 * static_install->|->rib_addqueue...... -> rib_process
2172 * | |
2173 * |-------->| |-> rib_unlink
6d691129
PJ
2174 * |-> set RIB_ENTRY_REMOVE |
2175 * rib_delnode (RIB freed)
2176 *
9fd92e3c
AS
2177 * The 'info' pointer of a route_node points to a rib_dest_t
2178 * ('dest'). Queueing state for a route_node is kept on the dest. The
2179 * dest is created on-demand by rib_link() and is kept around at least
2180 * as long as there are ribs hanging off it (@see rib_gc_dest()).
6d691129
PJ
2181 *
2182 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
2183 *
2184 * - route_nodes: refcounted by:
9fd92e3c
AS
2185 * - dest attached to route_node:
2186 * - managed by: rib_link/rib_gc_dest
6d691129
PJ
2187 * - route_node processing queue
2188 * - managed by: rib_addqueue, rib_process.
2189 *
2190 */
2191
718e3744 2192/* Add RIB to head of the route node. */
a1ac18c4 2193static void
2bf26d41 2194rib_link (struct route_node *rn, struct rib *rib, int process)
718e3744 2195{
2196 struct rib *head;
9fd92e3c 2197 rib_dest_t *dest;
7a4bb9c5 2198 afi_t afi;
8902474b 2199 const char *rmap_name;
9fd92e3c 2200
4d38fdb4 2201 assert (rib && rn);
2202
9fd92e3c
AS
2203 dest = rib_dest_from_rnode (rn);
2204 if (!dest)
6d691129 2205 {
41ec9222 2206 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
2263a412 2207 rnode_debug (rn, rib->vrf_id, "rn %p adding dest", rn);
9fd92e3c
AS
2208
2209 dest = XCALLOC (MTYPE_RIB_DEST, sizeof (rib_dest_t));
2210 route_lock_node (rn); /* rn route table reference */
2211 rn->info = dest;
2212 dest->rnode = rn;
2213 }
2214
2215 head = dest->routes;
2216 if (head)
2217 {
6d691129 2218 head->prev = rib;
6d691129 2219 }
718e3744 2220 rib->next = head;
9fd92e3c 2221 dest->routes = rib;
7a4bb9c5 2222
12f6fb97
DS
2223 afi = (rn->p.family == AF_INET) ? AFI_IP :
2224 (rn->p.family == AF_INET6) ? AFI_IP6 : AFI_MAX;
2225 if (is_zebra_import_table_enabled (afi, rib->table))
8902474b
DS
2226 {
2227 rmap_name = zebra_get_import_table_route_map (afi, rib->table);
2228 zebra_add_import_table_entry(rn, rib, rmap_name);
2229 }
7a4bb9c5 2230 else
12f6fb97 2231 if (process)
44e9909d 2232 rib_queue_add (rn);
718e3744 2233}
2234
a1ac18c4 2235static void
2bf26d41 2236rib_addnode (struct route_node *rn, struct rib *rib, int process)
718e3744 2237{
6d691129
PJ
2238 /* RIB node has been un-removed before route-node is processed.
2239 * route_node must hence already be on the queue for processing..
2240 */
2241 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2242 {
2263a412
DL
2243 if (IS_ZEBRA_DEBUG_RIB)
2244 rnode_debug (rn, rib->vrf_id, "rn %p, un-removed rib %p", rn, rib);
2245
6d691129
PJ
2246 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
2247 return;
2248 }
2bf26d41 2249 rib_link (rn, rib, process);
6d691129
PJ
2250}
2251
9fd92e3c
AS
2252/*
2253 * rib_unlink
2254 *
2255 * Detach a rib structure from a route_node.
2256 *
2257 * Note that a call to rib_unlink() should be followed by a call to
2258 * rib_gc_dest() at some point. This allows a rib_dest_t that is no
2259 * longer required to be deleted.
2260 */
6d691129
PJ
2261static void
2262rib_unlink (struct route_node *rn, struct rib *rib)
2263{
9fd92e3c 2264 rib_dest_t *dest;
6d691129 2265
4d38fdb4 2266 assert (rn && rib);
6d691129 2267
2263a412
DL
2268 if (IS_ZEBRA_DEBUG_RIB)
2269 rnode_debug (rn, rib->vrf_id, "rn %p, rib %p", rn, rib);
2270
9fd92e3c
AS
2271 dest = rib_dest_from_rnode (rn);
2272
718e3744 2273 if (rib->next)
2274 rib->next->prev = rib->prev;
6d691129 2275
718e3744 2276 if (rib->prev)
2277 rib->prev->next = rib->next;
2278 else
6d691129 2279 {
9fd92e3c 2280 dest->routes = rib->next;
6d691129
PJ
2281 }
2282
2283 /* free RIB and nexthops */
d82ae0de 2284 zebra_deregister_rnh_static_nexthops (rib->vrf_id, rib->nexthop, rn);
a399694f 2285 nexthops_free(rib->nexthop);
6d691129
PJ
2286 XFREE (MTYPE_RIB, rib);
2287
6d691129
PJ
2288}
2289
2290static void
2291rib_delnode (struct route_node *rn, struct rib *rib)
2292{
7a4bb9c5
DS
2293 afi_t afi;
2294
2263a412
DL
2295 if (IS_ZEBRA_DEBUG_RIB)
2296 rnode_debug (rn, rib->vrf_id, "rn %p, rib %p, removing", rn, rib);
6d691129 2297 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
7a4bb9c5 2298
12f6fb97
DS
2299 afi = (rn->p.family == AF_INET) ? AFI_IP :
2300 (rn->p.family == AF_INET6) ? AFI_IP6 : AFI_MAX;
2301 if (is_zebra_import_table_enabled (afi, rib->table))
7a4bb9c5 2302 {
12f6fb97 2303 zebra_del_import_table_entry(rn, rib);
7a4bb9c5 2304 /* Just clean up if non main table */
41ec9222 2305 if (IS_ZEBRA_DEBUG_RIB)
2306 {
2307 char buf[INET6_ADDRSTRLEN];
2308 if (IS_ZEBRA_DEBUG_RIB)
2309 {
2310 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
2311 zlog_debug ("%u:%s/%d: Freeing route rn %p, rib %p (type %d)",
2312 rib->vrf_id, buf, rn->p.prefixlen, rn, rib, rib->type);
2313 }
2314 }
2315
7a4bb9c5
DS
2316 rib_unlink(rn, rib);
2317 }
12f6fb97
DS
2318 else
2319 {
44e9909d 2320 rib_queue_add (rn);
12f6fb97 2321 }
718e3744 2322}
2323
2324int
7c8ff89e 2325rib_add_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
7514fb77 2326 struct in_addr *gate, struct in_addr *src,
78104b9b 2327 unsigned int ifindex, vrf_id_t vrf_id, u_int32_t table_id,
cddf391b 2328 u_int32_t metric, u_char distance, safi_t safi)
718e3744 2329{
2330 struct rib *rib;
2331 struct rib *same = NULL;
2332 struct route_table *table;
2333 struct route_node *rn;
2334 struct nexthop *nexthop;
2335
2336 /* Lookup table. */
ca46a78e 2337 table = zebra_vrf_table_with_table_id (AFI_IP, safi, vrf_id, table_id);
718e3744 2338 if (! table)
2339 return 0;
2340
2341 /* Make it sure prefixlen is applied to the prefix. */
2342 apply_mask_ipv4 (p);
2343
2344 /* Set default distance by route type. */
2345 if (distance == 0)
2346 {
837d16cc 2347 if ((unsigned)type >= array_size(route_info))
7052f228
DL
2348 distance = 150;
2349 else
2350 distance = route_info[type].distance;
718e3744 2351
2352 /* iBGP distance is 200. */
2353 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2354 distance = 200;
2355 }
2356
2357 /* Lookup route node.*/
2358 rn = route_node_get (table, (struct prefix *) p);
2359
2360 /* If same type of route are installed, treat it as a implicit
2361 withdraw. */
9fd92e3c 2362 RNODE_FOREACH_RIB (rn, rib)
718e3744 2363 {
6d691129
PJ
2364 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2365 continue;
2366
ebf1ead0 2367 if (rib->type != type)
2368 continue;
7c8ff89e
DS
2369 if (rib->instance != instance)
2370 continue;
7a4bb9c5 2371
ebf1ead0 2372 if (rib->type != ZEBRA_ROUTE_CONNECT)
4d38fdb4 2373 {
2374 same = rib;
2375 break;
2376 }
ebf1ead0 2377 /* Duplicate connected route comes in. */
2378 else if ((nexthop = rib->nexthop) &&
2379 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
6d691129
PJ
2380 nexthop->ifindex == ifindex &&
2381 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
ebf1ead0 2382 {
2383 rib->refcnt++;
2384 return 0 ;
2385 }
718e3744 2386 }
2387
2388 /* Allocate new rib structure. */
4d38fdb4 2389 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
718e3744 2390 rib->type = type;
7c8ff89e 2391 rib->instance = instance;
718e3744 2392 rib->distance = distance;
2393 rib->flags = flags;
2394 rib->metric = metric;
7a4bb9c5 2395 rib->table = table_id;
78104b9b 2396 rib->vrf_id = vrf_id;
718e3744 2397 rib->nexthop_num = 0;
2398 rib->uptime = time (NULL);
2399
2400 /* Nexthop settings. */
2401 if (gate)
2402 {
2403 if (ifindex)
a399694f 2404 rib_nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
718e3744 2405 else
a399694f 2406 rib_nexthop_ipv4_add (rib, gate, src);
718e3744 2407 }
2408 else
a399694f 2409 rib_nexthop_ifindex_add (rib, ifindex);
718e3744 2410
2411 /* If this route is kernel route, set FIB flag to the route. */
2412 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2413 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2414 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2415
2416 /* Link new rib to node.*/
dc95824a 2417 if (IS_ZEBRA_DEBUG_RIB)
41ec9222 2418 {
2419 char buf[INET6_ADDRSTRLEN];
2420 if (IS_ZEBRA_DEBUG_RIB)
2421 {
2422 inet_ntop (p->family, &p->prefix, buf, INET6_ADDRSTRLEN);
2423 zlog_debug ("%u:%s/%d: Inserting route rn %p, rib %p (type %d) "
2424 "existing %p",
2425 vrf_id, buf, p->prefixlen, rn, rib, rib->type, same);
2426 }
2427
2428 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
2429 rib_dump ((struct prefix *)p, rib);
2430 }
2bf26d41 2431 rib_addnode (rn, rib, 1);
4d38fdb4 2432
718e3744 2433 /* Free implicit route.*/
2434 if (same)
4d38fdb4 2435 rib_delnode (rn, same);
2436
2437 route_unlock_node (rn);
718e3744 2438 return 0;
2439}
2440
dc95824a
DO
2441/* This function dumps the contents of a given RIB entry into
2442 * standard debug log. Calling function name and IP prefix in
2443 * question are passed as 1st and 2nd arguments.
2444 */
2445
f7bf4153
DL
2446void _rib_dump (const char * func,
2447 union prefix46constptr pp, const struct rib * rib)
dc95824a 2448{
f7bf4153 2449 const struct prefix *p = pp.p;
4690c7d7 2450 char straddr[PREFIX2STR_BUFFER];
fa713d9e
CF
2451 struct nexthop *nexthop, *tnexthop;
2452 int recursing;
dc95824a 2453
78104b9b
FL
2454 zlog_debug ("%s: dumping RIB entry %p for %s vrf %u", func, rib,
2455 prefix2str(pp, straddr, sizeof(straddr)), rib->vrf_id);
dc95824a
DO
2456 zlog_debug
2457 (
7c8ff89e 2458 "%s: refcnt == %lu, uptime == %lu, type == %u, instance == %d, table == %d",
dc95824a
DO
2459 func,
2460 rib->refcnt,
d02c56cd 2461 (unsigned long) rib->uptime,
dc95824a 2462 rib->type,
7c8ff89e 2463 rib->instance,
dc95824a
DO
2464 rib->table
2465 );
2466 zlog_debug
2467 (
2468 "%s: metric == %u, distance == %u, flags == %u, status == %u",
2469 func,
2470 rib->metric,
2471 rib->distance,
2472 rib->flags,
2473 rib->status
2474 );
2475 zlog_debug
2476 (
2477 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
2478 func,
2479 rib->nexthop_num,
2480 rib->nexthop_active_num,
2481 rib->nexthop_fib_num
2482 );
fed643f4 2483
fa713d9e
CF
2484 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2485 {
fed643f4 2486 inet_ntop (p->family, &nexthop->gate, straddr, INET6_ADDRSTRLEN);
fa713d9e
CF
2487 zlog_debug
2488 (
2489 "%s: %s %s with flags %s%s%s",
2490 func,
2491 (recursing ? " NH" : "NH"),
2492 straddr,
2493 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
2494 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
2495 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
2496 );
2497 }
dc95824a
DO
2498 zlog_debug ("%s: dump complete", func);
2499}
2500
2501/* This is an exported helper to rtm_read() to dump the strange
2502 * RIB entry found by rib_lookup_ipv4_route()
2503 */
2504
12f6fb97 2505void rib_lookup_and_dump (struct prefix_ipv4 * p, vrf_id_t vrf_id)
dc95824a
DO
2506{
2507 struct route_table *table;
2508 struct route_node *rn;
2509 struct rib *rib;
2510 char prefix_buf[INET_ADDRSTRLEN];
2511
2512 /* Lookup table. */
12f6fb97 2513 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
dc95824a
DO
2514 if (! table)
2515 {
b72ede27 2516 zlog_err ("%s: zebra_vrf_table() returned NULL", __func__);
dc95824a
DO
2517 return;
2518 }
2519
2520 inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
2521 /* Scan the RIB table for exactly matching RIB entry. */
2522 rn = route_node_lookup (table, (struct prefix *) p);
2523
2524 /* No route for this prefix. */
2525 if (! rn)
2526 {
2527 zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
2528 return;
2529 }
2530
2531 /* Unlock node. */
2532 route_unlock_node (rn);
2533
2534 /* let's go */
9fd92e3c 2535 RNODE_FOREACH_RIB (rn, rib)
dc95824a
DO
2536 {
2537 zlog_debug
2538 (
2539 "%s: rn %p, rib %p: %s, %s",
2540 __func__,
2541 rn,
2542 rib,
2543 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
2544 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
2545 );
f7bf4153 2546 rib_dump (p, rib);
dc95824a
DO
2547 }
2548}
2549
20e5ff0a
DO
2550/* Check if requested address assignment will fail due to another
2551 * route being installed by zebra in FIB already. Take necessary
2552 * actions, if needed: remove such a route from FIB and deSELECT
2553 * corresponding RIB entry. Then put affected RN into RIBQ head.
2554 */
12f6fb97 2555void rib_lookup_and_pushup (struct prefix_ipv4 * p, vrf_id_t vrf_id)
20e5ff0a
DO
2556{
2557 struct route_table *table;
2558 struct route_node *rn;
2559 struct rib *rib;
2560 unsigned changed = 0;
2561
12f6fb97 2562 if (NULL == (table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id)))
20e5ff0a 2563 {
b72ede27 2564 zlog_err ("%s: zebra_vrf_table() returned NULL", __func__);
20e5ff0a
DO
2565 return;
2566 }
2567
2568 /* No matches would be the simplest case. */
2569 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
2570 return;
2571
2572 /* Unlock node. */
2573 route_unlock_node (rn);
2574
2575 /* Check all RIB entries. In case any changes have to be done, requeue
2576 * the RN into RIBQ head. If the routing message about the new connected
2577 * route (generated by the IP address we are going to assign very soon)
2578 * comes before the RIBQ is processed, the new RIB entry will join
2579 * RIBQ record already on head. This is necessary for proper revalidation
2580 * of the rest of the RIB.
2581 */
9fd92e3c 2582 RNODE_FOREACH_RIB (rn, rib)
20e5ff0a
DO
2583 {
2584 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
2585 ! RIB_SYSTEM_ROUTE (rib))
2586 {
2587 changed = 1;
2588 if (IS_ZEBRA_DEBUG_RIB)
2589 {
2590 char buf[INET_ADDRSTRLEN];
2591 inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
41ec9222 2592 zlog_debug ("%u:%s/%d: freeing way for connected prefix",
2593 rib->vrf_id, buf, p->prefixlen);
f7bf4153 2594 rib_dump (&rn->p, rib);
20e5ff0a
DO
2595 }
2596 rib_uninstall (rn, rib);
2597 }
2598 }
2599 if (changed)
44e9909d 2600 rib_queue_add (rn);
20e5ff0a
DO
2601}
2602
718e3744 2603int
cddf391b 2604rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
718e3744 2605{
2606 struct route_table *table;
2607 struct route_node *rn;
2608 struct rib *same;
2609 struct nexthop *nexthop;
04b02fda 2610 int ret = 0;
4d38fdb4 2611
718e3744 2612 /* Lookup table. */
ca46a78e 2613 table = zebra_vrf_table_with_table_id (AFI_IP, safi, rib->vrf_id, rib->table);
718e3744 2614 if (! table)
2615 return 0;
cddf391b 2616
718e3744 2617 /* Make it sure prefixlen is applied to the prefix. */
2618 apply_mask_ipv4 (p);
2619
2620 /* Set default distance by route type. */
2621 if (rib->distance == 0)
2622 {
2623 rib->distance = route_info[rib->type].distance;
2624
2625 /* iBGP distance is 200. */
2626 if (rib->type == ZEBRA_ROUTE_BGP
2627 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
2628 rib->distance = 200;
2629 }
2630
2631 /* Lookup route node.*/
2632 rn = route_node_get (table, (struct prefix *) p);
2633
2634 /* If same type of route are installed, treat it as a implicit
2635 withdraw. */
9fd92e3c 2636 RNODE_FOREACH_RIB (rn, same)
718e3744 2637 {
0b8c4f1d 2638 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
6d691129
PJ
2639 continue;
2640
7c8ff89e
DS
2641 if (same->type == rib->type && same->instance == rib->instance
2642 && same->table == rib->table
718e3744 2643 && same->type != ZEBRA_ROUTE_CONNECT)
4d38fdb4 2644 break;
718e3744 2645 }
4d38fdb4 2646
718e3744 2647 /* If this route is kernel route, set FIB flag to the route. */
2648 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
2649 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2650 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2651
2652 /* Link new rib to node.*/
41ec9222 2653 if (IS_ZEBRA_DEBUG_RIB)
2654 {
2655 char buf[INET6_ADDRSTRLEN];
2656 if (IS_ZEBRA_DEBUG_RIB)
2657 {
2658 inet_ntop (p->family, &p->prefix, buf, INET6_ADDRSTRLEN);
2659 zlog_debug ("%u:%s/%d: Inserting route rn %p, rib %p (type %d) "
2660 "existing %p",
2661 rib->vrf_id, buf, p->prefixlen, rn, rib, rib->type, same);
2662 }
2663
2664 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
2665 rib_dump ((struct prefix *)p, rib);
2666 }
2bf26d41 2667 rib_addnode (rn, rib, 1);
04b02fda 2668 ret = 1;
718e3744 2669
718e3744 2670 /* Free implicit route.*/
2671 if (same)
dc95824a 2672 {
41ec9222 2673 rib_delnode (rn, same);
2674 ret = -1;
dc95824a 2675 }
4d38fdb4 2676
2677 route_unlock_node (rn);
04b02fda 2678 return ret;
718e3744 2679}
2680
ebf1ead0 2681/* XXX factor with rib_delete_ipv6 */
718e3744 2682int
7c8ff89e 2683rib_delete_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
78104b9b 2684 struct in_addr *gate, unsigned int ifindex, vrf_id_t vrf_id,
7a4bb9c5 2685 u_int32_t table_id, safi_t safi)
718e3744 2686{
2687 struct route_table *table;
2688 struct route_node *rn;
2689 struct rib *rib;
2690 struct rib *fib = NULL;
2691 struct rib *same = NULL;
fa713d9e
CF
2692 struct nexthop *nexthop, *tnexthop;
2693 int recursing;
4690c7d7 2694 char buf1[PREFIX2STR_BUFFER];
41ec9222 2695 char buf2[INET6_ADDRSTRLEN];
718e3744 2696
2697 /* Lookup table. */
ca46a78e 2698 table = zebra_vrf_table_with_table_id (AFI_IP, safi, vrf_id, table_id);
718e3744 2699 if (! table)
2700 return 0;
2701
2702 /* Apply mask. */
2703 apply_mask_ipv4 (p);
2704
2705 /* Lookup route node. */
2706 rn = route_node_lookup (table, (struct prefix *) p);
2707 if (! rn)
2708 {
41ec9222 2709 if (IS_ZEBRA_DEBUG_RIB)
2710 zlog_debug ("%u:%s/%d: doesn't exist in rib",
2711 vrf_id, inet_ntop (p->family, &p->prefix, buf1, INET6_ADDRSTRLEN),
2712 p->prefixlen);
718e3744 2713 return ZEBRA_ERR_RTNOEXIST;
2714 }
2715
2716 /* Lookup same type route. */
9fd92e3c 2717 RNODE_FOREACH_RIB (rn, rib)
718e3744 2718 {
6d691129
PJ
2719 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2720 continue;
2721
718e3744 2722 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2723 fib = rib;
2724
ebf1ead0 2725 if (rib->type != type)
2726 continue;
7c8ff89e
DS
2727 if (rib->instance != instance)
2728 continue;
ebf1ead0 2729 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
4f1735fd 2730 nexthop->type == NEXTHOP_TYPE_IFINDEX)
718e3744 2731 {
4f1735fd
MF
2732 if (nexthop->ifindex != ifindex)
2733 continue;
ebf1ead0 2734 if (rib->refcnt)
718e3744 2735 {
ebf1ead0 2736 rib->refcnt--;
2737 route_unlock_node (rn);
2738 route_unlock_node (rn);
2739 return 0;
718e3744 2740 }
ebf1ead0 2741 same = rib;
2742 break;
718e3744 2743 }
ebf1ead0 2744 /* Make sure that the route found has the same gateway. */
fa713d9e 2745 else
5ec90d28 2746 {
fa713d9e
CF
2747 if (gate == NULL)
2748 {
2749 same = rib;
2750 break;
2751 }
2752 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2753 if (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate))
2754 {
2755 same = rib;
2756 break;
2757 }
2758 if (same)
2759 break;
2760 }
718e3744 2761 }
718e3744 2762 /* If same type of route can't be found and this message is from
2763 kernel. */
2764 if (! same)
2765 {
2037f143
DS
2766 if (fib && type == ZEBRA_ROUTE_KERNEL &&
2767 CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE))
2768 {
41ec9222 2769 if (IS_ZEBRA_DEBUG_RIB)
2037f143 2770 {
41ec9222 2771 zlog_debug ("%u:%s/%d: rn %p, rib %p (type %d) was deleted "
2772 "from kernel, adding",
2773 vrf_id, inet_ntop (p->family, &p->prefix, buf1, INET6_ADDRSTRLEN),
2774 p->prefixlen, rn, fib, fib->type);
2037f143 2775 }
6baf7bb8
DS
2776 if (allow_delete)
2777 {
2778 /* Unset flags. */
2779 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2780 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2781
2782 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2783 }
2784 else
2785 {
2786 /* This means someone else, other than Zebra, has deleted
2787 * a Zebra router from the kernel. We will add it back */
2788 rib_install_kernel(rn, fib, 0);
2789 }
2037f143 2790 }
718e3744 2791 else
2792 {
41ec9222 2793 if (IS_ZEBRA_DEBUG_RIB)
718e3744 2794 {
2795 if (gate)
41ec9222 2796 zlog_debug ("%u:%s: via %s ifindex %d type %d "
78104b9b 2797 "doesn't exist in rib",
41ec9222 2798 vrf_id, prefix2str (p, buf1, sizeof(buf1)),
81cce018 2799 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
718e3744 2800 ifindex,
2801 type);
2802 else
41ec9222 2803 zlog_debug ("%u:%s: ifindex %d type %d doesn't exist in rib",
2804 vrf_id, prefix2str (p, buf1, sizeof(buf1)),
718e3744 2805 ifindex,
2806 type);
2807 }
2808 route_unlock_node (rn);
2809 return ZEBRA_ERR_RTNOEXIST;
2810 }
2811 }
4d38fdb4 2812
718e3744 2813 if (same)
4d38fdb4 2814 rib_delnode (rn, same);
2815
718e3744 2816 route_unlock_node (rn);
718e3744 2817 return 0;
2818}
6b0655a2 2819
718e3744 2820/* Install static route into rib. */
fb148af4 2821void
bcd548ff 2822static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si)
718e3744 2823{
2824 struct rib *rib;
2825 struct route_node *rn;
2826 struct route_table *table;
6e26278c 2827 struct prefix nh_p;
718e3744 2828
2829 /* Lookup table. */
be5e48ab 2830 table = zebra_vrf_table (afi, safi, si->vrf_id);
718e3744 2831 if (! table)
2832 return;
2833
2834 /* Lookup existing route */
2835 rn = route_node_get (table, p);
9fd92e3c 2836 RNODE_FOREACH_RIB (rn, rib)
6d691129
PJ
2837 {
2838 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2839 continue;
2840
2841 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2842 break;
2843 }
718e3744 2844
2845 if (rib)
2846 {
0d9551dc
DS
2847 /* if tag value changed , update old value in RIB */
2848 if (rib->tag != si->tag)
2849 rib->tag = si->tag;
2850
718e3744 2851 /* Same distance static route is there. Update it with new
2852 nexthop. */
718e3744 2853 route_unlock_node (rn);
718e3744 2854 switch (si->type)
7021c425 2855 {
bcd548ff 2856 case STATIC_IPV4_GATEWAY:
a399694f 2857 rib_nexthop_ipv4_add (rib, &si->addr.ipv4, NULL);
bcd548ff
DS
2858 nh_p.family = AF_INET;
2859 nh_p.prefixlen = IPV4_MAX_BITLEN;
2860 nh_p.u.prefix4 = si->addr.ipv4;
d82ae0de 2861 zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn);
bcd548ff 2862 break;
ba779241
DS
2863 case STATIC_IFINDEX:
2864 rib_nexthop_ifindex_add (rib, si->ifindex);
bcd548ff
DS
2865 break;
2866 case STATIC_IPV4_BLACKHOLE:
a399694f 2867 rib_nexthop_blackhole_add (rib);
bcd548ff
DS
2868 break;
2869 case STATIC_IPV6_GATEWAY:
a399694f 2870 rib_nexthop_ipv6_add (rib, &si->addr.ipv6);
bcd548ff
DS
2871 nh_p.family = AF_INET6;
2872 nh_p.prefixlen = IPV6_MAX_BITLEN;
2873 nh_p.u.prefix6 = si->addr.ipv6;
d82ae0de 2874 zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn);
bcd548ff 2875 break;
ba779241
DS
2876 case STATIC_IPV6_GATEWAY_IFINDEX:
2877 rib_nexthop_ipv6_ifindex_add (rib, &si->addr.ipv6, si->ifindex);
bcd548ff 2878 break;
4d38fdb4 2879 }
41ec9222 2880
2881 if (IS_ZEBRA_DEBUG_RIB)
2882 {
2883 char buf[INET6_ADDRSTRLEN];
2884 if (IS_ZEBRA_DEBUG_RIB)
2885 {
2886 inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN);
2887 zlog_debug ("%u:%s/%d: Modifying route rn %p, rib %p (type %d)",
2888 si->vrf_id, buf, p->prefixlen, rn, rib, rib->type);
2889 }
2890 }
2bf26d41 2891 /* Schedule route for processing or invoke NHT, as appropriate. */
2892 if (si->type == STATIC_IPV4_GATEWAY ||
2893 si->type == STATIC_IPV6_GATEWAY)
2894 zebra_evaluate_rnh(si->vrf_id, nh_p.family, 1, RNH_NEXTHOP_TYPE, &nh_p);
2895 else
44e9909d 2896 rib_queue_add (rn);
718e3744 2897 }
2898 else
2899 {
2900 /* This is new static route. */
4d38fdb4 2901 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2902
718e3744 2903 rib->type = ZEBRA_ROUTE_STATIC;
7c8ff89e 2904 rib->instance = 0;
718e3744 2905 rib->distance = si->distance;
2906 rib->metric = 0;
8f527c5e 2907 rib->vrf_id = si->vrf_id;
12f6fb97 2908 rib->table = si->vrf_id ? (zebra_vrf_lookup(si->vrf_id))->table_id : zebrad.rtm_table_default;
718e3744 2909 rib->nexthop_num = 0;
0d9551dc 2910 rib->tag = si->tag;
718e3744 2911
2912 switch (si->type)
7021c425 2913 {
bcd548ff 2914 case STATIC_IPV4_GATEWAY:
a399694f 2915 rib_nexthop_ipv4_add (rib, &si->addr.ipv4, NULL);
bcd548ff
DS
2916 nh_p.family = AF_INET;
2917 nh_p.prefixlen = IPV4_MAX_BITLEN;
2918 nh_p.u.prefix4 = si->addr.ipv4;
d82ae0de 2919 zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn);
bcd548ff 2920 break;
ba779241
DS
2921 case STATIC_IFINDEX:
2922 rib_nexthop_ifindex_add (rib, si->ifindex);
bcd548ff
DS
2923 break;
2924 case STATIC_IPV4_BLACKHOLE:
a399694f 2925 rib_nexthop_blackhole_add (rib);
bcd548ff
DS
2926 break;
2927 case STATIC_IPV6_GATEWAY:
a399694f 2928 rib_nexthop_ipv6_add (rib, &si->addr.ipv6);
bcd548ff
DS
2929 nh_p.family = AF_INET6;
2930 nh_p.prefixlen = IPV6_MAX_BITLEN;
2931 nh_p.u.prefix6 = si->addr.ipv6;
d82ae0de 2932 zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn);
bcd548ff 2933 break;
ba779241
DS
2934 case STATIC_IPV6_GATEWAY_IFINDEX:
2935 rib_nexthop_ipv6_ifindex_add (rib, &si->addr.ipv6, si->ifindex);
bcd548ff 2936 break;
7021c425 2937 }
718e3744 2938
81dfcaa2 2939 /* Save the flags of this static routes (reject, blackhole) */
2940 rib->flags = si->flags;
2941
41ec9222 2942 if (IS_ZEBRA_DEBUG_RIB)
2943 {
2944 char buf[INET6_ADDRSTRLEN];
2945 if (IS_ZEBRA_DEBUG_RIB)
2946 {
2947 inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN);
2948 zlog_debug ("%u:%s/%d: Inserting route rn %p, rib %p (type %d)",
2949 si->vrf_id, buf, p->prefixlen, rn, rib, rib->type);
2950 }
2951 }
2bf26d41 2952 /* Link this rib to the tree. Schedule for processing or invoke NHT,
2953 * as appropriate.
2954 */
2955 if (si->type == STATIC_IPV4_GATEWAY ||
2956 si->type == STATIC_IPV6_GATEWAY)
2957 {
2958 rib_addnode (rn, rib, 0);
2959 zebra_evaluate_rnh(si->vrf_id, nh_p.family, 1, RNH_NEXTHOP_TYPE, &nh_p);
2960 }
2961 else
2962 rib_addnode (rn, rib, 1);
718e3744 2963 }
2964}
2965
a1ac18c4 2966static int
f2b49ed0 2967static_nexthop_same (struct nexthop *nexthop, struct static_route *si)
718e3744 2968{
2969 if (nexthop->type == NEXTHOP_TYPE_IPV4
2970 && si->type == STATIC_IPV4_GATEWAY
c0551cbb 2971 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->addr.ipv4))
718e3744 2972 return 1;
ba779241
DS
2973 if (nexthop->type == NEXTHOP_TYPE_IFINDEX
2974 && si->type == STATIC_IFINDEX
2975 && nexthop->ifindex == si->ifindex)
718e3744 2976 return 1;
595db7f1 2977 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2978 && si->type == STATIC_IPV4_BLACKHOLE)
2979 return 1;
f2b49ed0
DS
2980 if (nexthop->type == NEXTHOP_TYPE_IPV6
2981 && si->type == STATIC_IPV6_GATEWAY
2982 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6))
2983 return 1;
ba779241
DS
2984 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX
2985 && si->type == STATIC_IPV6_GATEWAY_IFINDEX
f2b49ed0 2986 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6)
ba779241 2987 && nexthop->ifindex == si->ifindex)
f2b49ed0 2988 return 1;
e8e1946e 2989 return 0;
718e3744 2990}
2991
2992/* Uninstall static route from RIB. */
fb148af4 2993void
b8a1effa 2994static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si)
718e3744 2995{
2996 struct route_node *rn;
2997 struct rib *rib;
2998 struct nexthop *nexthop;
2999 struct route_table *table;
6e26278c 3000 struct prefix nh_p;
718e3744 3001
3002 /* Lookup table. */
be5e48ab 3003 table = zebra_vrf_table (afi, safi, si->vrf_id);
718e3744 3004 if (! table)
3005 return;
4d38fdb4 3006
718e3744 3007 /* Lookup existing route with type and distance. */
3008 rn = route_node_lookup (table, p);
3009 if (! rn)
3010 return;
3011
9fd92e3c 3012 RNODE_FOREACH_RIB (rn, rib)
6d691129
PJ
3013 {
3014 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3015 continue;
3016
0d9551dc
DS
3017 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance &&
3018 rib->tag == si->tag)
6d691129
PJ
3019 break;
3020 }
718e3744 3021
3022 if (! rib)
3023 {
3024 route_unlock_node (rn);
3025 return;
3026 }
3027
3028 /* Lookup nexthop. */
3029 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
f2b49ed0 3030 if (static_nexthop_same (nexthop, si))
718e3744 3031 break;
3032
3033 /* Can't find nexthop. */
3034 if (! nexthop)
3035 {
3036 route_unlock_node (rn);
3037 return;
3038 }
3039
3040 /* Check nexthop. */
3041 if (rib->nexthop_num == 1)
6d691129 3042 rib_delnode (rn, rib);
718e3744 3043 else
3044 {
94ad353d
DS
3045 /* Mark this nexthop as inactive and reinstall the route. Then, delete
3046 * the nexthop. There is no need to re-evaluate the route for this
3047 * scenario.
3048 */
41ec9222 3049 if (IS_ZEBRA_DEBUG_RIB)
3050 {
3051 char buf[INET6_ADDRSTRLEN];
3052 if (IS_ZEBRA_DEBUG_RIB)
3053 {
3054 inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN);
3055 zlog_debug ("%u:%s/%d: Modifying route rn %p, rib %p (type %d)",
3056 si->vrf_id, buf, p->prefixlen, rn, rib, rib->type);
3057 }
3058 }
94ad353d 3059 UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
6baeb988 3060 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
94ad353d 3061 {
dccc5225 3062 /* If there are other active nexthops, do an update. */
3063 if (rib->nexthop_active_num > 1)
3064 {
3065 rib_install_kernel (rn, rib, 1);
3066 redistribute_update (&rn->p, rib, NULL);
3067 }
3068 else
3069 {
3070 redistribute_delete (&rn->p, rib);
3071 rib_uninstall_kernel (rn, rib);
3072 }
94ad353d 3073 }
6e26278c 3074
b8a1effa
DS
3075 if (afi == AFI_IP)
3076 {
3077 /* Delete the nexthop and dereg from NHT */
3078 nh_p.family = AF_INET;
3079 nh_p.prefixlen = IPV4_MAX_BITLEN;
3080 nh_p.u.prefix4 = nexthop->gate.ipv4;
3081 }
3082 else
3083 {
3084 nh_p.family = AF_INET6;
3085 nh_p.prefixlen = IPV6_MAX_BITLEN;
3086 nh_p.u.prefix6 = nexthop->gate.ipv6;
3087 }
a399694f 3088 rib_nexthop_delete (rib, nexthop);
d82ae0de 3089 zebra_deregister_rnh_static_nh(si->vrf_id, &nh_p, rn);
a399694f 3090 nexthop_free (nexthop);
718e3744 3091 }
718e3744 3092 /* Unlock node. */
3093 route_unlock_node (rn);
3094}
3095
718e3744 3096int
b78a80d7 3097static_add_ipv4 (safi_t safi, struct prefix *p, struct in_addr *gate, unsigned int ifindex,
a3d21ef3
DS
3098 const char *ifname, u_char flags, u_short tag,
3099 u_char distance, struct zebra_vrf *zvrf)
718e3744 3100{
3101 u_char type = 0;
3102 struct route_node *rn;
c0551cbb
DS
3103 struct static_route *si;
3104 struct static_route *pp;
3105 struct static_route *cp;
3106 struct static_route *update = NULL;
b78a80d7 3107 struct route_table *stable = zvrf->stable[AFI_IP][safi];
718e3744 3108
718e3744 3109 if (! stable)
3110 return -1;
3111
3112 /* Lookup static route prefix. */
3113 rn = route_node_get (stable, p);
3114
3115 /* Make flags. */
3116 if (gate)
3117 type = STATIC_IPV4_GATEWAY;
ba779241
DS
3118 else if (ifindex)
3119 type = STATIC_IFINDEX;
595db7f1 3120 else
3121 type = STATIC_IPV4_BLACKHOLE;
718e3744 3122
3123 /* Do nothing if there is a same static route. */
3124 for (si = rn->info; si; si = si->next)
3125 {
3126 if (type == si->type
c0551cbb 3127 && (! gate || IPV4_ADDR_SAME (gate, &si->addr.ipv4))
ba779241 3128 && (! ifindex || ifindex == si->ifindex))
718e3744 3129 {
0d9551dc 3130 if ((distance == si->distance) && (tag == si->tag))
718e3744 3131 {
3132 route_unlock_node (rn);
3133 return 0;
3134 }
3135 else
3136 update = si;
3137 }
3138 }
3139
0d9551dc 3140 /* Distance or tag changed. */
718e3744 3141 if (update)
b78a80d7 3142 static_delete_ipv4 (safi, p, gate, ifindex, update->tag, update->distance, zvrf);
718e3744 3143
3144 /* Make new static route structure. */
c0551cbb 3145 si = XCALLOC (MTYPE_STATIC_ROUTE, sizeof (struct static_route));
718e3744 3146
3147 si->type = type;
3148 si->distance = distance;
81dfcaa2 3149 si->flags = flags;
0d9551dc 3150 si->tag = tag;
b9f1114e 3151 si->vrf_id = zvrf->vrf_id;
ba779241 3152 si->ifindex = ifindex;
fb148af4 3153 if (si->ifindex)
a3d21ef3 3154 strcpy(si->ifname, ifname);
718e3744 3155
3156 if (gate)
c0551cbb 3157 si->addr.ipv4 = *gate;
718e3744 3158
3159 /* Add new static route information to the tree with sort by
3160 distance value and gateway address. */
3161 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
3162 {
3163 if (si->distance < cp->distance)
3164 break;
3165 if (si->distance > cp->distance)
3166 continue;
3167 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
3168 {
c0551cbb 3169 if (ntohl (si->addr.ipv4.s_addr) < ntohl (cp->addr.ipv4.s_addr))
718e3744 3170 break;
c0551cbb 3171 if (ntohl (si->addr.ipv4.s_addr) > ntohl (cp->addr.ipv4.s_addr))
718e3744 3172 continue;
3173 }
3174 }
3175
3176 /* Make linked list. */
3177 if (pp)
3178 pp->next = si;
3179 else
3180 rn->info = si;
3181 if (cp)
3182 cp->prev = si;
3183 si->prev = pp;
3184 si->next = cp;
3185
3186 /* Install into rib. */
b78a80d7 3187 static_install_route (AFI_IP, safi, p, si);
718e3744 3188
3189 return 1;
3190}
3191
718e3744 3192int
b78a80d7 3193static_delete_ipv4 (safi_t safi, struct prefix *p, struct in_addr *gate, unsigned int ifindex,
b9f1114e 3194 u_short tag, u_char distance, struct zebra_vrf *zvrf)
718e3744 3195{
3196 u_char type = 0;
3197 struct route_node *rn;
c0551cbb 3198 struct static_route *si;
718e3744 3199 struct route_table *stable;
3200
3201 /* Lookup table. */
b78a80d7 3202 stable = zebra_vrf_static_table (AFI_IP, safi, zvrf);
718e3744 3203 if (! stable)
3204 return -1;
3205
3206 /* Lookup static route prefix. */
3207 rn = route_node_lookup (stable, p);
3208 if (! rn)
3209 return 0;
3210
3211 /* Make flags. */
3212 if (gate)
3213 type = STATIC_IPV4_GATEWAY;
ba779241
DS
3214 else if (ifindex)
3215 type = STATIC_IFINDEX;
595db7f1 3216 else
3217 type = STATIC_IPV4_BLACKHOLE;
718e3744 3218
3219 /* Find same static route is the tree */
3220 for (si = rn->info; si; si = si->next)
3221 if (type == si->type
c0551cbb 3222 && (! gate || IPV4_ADDR_SAME (gate, &si->addr.ipv4))
ba779241 3223 && (! ifindex || ifindex == si->ifindex)
0d9551dc 3224 && (! tag || (tag == si->tag)))
718e3744 3225 break;
3226
3227 /* Can't find static route. */
3228 if (! si)
3229 {
3230 route_unlock_node (rn);
3231 return 0;
3232 }
3233
3234 /* Install into rib. */
b78a80d7 3235 static_uninstall_route (AFI_IP, safi, p, si);
718e3744 3236
3237 /* Unlink static route from linked list. */
3238 if (si->prev)
3239 si->prev->next = si->next;
3240 else
3241 rn->info = si->next;
3242 if (si->next)
3243 si->next->prev = si->prev;
143a385f 3244 route_unlock_node (rn);
718e3744 3245
3246 /* Free static route configuration. */
c0551cbb 3247 XFREE (MTYPE_STATIC_ROUTE, si);
718e3744 3248
143a385f 3249 route_unlock_node (rn);
3250
718e3744 3251 return 1;
3252}
3253
718e3744 3254int
7c8ff89e 3255rib_add_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
78104b9b
FL
3256 struct in6_addr *gate, unsigned int ifindex, vrf_id_t vrf_id,
3257 u_int32_t table_id, u_int32_t metric, u_char distance, safi_t safi)
718e3744 3258{
3259 struct rib *rib;
3260 struct rib *same = NULL;
3261 struct route_table *table;
3262 struct route_node *rn;
3263 struct nexthop *nexthop;
3264
718e3744 3265 /* Lookup table. */
ca46a78e 3266 table = zebra_vrf_table_with_table_id (AFI_IP6, safi, vrf_id, table_id);
718e3744 3267 if (! table)
3268 return 0;
3269
3270 /* Make sure mask is applied. */
3271 apply_mask_ipv6 (p);
3272
3273 /* Set default distance by route type. */
be61c4eb 3274 if (!distance)
3275 distance = route_info[type].distance;
718e3744 3276
3277 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
3278 distance = 200;
3279
718e3744 3280 /* Lookup route node.*/
3281 rn = route_node_get (table, (struct prefix *) p);
3282
3283 /* If same type of route are installed, treat it as a implicit
3284 withdraw. */
9fd92e3c 3285 RNODE_FOREACH_RIB (rn, rib)
718e3744 3286 {
6d691129
PJ
3287 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3288 continue;
3289
ebf1ead0 3290 if (rib->type != type)
3291 continue;
7c8ff89e
DS
3292 if (rib->instance != instance)
3293 continue;
ebf1ead0 3294 if (rib->type != ZEBRA_ROUTE_CONNECT)
718e3744 3295 {
3296 same = rib;
718e3744 3297 break;
3298 }
ebf1ead0 3299 else if ((nexthop = rib->nexthop) &&
3300 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
3301 nexthop->ifindex == ifindex)
3302 {
3303 rib->refcnt++;
3304 return 0;
3305 }
718e3744 3306 }
3307
3308 /* Allocate new rib structure. */
4d38fdb4 3309 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
3310
718e3744 3311 rib->type = type;
7c8ff89e 3312 rib->instance = instance;
718e3744 3313 rib->distance = distance;
3314 rib->flags = flags;
3315 rib->metric = metric;
7a4bb9c5 3316 rib->table = table_id;
78104b9b 3317 rib->vrf_id = vrf_id;
718e3744 3318 rib->nexthop_num = 0;
3319 rib->uptime = time (NULL);
3320
3321 /* Nexthop settings. */
3322 if (gate)
3323 {
3324 if (ifindex)
a399694f 3325 rib_nexthop_ipv6_ifindex_add (rib, gate, ifindex);
718e3744 3326 else
a399694f 3327 rib_nexthop_ipv6_add (rib, gate);
718e3744 3328 }
3329 else
a399694f 3330 rib_nexthop_ifindex_add (rib, ifindex);
718e3744 3331
3332 /* If this route is kernel route, set FIB flag to the route. */
3333 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
3334 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
3335 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
3336
3337 /* Link new rib to node.*/
fed643f4 3338 if (IS_ZEBRA_DEBUG_RIB)
41ec9222 3339 {
3340 char buf[INET6_ADDRSTRLEN];
3341 if (IS_ZEBRA_DEBUG_RIB)
3342 {
3343 inet_ntop (p->family, &p->prefix, buf, INET6_ADDRSTRLEN);
3344 zlog_debug ("%u:%s/%d: Inserting route rn %p, rib %p (type %d) "
3345 "existing %p",
3346 vrf_id, buf, p->prefixlen, rn, rib, rib->type, same);
3347 }
3348
3349 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
3350 rib_dump ((struct prefix *)p, rib);
3351 }
2bf26d41 3352 rib_addnode (rn, rib, 1);
718e3744 3353
718e3744 3354 /* Free implicit route.*/
3355 if (same)
4d38fdb4 3356 rib_delnode (rn, same);
3357
3358 route_unlock_node (rn);
718e3744 3359 return 0;
3360}
3361
41fc2714 3362int
8a92a8a0 3363rib_add_ipv6_multipath (struct prefix *p, struct rib *rib, safi_t safi,
41fc2714
DS
3364 unsigned long ifindex)
3365{
3366 struct route_table *table;
3367 struct route_node *rn;
3368 struct rib *same = NULL;
3369 struct nexthop *nexthop;
3370 int ret = 0;
154caaed 3371 int family;
3372
3373 if (!rib)
3374 return 0;
41fc2714 3375
8a92a8a0 3376 if (p->family == AF_INET)
154caaed 3377 family = AFI_IP;
3378 else
3379 family = AFI_IP6;
8a92a8a0 3380
154caaed 3381 /* Lookup table. */
3382 table = zebra_vrf_table_with_table_id (family, safi, rib->vrf_id, rib->table);
3383 if (! table)
3384 return 0;
3385
3386 if (p->family == AF_INET)
3387 {
8a92a8a0 3388 /* Make it sure prefixlen is applied to the prefix. */
88177fe3 3389 apply_mask_ipv4 ((struct prefix_ipv4 *)p);
7a4bb9c5
DS
3390 }
3391 else
3392 {
8a92a8a0 3393 /* Make sure mask is applied. */
88177fe3 3394 apply_mask_ipv6 ((struct prefix_ipv6 *)p);
8a92a8a0 3395 }
41fc2714
DS
3396
3397 /* Set default distance by route type. */
3398 if (rib->distance == 0)
3399 {
3400 rib->distance = route_info[rib->type].distance;
3401
3402 /* iBGP distance is 200. */
3403 if (rib->type == ZEBRA_ROUTE_BGP
3404 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
3405 rib->distance = 200;
3406 }
3407
3408 /* Lookup route node.*/
3409 rn = route_node_get (table, (struct prefix *) p);
3410
3411 /* If same type of route are installed, treat it as a implicit
3412 withdraw. */
3413 RNODE_FOREACH_RIB (rn, same) {
3414 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED)) {
3415 continue;
3416 }
3417 if (same->type != rib->type) {
3418 continue;
3419 }
3420
7c8ff89e
DS
3421 if (same->instance != rib->instance) {
3422 continue;
3423 }
3424
41fc2714
DS
3425 if (same->table != rib->table) {
3426 continue;
3427 }
3428 if (same->type != ZEBRA_ROUTE_CONNECT) {
3429 break;
3430 }
3431 else if ((nexthop = same->nexthop) &&
3432 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
3433 nexthop->ifindex == ifindex) {
3434 same->refcnt++;
3435 return 0;
3436 }
3437 }
3438
3439 /* If this route is kernel route, set FIB flag to the route. */
3440 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT) {
3441 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) {
3442 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
3443 }
3444 }
3445
3446 /* Link new rib to node.*/
41ec9222 3447 if (IS_ZEBRA_DEBUG_RIB)
3448 {
3449 char buf[INET6_ADDRSTRLEN];
3450 if (IS_ZEBRA_DEBUG_RIB)
3451 {
3452 inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN);
3453 zlog_debug ("%u:%s/%d: Inserting route rn %p, rib %p (type %d) "
3454 "existing %p",
3455 rib->vrf_id, buf, p->prefixlen, rn, rib, rib->type, same);
3456 }
3457
3458 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
3459 rib_dump ((struct prefix *)p, rib);
3460 }
2bf26d41 3461 rib_addnode (rn, rib, 1);
41fc2714 3462 ret = 1;
41ec9222 3463
41fc2714
DS
3464 /* Free implicit route.*/
3465 if (same)
41fc2714 3466 {
41ec9222 3467 rib_delnode (rn, same);
3468 ret = -1;
41fc2714 3469 }
41fc2714
DS
3470
3471 route_unlock_node (rn);
3472 return ret;
3473}
3474
ebf1ead0 3475/* XXX factor with rib_delete_ipv6 */
12f6fb97 3476
718e3744 3477int
7c8ff89e 3478rib_delete_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
78104b9b
FL
3479 struct in6_addr *gate, unsigned int ifindex, vrf_id_t vrf_id,
3480 u_int32_t table_id, safi_t safi)
718e3744 3481{
3482 struct route_table *table;
3483 struct route_node *rn;
3484 struct rib *rib;
3485 struct rib *fib = NULL;
3486 struct rib *same = NULL;
fa713d9e
CF
3487 struct nexthop *nexthop, *tnexthop;
3488 int recursing;
4690c7d7 3489 char buf1[PREFIX2STR_BUFFER];
81cce018 3490 char buf2[INET6_ADDRSTRLEN];
718e3744 3491
3492 /* Apply mask. */
3493 apply_mask_ipv6 (p);
3494
3495 /* Lookup table. */
ca46a78e 3496 table = zebra_vrf_table_with_table_id (AFI_IP6, safi, vrf_id, table_id);
718e3744 3497 if (! table)
3498 return 0;
4d38fdb4 3499
718e3744 3500 /* Lookup route node. */
3501 rn = route_node_lookup (table, (struct prefix *) p);
3502 if (! rn)
3503 {
41ec9222 3504 if (IS_ZEBRA_DEBUG_RIB)
3505 zlog_debug ("%u:%s/%d: doesn't exist in rib",
3506 vrf_id, inet_ntop (p->family, &p->prefix, buf1, INET6_ADDRSTRLEN),
3507 p->prefixlen);
718e3744 3508 return ZEBRA_ERR_RTNOEXIST;
3509 }
3510
3511 /* Lookup same type route. */
9fd92e3c 3512 RNODE_FOREACH_RIB (rn, rib)
718e3744 3513 {
6d691129
PJ
3514 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
3515 continue;
3516
718e3744 3517 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
3518 fib = rib;
3519
ebf1ead0 3520 if (rib->type != type)
3521 continue;
7c8ff89e
DS
3522 if (rib->instance != instance)
3523 continue;
ebf1ead0 3524 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
4f1735fd 3525 nexthop->type == NEXTHOP_TYPE_IFINDEX)
718e3744 3526 {
4f1735fd
MF
3527 if (nexthop->ifindex != ifindex)
3528 continue;
ebf1ead0 3529 if (rib->refcnt)
718e3744 3530 {
ebf1ead0 3531 rib->refcnt--;
3532 route_unlock_node (rn);
3533 route_unlock_node (rn);
3534 return 0;
718e3744 3535 }
ebf1ead0 3536 same = rib;
3537 break;
718e3744 3538 }
ebf1ead0 3539 /* Make sure that the route found has the same gateway. */
fa713d9e
CF
3540 else
3541 {
3542 if (gate == NULL)
3543 {
3544 same = rib;
3545 break;
3546 }
3547 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
3548 if (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate))
3549 {
3550 same = rib;
3551 break;
3552 }
3553 if (same)
3554 break;
3555 }
718e3744 3556 }
3557
3558 /* If same type of route can't be found and this message is from
3559 kernel. */
3560 if (! same)
3561 {
2037f143
DS
3562 if (fib && type == ZEBRA_ROUTE_KERNEL &&
3563 CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE))
3564 {
41ec9222 3565 if (IS_ZEBRA_DEBUG_RIB)
3566 zlog_debug ("%u:%s/%d: rn %p, rib %p (type %d) was deleted "
3567 "from kernel, adding",
3568 vrf_id, inet_ntop (p->family, &p->prefix, buf1, INET6_ADDRSTRLEN),
3569 p->prefixlen, rn, fib, fib->type);
6baf7bb8
DS
3570 if (allow_delete)
3571 {
3572 /* Unset flags. */
3573 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
3574 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
3575
3576 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
3577 }
3578 else
3579 {
3580 /* This means someone else, other than Zebra, has deleted a Zebra
3581 * route from the kernel. We will add it back */
3582 rib_install_kernel(rn, fib, 0);
3583 }
2037f143 3584 }
718e3744 3585 else
3586 {
3587 if (IS_ZEBRA_DEBUG_KERNEL)
3588 {
3589 if (gate)
41ec9222 3590 zlog_debug ("%s: vrf %u via %s ifindex %d type %d "
78104b9b
FL
3591 "doesn't exist in rib",
3592 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
81cce018 3593 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
718e3744 3594 ifindex,
3595 type);
3596 else
41ec9222 3597 zlog_debug ("%s: vrf %u ifindex %d type %d doesn't exist in rib",
78104b9b 3598 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
718e3744 3599 ifindex,
3600 type);
3601 }
3602 route_unlock_node (rn);
3603 return ZEBRA_ERR_RTNOEXIST;
3604 }
3605 }
3606
718e3744 3607 if (same)
4d38fdb4 3608 rib_delnode (rn, same);
3609
718e3744 3610 route_unlock_node (rn);
718e3744 3611 return 0;
3612}
6b0655a2 3613
718e3744 3614/* Add static route into static route configuration. */
3615int
3616static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
a3d21ef3
DS
3617 unsigned int ifindex, const char *ifname, u_char flags,
3618 u_short tag, u_char distance, struct zebra_vrf *zvrf)
718e3744 3619{
3620 struct route_node *rn;
c0551cbb
DS
3621 struct static_route *si;
3622 struct static_route *pp;
3623 struct static_route *cp;
526e1728 3624 struct static_route *update = NULL;
78104b9b 3625 struct route_table *stable = zvrf->stable[AFI_IP6][SAFI_UNICAST];
718e3744 3626
718e3744 3627 if (! stable)
3628 return -1;
27b47253
PJ
3629
3630 if (!gate &&
ba779241 3631 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFINDEX))
27b47253
PJ
3632 return -1;
3633
ba779241
DS
3634 if (!ifindex &&
3635 (type == STATIC_IPV6_GATEWAY_IFINDEX || type == STATIC_IFINDEX))
27b47253 3636 return -1;
718e3744 3637
3638 /* Lookup static route prefix. */
3639 rn = route_node_get (stable, p);
3640
3641 /* Do nothing if there is a same static route. */
3642 for (si = rn->info; si; si = si->next)
3643 {
526e1728 3644 if (type == si->type
c0551cbb 3645 && (! gate || IPV6_ADDR_SAME (gate, &si->addr.ipv6))
ba779241 3646 && (! ifindex || ifindex == si->ifindex))
718e3744 3647 {
526e1728
DS
3648 if ((distance == si->distance) && (tag == si->tag))
3649 {
3650 route_unlock_node (rn);
3651 return 0;
3652 }
3653 else
3654 update = si;
718e3744 3655 }
3656 }
3657
526e1728
DS
3658 /* Distance or tag changed. */
3659 if (update)
b9f1114e 3660 static_delete_ipv6 (p, type, gate, ifindex, update->tag, update->distance, zvrf);
526e1728 3661
718e3744 3662 /* Make new static route structure. */
c0551cbb 3663 si = XCALLOC (MTYPE_STATIC_ROUTE, sizeof (struct static_route));
718e3744 3664
3665 si->type = type;
3666 si->distance = distance;
81dfcaa2 3667 si->flags = flags;
0d9551dc 3668 si->tag = tag;
b9f1114e 3669 si->vrf_id = zvrf->vrf_id;
ba779241 3670 si->ifindex = ifindex;
a3d21ef3
DS
3671 if (si->ifindex)
3672 strcpy (si->ifname, ifname);
718e3744 3673
3674 switch (type)
3675 {
3676 case STATIC_IPV6_GATEWAY:
c0551cbb 3677 si->addr.ipv6 = *gate;
718e3744 3678 break;
ba779241 3679 case STATIC_IPV6_GATEWAY_IFINDEX:
c0551cbb 3680 si->addr.ipv6 = *gate;
718e3744 3681 break;
3682 }
3683
3684 /* Add new static route information to the tree with sort by
3685 distance value and gateway address. */
3686 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
3687 {
3688 if (si->distance < cp->distance)
3689 break;
3690 if (si->distance > cp->distance)
3691 continue;
3692 }
3693
3694 /* Make linked list. */
3695 if (pp)
3696 pp->next = si;
3697 else
3698 rn->info = si;
3699 if (cp)
3700 cp->prev = si;
3701 si->prev = pp;
3702 si->next = cp;
3703
3704 /* Install into rib. */
bcd548ff 3705 static_install_route (AFI_IP6, SAFI_UNICAST, p, si);
718e3744 3706
3707 return 1;
3708}
3709
3710/* Delete static route from static route configuration. */
3711int
3712static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
ba779241 3713 unsigned int ifindex, u_short tag, u_char distance,
b9f1114e 3714 struct zebra_vrf *zvrf)
718e3744 3715{
3716 struct route_node *rn;
c0551cbb 3717 struct static_route *si;
718e3744 3718 struct route_table *stable;
3719
3720 /* Lookup table. */
01bb6d57 3721 stable = zebra_vrf_static_table (AFI_IP6, SAFI_UNICAST, zvrf);
718e3744 3722 if (! stable)
3723 return -1;
3724
3725 /* Lookup static route prefix. */
3726 rn = route_node_lookup (stable, p);
3727 if (! rn)
3728 return 0;
3729
3730 /* Find same static route is the tree */
3731 for (si = rn->info; si; si = si->next)
3732 if (distance == si->distance
3733 && type == si->type
c0551cbb 3734 && (! gate || IPV6_ADDR_SAME (gate, &si->addr.ipv6))
ba779241 3735 && (! ifindex || ifindex == si->ifindex)
0d9551dc 3736 && (! tag || (tag == si->tag)))
718e3744 3737 break;
3738
3739 /* Can't find static route. */
3740 if (! si)
3741 {
3742 route_unlock_node (rn);
3743 return 0;
3744 }
3745
3746 /* Install into rib. */
b8a1effa 3747 static_uninstall_route (AFI_IP6, SAFI_UNICAST, p, si);
718e3744 3748
3749 /* Unlink static route from linked list. */
3750 if (si->prev)
3751 si->prev->next = si->next;
3752 else
3753 rn->info = si->next;
3754 if (si->next)
3755 si->next->prev = si->prev;
3756
3757 /* Free static route configuration. */
c0551cbb 3758 XFREE (MTYPE_STATIC_ROUTE, si);
718e3744 3759
3760 return 1;
3761}
6b0655a2 3762
1c848137 3763/* Schedule routes of a particular table (address-family) based on event. */
3764static void
3765rib_update_table (struct route_table *table, rib_update_event_t event)
b84c7253 3766{
3767 struct route_node *rn;
b84c7253 3768 struct rib *rib, *next;
3769
1c848137 3770 /* Walk all routes and queue for processing, if appropriate for
3771 * the trigger event.
3772 */
3773 for (rn = route_top (table); rn; rn = route_next (rn))
3774 {
3775 switch (event)
3776 {
3777 case RIB_UPDATE_IF_CHANGE:
3778 /* Examine all routes that won't get processed by the protocol or
3779 * triggered by nexthop evaluation (NHT). This would be system,
3780 * kernel and certain static routes. Note that NHT will get
3781 * triggered upon an interface event as connected routes always
3782 * get queued for processing.
3783 */
3784 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
3785 {
3786 if (rib->type == ZEBRA_ROUTE_OSPF ||
3787 rib->type == ZEBRA_ROUTE_OSPF6 ||
3788 rib->type == ZEBRA_ROUTE_BGP)
3789 continue; /* protocol will handle. */
3790 else if (rib->type == ZEBRA_ROUTE_STATIC)
3791 {
3792 struct nexthop *nh;
3793 for (nh = rib->nexthop; nh; nh = nh->next)
3794 if (!(nh->type == NEXTHOP_TYPE_IPV4 ||
3795 nh->type == NEXTHOP_TYPE_IPV6))
3796 break;
3797
3798 /* If we only have nexthops to a gateway, NHT will
3799 * take care.
3800 */
3801 if (nh)
44e9909d 3802 rib_queue_add (rn);
1c848137 3803 }
3804 else
44e9909d 3805 rib_queue_add (rn);
1c848137 3806 }
3807 break;
b84c7253 3808
1c848137 3809 case RIB_UPDATE_RMAP_CHANGE:
3810 case RIB_UPDATE_OTHER:
3811 /* Right now, examine all routes. Can restrict to a protocol in
3812 * some cases (TODO).
3813 */
3814 if (rnode_to_ribs (rn))
44e9909d 3815 rib_queue_add (rn);
1c848137 3816 break;
3817
3818 default:
3819 break;
3820 }
3821 }
b84c7253 3822}
3823
718e3744 3824/* RIB update function. */
3825void
1c848137 3826rib_update (vrf_id_t vrf_id, rib_update_event_t event)
718e3744 3827{
718e3744 3828 struct route_table *table;
1c848137 3829
3830 /* Process routes of interested address-families. */
78104b9b 3831 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
718e3744 3832 if (table)
1c848137 3833 rib_update_table (table, event);
718e3744 3834
78104b9b 3835 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
718e3744 3836 if (table)
1c848137 3837 rib_update_table (table, event);
718e3744 3838}
3839
718e3744 3840/* Remove all routes which comes from non main table. */
a1ac18c4 3841static void
718e3744 3842rib_weed_table (struct route_table *table)
3843{
3844 struct route_node *rn;
3845 struct rib *rib;
3846 struct rib *next;
3847
3848 if (table)
3849 for (rn = route_top (table); rn; rn = route_next (rn))
9fd92e3c 3850 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
718e3744 3851 {
6d691129
PJ
3852 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3853 continue;
3854
b21b19c5 3855 if (rib->table != zebrad.rtm_table_default &&
718e3744 3856 rib->table != RT_TABLE_MAIN)
4d38fdb4 3857 rib_delnode (rn, rib);
718e3744 3858 }
3859}
3860
3861/* Delete all routes from non main table. */
3862void
a1ac18c4 3863rib_weed_tables (void)
718e3744 3864{
78104b9b
FL
3865 vrf_iter_t iter;
3866 struct zebra_vrf *zvrf;
3867
3868 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3869 if ((zvrf = vrf_iter2info (iter)) != NULL)
3870 {
3871 rib_weed_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
3872 rib_weed_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
3873 }
718e3744 3874}
6b0655a2 3875
718e3744 3876/* Delete self installed routes after zebra is relaunched. */
a1ac18c4 3877static void
718e3744 3878rib_sweep_table (struct route_table *table)
3879{
3880 struct route_node *rn;
3881 struct rib *rib;
3882 struct rib *next;
3883 int ret = 0;
3884
3885 if (table)
3886 for (rn = route_top (table); rn; rn = route_next (rn))
9fd92e3c 3887 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
718e3744 3888 {
6d691129
PJ
3889 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3890 continue;
3891
718e3744 3892 if (rib->type == ZEBRA_ROUTE_KERNEL &&
3893 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
3894 {
3895 ret = rib_uninstall_kernel (rn, rib);
3896 if (! ret)
4d38fdb4 3897 rib_delnode (rn, rib);
718e3744 3898 }
3899 }
3900}
3901
3902/* Sweep all RIB tables. */
3903void
a1ac18c4 3904rib_sweep_route (void)
718e3744 3905{
78104b9b
FL
3906 vrf_iter_t iter;
3907 struct zebra_vrf *zvrf;
3908
3909 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3910 if ((zvrf = vrf_iter2info (iter)) != NULL)
3911 {
3912 rib_sweep_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
3913 rib_sweep_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
3914 }
718e3744 3915}
2ea1ab1c
VT
3916
3917/* Remove specific by protocol routes from 'table'. */
3918static unsigned long
7c8ff89e 3919rib_score_proto_table (u_char proto, u_short instance, struct route_table *table)
2ea1ab1c
VT
3920{
3921 struct route_node *rn;
3922 struct rib *rib;
3923 struct rib *next;
3924 unsigned long n = 0;
3925
3926 if (table)
3927 for (rn = route_top (table); rn; rn = route_next (rn))
9fd92e3c 3928 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
2ea1ab1c 3929 {
2ea1ab1c
VT
3930 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3931 continue;
7c8ff89e 3932 if (rib->type == proto && rib->instance == instance)
2ea1ab1c
VT
3933 {
3934 rib_delnode (rn, rib);
3935 n++;
3936 }
3937 }
3938
3939 return n;
3940}
3941
3942/* Remove specific by protocol routes. */
3943unsigned long
7c8ff89e 3944rib_score_proto (u_char proto, u_short instance)
2ea1ab1c 3945{
78104b9b
FL
3946 vrf_iter_t iter;
3947 struct zebra_vrf *zvrf;
3948 unsigned long cnt = 0;
3949
3950 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3951 if ((zvrf = vrf_iter2info (iter)) != NULL)
3952 cnt += rib_score_proto_table (proto, instance, zvrf->table[AFI_IP][SAFI_UNICAST])
3953 +rib_score_proto_table (proto, instance, zvrf->table[AFI_IP6][SAFI_UNICAST]);
3954
3955 return cnt;
2ea1ab1c
VT
3956}
3957
718e3744 3958/* Close RIB and clean up kernel routes. */
a31c5886 3959void
718e3744 3960rib_close_table (struct route_table *table)
3961{
3962 struct route_node *rn;
416ec78d 3963 rib_table_info_t *info = table->info;
718e3744 3964 struct rib *rib;
3965
3966 if (table)
3967 for (rn = route_top (table); rn; rn = route_next (rn))
9fd92e3c 3968 RNODE_FOREACH_RIB (rn, rib)
6d691129 3969 {
9fd92e3c
AS
3970 if (!CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
3971 continue;
3972
416ec78d
DL
3973 if (info->safi == SAFI_UNICAST)
3974 zfpm_trigger_update (rn, NULL);
5adc2528 3975
9fd92e3c
AS
3976 if (! RIB_SYSTEM_ROUTE (rib))
3977 rib_uninstall_kernel (rn, rib);
6d691129 3978 }
718e3744 3979}
3980
3981/* Close all RIB tables. */
3982void
a1ac18c4 3983rib_close (void)
718e3744 3984{
78104b9b
FL
3985 vrf_iter_t iter;
3986 struct zebra_vrf *zvrf;
3987 struct listnode *node;
5c610faf 3988 struct interface *ifp;
6678277c 3989 u_int32_t table_id;
5c610faf 3990
78104b9b
FL
3991 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3992 {
3993 if ((zvrf = vrf_iter2info (iter)) != NULL)
3994 {
3995 rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
3996 rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
3997 }
3998 for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
3999 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp);
4000 }
6678277c
DS
4001
4002 /* If we do multiple tables per vrf, need to move this to loop above */
4003 zvrf = vrf_info_lookup (VRF_DEFAULT);
4004
4005 for (table_id = 0; table_id < ZEBRA_KERNEL_TABLE_MAX; table_id++)
4006 {
4007 if (zvrf->other_table[AFI_IP][table_id])
4008 rib_close_table (zvrf->other_table[AFI_IP][table_id]);
4009
4010 if (zvrf->other_table[AFI_IP6][table_id])
4011 rib_close_table (zvrf->other_table[AFI_IP6][table_id]);
4012 }
718e3744 4013}
6b0655a2 4014
718e3744 4015/* Routing information base initialize. */
4016void
a1ac18c4 4017rib_init (void)
718e3744 4018{
4d38fdb4 4019 rib_queue_init (&zebrad);
718e3744 4020}
0915bb0c
AS
4021
4022/*
4023 * vrf_id_get_next
4024 *
4025 * Get the first vrf id that is greater than the given vrf id if any.
4026 *
4027 * Returns TRUE if a vrf id was found, FALSE otherwise.
4028 */
4029static inline int
b72ede27 4030vrf_id_get_next (vrf_id_t vrf_id, vrf_id_t *next_id_p)
0915bb0c 4031{
b72ede27
FL
4032 vrf_iter_t iter = vrf_iterator (vrf_id);
4033 struct zebra_vrf *zvrf = vrf_iter2info (iter);
4034
4035 /* The same one ? Then find out the next. */
4036 if (zvrf && (zvrf->vrf_id == vrf_id))
4037 zvrf = vrf_iter2info (vrf_next (iter));
4038
4039 if (zvrf)
0915bb0c 4040 {
b72ede27
FL
4041 *next_id_p = zvrf->vrf_id;
4042 return 1;
0915bb0c
AS
4043 }
4044
4045 return 0;
4046}
4047
4048/*
4049 * rib_tables_iter_next
4050 *
4051 * Returns the next table in the iteration.
4052 */
4053struct route_table *
4054rib_tables_iter_next (rib_tables_iter_t *iter)
4055{
4056 struct route_table *table;
4057
4058 /*
4059 * Array that helps us go over all AFI/SAFI combinations via one
4060 * index.
4061 */
4062 static struct {
4063 afi_t afi;
4064 safi_t safi;
4065 } afi_safis[] = {
4066 { AFI_IP, SAFI_UNICAST },
4067 { AFI_IP, SAFI_MULTICAST },
4068 { AFI_IP6, SAFI_UNICAST },
4069 { AFI_IP6, SAFI_MULTICAST },
4070 };
4071
4072 table = NULL;
4073
4074 switch (iter->state)
4075 {
4076
4077 case RIB_TABLES_ITER_S_INIT:
9c2bf1cf 4078 iter->vrf_id = VRF_DEFAULT;
0915bb0c
AS
4079 iter->afi_safi_ix = -1;
4080
4081 /* Fall through */
4082
4083 case RIB_TABLES_ITER_S_ITERATING:
4084 iter->afi_safi_ix++;
4085 while (1)
4086 {
4087
4088 while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
4089 {
b72ede27 4090 table = zebra_vrf_table (afi_safis[iter->afi_safi_ix].afi,
0915bb0c
AS
4091 afi_safis[iter->afi_safi_ix].safi,
4092 iter->vrf_id);
4093 if (table)
4094 break;
4095
4096 iter->afi_safi_ix++;
4097 }
4098
4099 /*
4100 * Found another table in this vrf.
4101 */
4102 if (table)
4103 break;
4104
4105 /*
4106 * Done with all tables in the current vrf, go to the next
4107 * one.
4108 */
4109 if (!vrf_id_get_next (iter->vrf_id, &iter->vrf_id))
4110 break;
4111
4112 iter->afi_safi_ix = 0;
4113 }
4114
4115 break;
4116
4117 case RIB_TABLES_ITER_S_DONE:
4118 return NULL;
4119 }
4120
4121 if (table)
4122 iter->state = RIB_TABLES_ITER_S_ITERATING;
4123 else
4124 iter->state = RIB_TABLES_ITER_S_DONE;
4125
4126 return table;
4127}
b72ede27 4128