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