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