]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_rib.c
fpm: Add public header for Forwarding Plane Manager
[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"
718e3744 37
38#include "zebra/rib.h"
39#include "zebra/rt.h"
40#include "zebra/zserv.h"
41#include "zebra/redistribute.h"
42#include "zebra/debug.h"
43
44/* Default rtm_table for all clients */
b21b19c5 45extern struct zebra_t zebrad;
718e3744 46
457eb9af
PJ
47/* Hold time for RIB process, should be very minimal.
48 * it is useful to able to set it otherwise for testing, hence exported
49 * as global here for test-rig code.
50 */
51int rib_process_hold_time = 10;
52
718e3744 53/* Each route type's string and default distance value. */
d145bc00 54static const struct
718e3744 55{
56 int key;
57 int distance;
5734509c 58} route_info[ZEBRA_ROUTE_MAX] =
718e3744 59{
5734509c
PJ
60 [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0},
61 [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0},
62 [ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0},
63 [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1},
64 [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120},
65 [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120},
66 [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110},
67 [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110},
68 [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115},
69 [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */},
70 [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 95},
7052f228 71 /* no entry/default: 150 */
718e3744 72};
73\f
74/* Vector for routing table. */
d145bc00 75static vector vrf_vector;
718e3744 76
1b5ed1b0
AS
77/*
78 * vrf_table_create
79 */
80static void
81vrf_table_create (struct vrf *vrf, afi_t afi, safi_t safi)
82{
83 rib_table_info_t *info;
84 struct route_table *table;
85
86 assert (!vrf->table[afi][safi]);
87
88 table = route_table_init ();
89 vrf->table[afi][safi] = table;
90
91 info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
92 info->vrf = vrf;
93 info->afi = afi;
94 info->safi = safi;
95 table->info = info;
96}
97
718e3744 98/* Allocate new VRF. */
a1ac18c4 99static struct vrf *
fce954f8 100vrf_alloc (const char *name)
718e3744 101{
102 struct vrf *vrf;
103
104 vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
105
106 /* Put name. */
107 if (name)
108 vrf->name = XSTRDUP (MTYPE_VRF_NAME, name);
109
110 /* Allocate routing table and static table. */
1b5ed1b0
AS
111 vrf_table_create (vrf, AFI_IP, SAFI_UNICAST);
112 vrf_table_create (vrf, AFI_IP6, SAFI_UNICAST);
718e3744 113 vrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
114 vrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
1b5ed1b0
AS
115 vrf_table_create (vrf, AFI_IP, SAFI_MULTICAST);
116 vrf_table_create (vrf, AFI_IP6, SAFI_MULTICAST);
cddf391b
B
117 vrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
118 vrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
119
718e3744 120
121 return vrf;
122}
123
718e3744 124/* Lookup VRF by identifier. */
125struct vrf *
126vrf_lookup (u_int32_t id)
127{
128 return vector_lookup (vrf_vector, id);
129}
130
718e3744 131/* Initialize VRF. */
a1ac18c4 132static void
133vrf_init (void)
718e3744 134{
135 struct vrf *default_table;
136
137 /* Allocate VRF vector. */
138 vrf_vector = vector_init (1);
139
140 /* Allocate default main table. */
141 default_table = vrf_alloc ("Default-IP-Routing-Table");
142
143 /* Default table index must be 0. */
144 vector_set_index (vrf_vector, 0, default_table);
145}
146
147/* Lookup route table. */
148struct route_table *
149vrf_table (afi_t afi, safi_t safi, u_int32_t id)
150{
151 struct vrf *vrf;
152
153 vrf = vrf_lookup (id);
154 if (! vrf)
155 return NULL;
156
157 return vrf->table[afi][safi];
158}
159
160/* Lookup static route table. */
161struct route_table *
162vrf_static_table (afi_t afi, safi_t safi, u_int32_t id)
163{
164 struct vrf *vrf;
165
166 vrf = vrf_lookup (id);
167 if (! vrf)
168 return NULL;
169
170 return vrf->stable[afi][safi];
171}
172\f
78deec45
AS
173/*
174 * nexthop_type_to_str
175 */
176const char *
177nexthop_type_to_str (enum nexthop_types_t nh_type)
178{
179 static const char *desc[] = {
180 "none",
181 "Directly connected",
182 "Interface route",
183 "IPv4 nexthop",
184 "IPv4 nexthop with ifindex",
185 "IPv4 nexthop with ifname",
186 "IPv6 nexthop",
187 "IPv6 nexthop with ifindex",
188 "IPv6 nexthop with ifname",
189 "Null0 nexthop",
190 };
191
192 if (nh_type >= ZEBRA_NUM_OF (desc))
193 return "<Invalid nh type>";
194
195 return desc[nh_type];
196}
197
718e3744 198/* Add nexthop to the end of the list. */
a1ac18c4 199static void
718e3744 200nexthop_add (struct rib *rib, struct nexthop *nexthop)
201{
202 struct nexthop *last;
203
204 for (last = rib->nexthop; last && last->next; last = last->next)
205 ;
206 if (last)
207 last->next = nexthop;
208 else
209 rib->nexthop = nexthop;
210 nexthop->prev = last;
211
212 rib->nexthop_num++;
213}
214
215/* Delete specified nexthop from the list. */
a1ac18c4 216static void
718e3744 217nexthop_delete (struct rib *rib, struct nexthop *nexthop)
218{
219 if (nexthop->next)
220 nexthop->next->prev = nexthop->prev;
221 if (nexthop->prev)
222 nexthop->prev->next = nexthop->next;
223 else
224 rib->nexthop = nexthop->next;
225 rib->nexthop_num--;
226}
227
228/* Free nexthop. */
a1ac18c4 229static void
718e3744 230nexthop_free (struct nexthop *nexthop)
231{
a4b70768 232 if (nexthop->ifname)
233 XFREE (0, nexthop->ifname);
718e3744 234 XFREE (MTYPE_NEXTHOP, nexthop);
235}
236
237struct nexthop *
238nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
239{
240 struct nexthop *nexthop;
241
393deb9b 242 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
718e3744 243 nexthop->type = NEXTHOP_TYPE_IFINDEX;
244 nexthop->ifindex = ifindex;
245
246 nexthop_add (rib, nexthop);
247
248 return nexthop;
249}
250
251struct nexthop *
252nexthop_ifname_add (struct rib *rib, char *ifname)
253{
254 struct nexthop *nexthop;
255
393deb9b 256 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
718e3744 257 nexthop->type = NEXTHOP_TYPE_IFNAME;
a4b70768 258 nexthop->ifname = XSTRDUP (0, ifname);
718e3744 259
260 nexthop_add (rib, nexthop);
261
262 return nexthop;
263}
264
265struct nexthop *
7514fb77 266nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src)
718e3744 267{
268 struct nexthop *nexthop;
269
393deb9b 270 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
718e3744 271 nexthop->type = NEXTHOP_TYPE_IPV4;
272 nexthop->gate.ipv4 = *ipv4;
7514fb77
PJ
273 if (src)
274 nexthop->src.ipv4 = *src;
718e3744 275
276 nexthop_add (rib, nexthop);
277
278 return nexthop;
279}
280
26e2ae36 281struct nexthop *
718e3744 282nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
7514fb77 283 struct in_addr *src, unsigned int ifindex)
718e3744 284{
285 struct nexthop *nexthop;
286
393deb9b 287 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
718e3744 288 nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
289 nexthop->gate.ipv4 = *ipv4;
7514fb77
PJ
290 if (src)
291 nexthop->src.ipv4 = *src;
718e3744 292 nexthop->ifindex = ifindex;
293
294 nexthop_add (rib, nexthop);
295
296 return nexthop;
297}
298
299#ifdef HAVE_IPV6
300struct nexthop *
301nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
302{
303 struct nexthop *nexthop;
304
393deb9b 305 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
718e3744 306 nexthop->type = NEXTHOP_TYPE_IPV6;
307 nexthop->gate.ipv6 = *ipv6;
308
309 nexthop_add (rib, nexthop);
310
311 return nexthop;
312}
313
a1ac18c4 314static struct nexthop *
718e3744 315nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
316 char *ifname)
317{
318 struct nexthop *nexthop;
319
393deb9b 320 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
718e3744 321 nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
322 nexthop->gate.ipv6 = *ipv6;
323 nexthop->ifname = XSTRDUP (0, ifname);
324
325 nexthop_add (rib, nexthop);
326
327 return nexthop;
328}
329
a1ac18c4 330static struct nexthop *
718e3744 331nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
332 unsigned int ifindex)
333{
334 struct nexthop *nexthop;
335
393deb9b 336 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
718e3744 337 nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
338 nexthop->gate.ipv6 = *ipv6;
339 nexthop->ifindex = ifindex;
340
341 nexthop_add (rib, nexthop);
342
343 return nexthop;
344}
345#endif /* HAVE_IPV6 */
346
595db7f1 347struct nexthop *
348nexthop_blackhole_add (struct rib *rib)
349{
350 struct nexthop *nexthop;
351
393deb9b 352 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
595db7f1 353 nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
354 SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
355
356 nexthop_add (rib, nexthop);
357
358 return nexthop;
359}
360
718e3744 361/* If force flag is not set, do not modify falgs at all for uninstall
362 the route from FIB. */
a1ac18c4 363static int
718e3744 364nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
365 struct route_node *top)
366{
367 struct prefix_ipv4 p;
368 struct route_table *table;
369 struct route_node *rn;
370 struct rib *match;
371 struct nexthop *newhop;
372
373 if (nexthop->type == NEXTHOP_TYPE_IPV4)
374 nexthop->ifindex = 0;
375
376 if (set)
377 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
378
379 /* Make lookup prefix. */
380 memset (&p, 0, sizeof (struct prefix_ipv4));
381 p.family = AF_INET;
382 p.prefixlen = IPV4_MAX_PREFIXLEN;
383 p.prefix = nexthop->gate.ipv4;
384
385 /* Lookup table. */
386 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
387 if (! table)
388 return 0;
389
390 rn = route_node_match (table, (struct prefix *) &p);
391 while (rn)
392 {
393 route_unlock_node (rn);
394
a50c107e 395 /* If lookup self prefix return immediately. */
718e3744 396 if (rn == top)
397 return 0;
398
399 /* Pick up selected route. */
9fd92e3c 400 RNODE_FOREACH_RIB (rn, match)
16814f96
SH
401 {
402 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
403 continue;
404 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
405 break;
406 }
718e3744 407
408 /* If there is no selected route or matched route is EGP, go up
409 tree. */
410 if (! match
411 || match->type == ZEBRA_ROUTE_BGP)
412 {
413 do {
414 rn = rn->parent;
415 } while (rn && rn->info == NULL);
416 if (rn)
417 route_lock_node (rn);
418 }
419 else
420 {
421 if (match->type == ZEBRA_ROUTE_CONNECT)
422 {
423 /* Directly point connected route. */
424 newhop = match->nexthop;
425 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
426 nexthop->ifindex = newhop->ifindex;
427
428 return 1;
429 }
430 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
431 {
432 for (newhop = match->nexthop; newhop; newhop = newhop->next)
433 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
434 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
435 {
436 if (set)
437 {
438 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
439 nexthop->rtype = newhop->type;
440 if (newhop->type == NEXTHOP_TYPE_IPV4 ||
441 newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
442 nexthop->rgate.ipv4 = newhop->gate.ipv4;
443 if (newhop->type == NEXTHOP_TYPE_IFINDEX
444 || newhop->type == NEXTHOP_TYPE_IFNAME
445 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
446 nexthop->rifindex = newhop->ifindex;
447 }
448 return 1;
449 }
450 return 0;
451 }
452 else
453 {
454 return 0;
455 }
456 }
457 }
458 return 0;
459}
460
461#ifdef HAVE_IPV6
462/* If force flag is not set, do not modify falgs at all for uninstall
463 the route from FIB. */
a1ac18c4 464static int
718e3744 465nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
466 struct route_node *top)
467{
468 struct prefix_ipv6 p;
469 struct route_table *table;
470 struct route_node *rn;
471 struct rib *match;
472 struct nexthop *newhop;
473
474 if (nexthop->type == NEXTHOP_TYPE_IPV6)
475 nexthop->ifindex = 0;
476
477 if (set)
478 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
479
480 /* Make lookup prefix. */
481 memset (&p, 0, sizeof (struct prefix_ipv6));
482 p.family = AF_INET6;
483 p.prefixlen = IPV6_MAX_PREFIXLEN;
484 p.prefix = nexthop->gate.ipv6;
485
486 /* Lookup table. */
487 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
488 if (! table)
489 return 0;
490
491 rn = route_node_match (table, (struct prefix *) &p);
492 while (rn)
493 {
494 route_unlock_node (rn);
495
a50c107e 496 /* If lookup self prefix return immediately. */
718e3744 497 if (rn == top)
498 return 0;
499
500 /* Pick up selected route. */
9fd92e3c 501 RNODE_FOREACH_RIB (rn, match)
16814f96
SH
502 {
503 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
504 continue;
505 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
506 break;
507 }
718e3744 508
509 /* If there is no selected route or matched route is EGP, go up
510 tree. */
511 if (! match
512 || match->type == ZEBRA_ROUTE_BGP)
513 {
514 do {
515 rn = rn->parent;
516 } while (rn && rn->info == NULL);
517 if (rn)
518 route_lock_node (rn);
519 }
520 else
521 {
522 if (match->type == ZEBRA_ROUTE_CONNECT)
523 {
524 /* Directly point connected route. */
525 newhop = match->nexthop;
526
527 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
528 nexthop->ifindex = newhop->ifindex;
529
530 return 1;
531 }
532 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
533 {
534 for (newhop = match->nexthop; newhop; newhop = newhop->next)
535 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
536 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
537 {
538 if (set)
539 {
540 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
541 nexthop->rtype = newhop->type;
542 if (newhop->type == NEXTHOP_TYPE_IPV6
543 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
544 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
545 nexthop->rgate.ipv6 = newhop->gate.ipv6;
546 if (newhop->type == NEXTHOP_TYPE_IFINDEX
547 || newhop->type == NEXTHOP_TYPE_IFNAME
548 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
549 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
550 nexthop->rifindex = newhop->ifindex;
551 }
552 return 1;
553 }
554 return 0;
555 }
556 else
557 {
558 return 0;
559 }
560 }
561 }
562 return 0;
563}
564#endif /* HAVE_IPV6 */
565
566struct rib *
567rib_match_ipv4 (struct in_addr addr)
568{
569 struct prefix_ipv4 p;
570 struct route_table *table;
571 struct route_node *rn;
572 struct rib *match;
573 struct nexthop *newhop;
574
575 /* Lookup table. */
576 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
577 if (! table)
578 return 0;
579
580 memset (&p, 0, sizeof (struct prefix_ipv4));
581 p.family = AF_INET;
582 p.prefixlen = IPV4_MAX_PREFIXLEN;
583 p.prefix = addr;
584
585 rn = route_node_match (table, (struct prefix *) &p);
586
587 while (rn)
588 {
589 route_unlock_node (rn);
590
591 /* Pick up selected route. */
9fd92e3c 592 RNODE_FOREACH_RIB (rn, match)
16814f96
SH
593 {
594 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
595 continue;
596 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
597 break;
598 }
718e3744 599
600 /* If there is no selected route or matched route is EGP, go up
601 tree. */
602 if (! match
603 || match->type == ZEBRA_ROUTE_BGP)
604 {
605 do {
606 rn = rn->parent;
607 } while (rn && rn->info == NULL);
608 if (rn)
609 route_lock_node (rn);
610 }
611 else
612 {
613 if (match->type == ZEBRA_ROUTE_CONNECT)
614 /* Directly point connected route. */
615 return match;
616 else
617 {
618 for (newhop = match->nexthop; newhop; newhop = newhop->next)
619 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
620 return match;
621 return NULL;
622 }
623 }
624 }
625 return NULL;
626}
627
628struct rib *
629rib_lookup_ipv4 (struct prefix_ipv4 *p)
630{
631 struct route_table *table;
632 struct route_node *rn;
633 struct rib *match;
634 struct nexthop *nexthop;
635
636 /* Lookup table. */
637 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
638 if (! table)
639 return 0;
640
641 rn = route_node_lookup (table, (struct prefix *) p);
642
643 /* No route for this prefix. */
644 if (! rn)
645 return NULL;
646
647 /* Unlock node. */
648 route_unlock_node (rn);
649
9fd92e3c 650 RNODE_FOREACH_RIB (rn, match)
16814f96
SH
651 {
652 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
653 continue;
654 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
655 break;
656 }
718e3744 657
658 if (! match || match->type == ZEBRA_ROUTE_BGP)
659 return NULL;
660
661 if (match->type == ZEBRA_ROUTE_CONNECT)
662 return match;
663
664 for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
665 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
666 return match;
667
668 return NULL;
669}
670
dc95824a
DO
671/*
672 * This clone function, unlike its original rib_lookup_ipv4(), checks
673 * if specified IPv4 route record (prefix/mask -> gate) exists in
674 * the whole RIB and has ZEBRA_FLAG_SELECTED set.
675 *
676 * Return values:
677 * -1: error
678 * 0: exact match found
679 * 1: a match was found with a different gate
680 * 2: connected route found
681 * 3: no matches found
682 */
683int
684rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
685{
686 struct route_table *table;
687 struct route_node *rn;
688 struct rib *match;
689 struct nexthop *nexthop;
690
691 /* Lookup table. */
692 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
693 if (! table)
694 return ZEBRA_RIB_LOOKUP_ERROR;
695
696 /* Scan the RIB table for exactly matching RIB entry. */
697 rn = route_node_lookup (table, (struct prefix *) p);
698
699 /* No route for this prefix. */
700 if (! rn)
701 return ZEBRA_RIB_NOTFOUND;
702
703 /* Unlock node. */
704 route_unlock_node (rn);
705
706 /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
9fd92e3c 707 RNODE_FOREACH_RIB (rn, match)
16814f96
SH
708 {
709 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
710 continue;
711 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
712 break;
713 }
dc95824a
DO
714
715 /* None such found :( */
716 if (!match)
717 return ZEBRA_RIB_NOTFOUND;
718
719 if (match->type == ZEBRA_ROUTE_CONNECT)
720 return ZEBRA_RIB_FOUND_CONNECTED;
721
722 /* Ok, we have a cood candidate, let's check it's nexthop list... */
723 for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
724 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
725 {
726 /* We are happy with either direct or recursive hexthop */
12829328
JBD
727 if (nexthop->gate.ipv4.s_addr == sockunion2ip (qgate) ||
728 nexthop->rgate.ipv4.s_addr == sockunion2ip (qgate))
dc95824a
DO
729 return ZEBRA_RIB_FOUND_EXACT;
730 else
731 {
732 if (IS_ZEBRA_DEBUG_RIB)
733 {
734 char gate_buf[INET_ADDRSTRLEN], rgate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
735 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
736 inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, rgate_buf, INET_ADDRSTRLEN);
12829328 737 inet_ntop (AF_INET, &sockunion2ip (qgate), qgate_buf, INET_ADDRSTRLEN);
dc95824a
DO
738 zlog_debug ("%s: qgate == %s, gate == %s, rgate == %s", __func__, qgate_buf, gate_buf, rgate_buf);
739 }
740 return ZEBRA_RIB_FOUND_NOGATE;
741 }
742 }
743
744 return ZEBRA_RIB_NOTFOUND;
745}
746
718e3744 747#ifdef HAVE_IPV6
748struct rib *
749rib_match_ipv6 (struct in6_addr *addr)
750{
751 struct prefix_ipv6 p;
752 struct route_table *table;
753 struct route_node *rn;
754 struct rib *match;
755 struct nexthop *newhop;
756
757 /* Lookup table. */
758 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
759 if (! table)
760 return 0;
761
762 memset (&p, 0, sizeof (struct prefix_ipv6));
763 p.family = AF_INET6;
764 p.prefixlen = IPV6_MAX_PREFIXLEN;
765 IPV6_ADDR_COPY (&p.prefix, addr);
766
767 rn = route_node_match (table, (struct prefix *) &p);
768
769 while (rn)
770 {
771 route_unlock_node (rn);
772
773 /* Pick up selected route. */
9fd92e3c 774 RNODE_FOREACH_RIB (rn, match)
16814f96
SH
775 {
776 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
777 continue;
778 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
779 break;
780 }
718e3744 781
782 /* If there is no selected route or matched route is EGP, go up
783 tree. */
784 if (! match
785 || match->type == ZEBRA_ROUTE_BGP)
786 {
787 do {
788 rn = rn->parent;
789 } while (rn && rn->info == NULL);
790 if (rn)
791 route_lock_node (rn);
792 }
793 else
794 {
795 if (match->type == ZEBRA_ROUTE_CONNECT)
796 /* Directly point connected route. */
797 return match;
798 else
799 {
800 for (newhop = match->nexthop; newhop; newhop = newhop->next)
801 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
802 return match;
803 return NULL;
804 }
805 }
806 }
807 return NULL;
808}
809#endif /* HAVE_IPV6 */
810
7514fb77
PJ
811#define RIB_SYSTEM_ROUTE(R) \
812 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
813
dc95824a
DO
814/* This function verifies reachability of one given nexthop, which can be
815 * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
816 * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
817 * nexthop->ifindex will be updated appropriately as well.
818 * An existing route map can turn (otherwise active) nexthop into inactive, but
819 * not vice versa.
820 *
821 * The return value is the final value of 'ACTIVE' flag.
822 */
823
d02c56cd 824static unsigned
718e3744 825nexthop_active_check (struct route_node *rn, struct rib *rib,
826 struct nexthop *nexthop, int set)
827{
828 struct interface *ifp;
7514fb77
PJ
829 route_map_result_t ret = RMAP_MATCH;
830 extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
831 struct route_map *rmap;
832 int family;
718e3744 833
7514fb77 834 family = 0;
718e3744 835 switch (nexthop->type)
836 {
837 case NEXTHOP_TYPE_IFINDEX:
838 ifp = if_lookup_by_index (nexthop->ifindex);
3f087670 839 if (ifp && if_is_operative(ifp))
718e3744 840 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
841 else
842 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
843 break;
718e3744 844 case NEXTHOP_TYPE_IPV6_IFNAME:
7514fb77
PJ
845 family = AFI_IP6;
846 case NEXTHOP_TYPE_IFNAME:
718e3744 847 ifp = if_lookup_by_name (nexthop->ifname);
3f087670 848 if (ifp && if_is_operative(ifp))
718e3744 849 {
850 if (set)
851 nexthop->ifindex = ifp->ifindex;
852 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
853 }
854 else
855 {
856 if (set)
857 nexthop->ifindex = 0;
858 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
859 }
860 break;
861 case NEXTHOP_TYPE_IPV4:
862 case NEXTHOP_TYPE_IPV4_IFINDEX:
7514fb77 863 family = AFI_IP;
718e3744 864 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
865 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
866 else
867 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
868 break;
869#ifdef HAVE_IPV6
870 case NEXTHOP_TYPE_IPV6:
7514fb77 871 family = AFI_IP6;
718e3744 872 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
873 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
874 else
875 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
876 break;
877 case NEXTHOP_TYPE_IPV6_IFINDEX:
7514fb77 878 family = AFI_IP6;
718e3744 879 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
880 {
881 ifp = if_lookup_by_index (nexthop->ifindex);
3f087670 882 if (ifp && if_is_operative(ifp))
718e3744 883 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
884 else
885 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
886 }
887 else
888 {
889 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
890 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
891 else
892 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
893 }
894 break;
895#endif /* HAVE_IPV6 */
595db7f1 896 case NEXTHOP_TYPE_BLACKHOLE:
897 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
898 break;
718e3744 899 default:
900 break;
901 }
7514fb77
PJ
902 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
903 return 0;
904
905 if (RIB_SYSTEM_ROUTE(rib) ||
906 (family == AFI_IP && rn->p.family != AF_INET) ||
907 (family == AFI_IP6 && rn->p.family != AF_INET6))
908 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
909
910 rmap = 0;
911 if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
912 proto_rm[family][rib->type])
913 rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
914 if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
915 rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
916 if (rmap) {
917 ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, nexthop);
918 }
919
920 if (ret == RMAP_DENYMATCH)
921 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
718e3744 922 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
923}
924
03e232a4
DO
925/* Iterate over all nexthops of the given RIB entry and refresh their
926 * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
927 * nexthop is found to toggle the ACTIVE flag, the whole rib structure
928 * is flagged with ZEBRA_FLAG_CHANGED. The 4th 'set' argument is
929 * transparently passed to nexthop_active_check().
930 *
931 * Return value is the new number of active nexthops.
932 */
933
a1ac18c4 934static int
718e3744 935nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
936{
937 struct nexthop *nexthop;
d02c56cd 938 unsigned int prev_active, prev_index, new_active;
718e3744 939
940 rib->nexthop_active_num = 0;
941 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
942
943 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
03e232a4
DO
944 {
945 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
c3a56063 946 prev_index = nexthop->ifindex;
03e232a4
DO
947 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
948 rib->nexthop_active_num++;
c3a56063
JT
949 if (prev_active != new_active ||
950 prev_index != nexthop->ifindex)
03e232a4
DO
951 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
952 }
718e3744 953 return rib->nexthop_active_num;
954}
6baeb988 955
718e3744 956\f
718e3744 957
a1ac18c4 958static void
718e3744 959rib_install_kernel (struct route_node *rn, struct rib *rib)
960{
961 int ret = 0;
962 struct nexthop *nexthop;
963
964 switch (PREFIX_FAMILY (&rn->p))
965 {
966 case AF_INET:
967 ret = kernel_add_ipv4 (&rn->p, rib);
968 break;
969#ifdef HAVE_IPV6
970 case AF_INET6:
971 ret = kernel_add_ipv6 (&rn->p, rib);
972 break;
973#endif /* HAVE_IPV6 */
974 }
975
dc95824a 976 /* This condition is never met, if we are using rt_socket.c */
718e3744 977 if (ret < 0)
978 {
979 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
980 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
981 }
982}
983
984/* Uninstall the route from kernel. */
a1ac18c4 985static int
718e3744 986rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
987{
988 int ret = 0;
989 struct nexthop *nexthop;
990
991 switch (PREFIX_FAMILY (&rn->p))
992 {
993 case AF_INET:
994 ret = kernel_delete_ipv4 (&rn->p, rib);
995 break;
996#ifdef HAVE_IPV6
997 case AF_INET6:
998 ret = kernel_delete_ipv6 (&rn->p, rib);
999 break;
1000#endif /* HAVE_IPV6 */
1001 }
1002
1003 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1004 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1005
1006 return ret;
1007}
1008
1009/* Uninstall the route from kernel. */
a1ac18c4 1010static void
718e3744 1011rib_uninstall (struct route_node *rn, struct rib *rib)
1012{
1013 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1014 {
1015 redistribute_delete (&rn->p, rib);
1016 if (! RIB_SYSTEM_ROUTE (rib))
1017 rib_uninstall_kernel (rn, rib);
1018 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
1019 }
1020}
1021
6d691129
PJ
1022static void rib_unlink (struct route_node *, struct rib *);
1023
9fd92e3c
AS
1024/*
1025 * rib_can_delete_dest
1026 *
1027 * Returns TRUE if the given dest can be deleted from the table.
1028 */
1029static int
1030rib_can_delete_dest (rib_dest_t *dest)
1031{
1032 if (dest->routes)
1033 {
1034 return 0;
1035 }
1036
1037 return 1;
1038}
1039
1040/*
1041 * rib_gc_dest
1042 *
1043 * Garbage collect the rib dest corresponding to the given route node
1044 * if appropriate.
1045 *
1046 * Returns TRUE if the dest was deleted, FALSE otherwise.
1047 */
1048int
1049rib_gc_dest (struct route_node *rn)
1050{
1051 rib_dest_t *dest;
1052 char buf[INET6_ADDRSTRLEN];
1053
1054 dest = rib_dest_from_rnode (rn);
1055 if (!dest)
1056 return 0;
1057
1058 if (!rib_can_delete_dest (dest))
1059 return 0;
1060
1061 if (IS_ZEBRA_DEBUG_RIB)
1062 {
1063 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, sizeof (buf));
1064 zlog_debug ("%s: %s/%d: removing dest from table", __func__,
1065 buf, rn->p.prefixlen);
1066 }
1067
1068 dest->rnode = NULL;
1069 XFREE (MTYPE_RIB_DEST, dest);
1070 rn->info = NULL;
1071
1072 /*
1073 * Release the one reference that we keep on the route node.
1074 */
1075 route_unlock_node (rn);
1076 return 1;
1077}
1078
718e3744 1079/* Core function for processing routing information base. */
e96f9203
DO
1080static void
1081rib_process (struct route_node *rn)
718e3744 1082{
1083 struct rib *rib;
1084 struct rib *next;
1085 struct rib *fib = NULL;
1086 struct rib *select = NULL;
6d691129 1087 struct rib *del = NULL;
d753e9ee 1088 int installed = 0;
1089 struct nexthop *nexthop = NULL;
f304cb48 1090 char buf[INET6_ADDRSTRLEN];
4d38fdb4 1091
1092 assert (rn);
1093
93bdadae 1094 if (IS_ZEBRA_DEBUG_RIB || IS_ZEBRA_DEBUG_RIB_Q)
f304cb48 1095 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
93bdadae 1096
9fd92e3c 1097 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
718e3744 1098 {
718e3744 1099 /* Currently installed rib. */
1100 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
6d691129
PJ
1101 {
1102 assert (fib == NULL);
1103 fib = rib;
1104 }
1105
1106 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1107 * which we need to do do further work with below.
1108 */
1109 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1110 {
1111 if (rib != fib)
1112 {
1113 if (IS_ZEBRA_DEBUG_RIB)
93bdadae
PJ
1114 zlog_debug ("%s: %s/%d: rn %p, removing rib %p", __func__,
1115 buf, rn->p.prefixlen, rn, rib);
9fd92e3c 1116 rib_unlink (rn, rib);
6d691129
PJ
1117 }
1118 else
1119 del = rib;
1120
1121 continue;
1122 }
4d38fdb4 1123
718e3744 1124 /* Skip unreachable nexthop. */
1125 if (! nexthop_active_update (rn, rib, 0))
7021c425 1126 continue;
718e3744 1127
1128 /* Infinit distance. */
1129 if (rib->distance == DISTANCE_INFINITY)
7021c425 1130 continue;
718e3744 1131
af887b51 1132 /* Newly selected rib, the common case. */
1133 if (!select)
1134 {
1135 select = rib;
1136 continue;
1137 }
1138
1139 /* filter route selection in following order:
af887b51 1140 * - connected beats other types
a8d9c1f9 1141 * - lower distance beats higher
af887b51 1142 * - lower metric beats higher for equal distance
1143 * - last, hence oldest, route wins tie break.
1144 */
a1038a15 1145
1146 /* Connected routes. Pick the last connected
1147 * route of the set of lowest metric connected routes.
1148 */
a8d9c1f9 1149 if (rib->type == ZEBRA_ROUTE_CONNECT)
1150 {
a1038a15 1151 if (select->type != ZEBRA_ROUTE_CONNECT
a8d9c1f9 1152 || rib->metric <= select->metric)
a1038a15 1153 select = rib;
1154 continue;
a8d9c1f9 1155 }
1156 else if (select->type == ZEBRA_ROUTE_CONNECT)
1157 continue;
1158
1159 /* higher distance loses */
1160 if (rib->distance > select->distance)
1161 continue;
1162
1163 /* lower wins */
1164 if (rib->distance < select->distance)
1165 {
af887b51 1166 select = rib;
a8d9c1f9 1167 continue;
1168 }
1169
1170 /* metric tie-breaks equal distance */
1171 if (rib->metric <= select->metric)
1172 select = rib;
9fd92e3c 1173 } /* RNODE_FOREACH_RIB_SAFE */
dc95824a
DO
1174
1175 /* After the cycle is finished, the following pointers will be set:
1176 * select --- the winner RIB entry, if any was found, otherwise NULL
1177 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1178 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1179 * rib --- NULL
1180 */
1181
1182 /* Same RIB entry is selected. Update FIB and finish. */
718e3744 1183 if (select && select == fib)
1184 {
6d691129 1185 if (IS_ZEBRA_DEBUG_RIB)
93bdadae
PJ
1186 zlog_debug ("%s: %s/%d: Updating existing route, select %p, fib %p",
1187 __func__, buf, rn->p.prefixlen, select, fib);
718e3744 1188 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
4d38fdb4 1189 {
1190 redistribute_delete (&rn->p, select);
1191 if (! RIB_SYSTEM_ROUTE (select))
1192 rib_uninstall_kernel (rn, select);
718e3744 1193
4d38fdb4 1194 /* Set real nexthop. */
1195 nexthop_active_update (rn, select, 1);
718e3744 1196
4d38fdb4 1197 if (! RIB_SYSTEM_ROUTE (select))
1198 rib_install_kernel (rn, select);
1199 redistribute_add (&rn->p, select);
1200 }
d753e9ee 1201 else if (! RIB_SYSTEM_ROUTE (select))
4d38fdb4 1202 {
1203 /* Housekeeping code to deal with
1204 race conditions in kernel with linux
1205 netlink reporting interface up before IPv4 or IPv6 protocol
1206 is ready to add routes.
1207 This makes sure the routes are IN the kernel.
1208 */
1209
1210 for (nexthop = select->nexthop; nexthop; nexthop = nexthop->next)
a3aaf5b0 1211 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
4d38fdb4 1212 {
a3aaf5b0
DO
1213 installed = 1;
1214 break;
4d38fdb4 1215 }
1216 if (! installed)
1217 rib_install_kernel (rn, select);
1218 }
6d691129 1219 goto end;
718e3744 1220 }
1221
dc95824a
DO
1222 /* At this point we either haven't found the best RIB entry or it is
1223 * different from what we currently intend to flag with SELECTED. In both
1224 * cases, if a RIB block is present in FIB, it should be withdrawn.
1225 */
718e3744 1226 if (fib)
1227 {
6d691129 1228 if (IS_ZEBRA_DEBUG_RIB)
93bdadae
PJ
1229 zlog_debug ("%s: %s/%d: Removing existing route, fib %p", __func__,
1230 buf, rn->p.prefixlen, fib);
718e3744 1231 redistribute_delete (&rn->p, fib);
1232 if (! RIB_SYSTEM_ROUTE (fib))
1233 rib_uninstall_kernel (rn, fib);
1234 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1235
1236 /* Set real nexthop. */
1237 nexthop_active_update (rn, fib, 1);
1238 }
1239
dc95824a
DO
1240 /* Regardless of some RIB entry being SELECTED or not before, now we can
1241 * tell, that if a new winner exists, FIB is still not updated with this
1242 * data, but ready to be.
1243 */
718e3744 1244 if (select)
1245 {
6d691129 1246 if (IS_ZEBRA_DEBUG_RIB)
93bdadae
PJ
1247 zlog_debug ("%s: %s/%d: Adding route, select %p", __func__, buf,
1248 rn->p.prefixlen, select);
718e3744 1249 /* Set real nexthop. */
1250 nexthop_active_update (rn, select, 1);
1251
1252 if (! RIB_SYSTEM_ROUTE (select))
4d38fdb4 1253 rib_install_kernel (rn, select);
718e3744 1254 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1255 redistribute_add (&rn->p, select);
1256 }
4d38fdb4 1257
6d691129
PJ
1258 /* FIB route was removed, should be deleted */
1259 if (del)
1260 {
1261 if (IS_ZEBRA_DEBUG_RIB)
93bdadae
PJ
1262 zlog_debug ("%s: %s/%d: Deleting fib %p, rn %p", __func__, buf,
1263 rn->p.prefixlen, del, rn);
6d691129
PJ
1264 rib_unlink (rn, del);
1265 }
4d38fdb4 1266
6d691129
PJ
1267end:
1268 if (IS_ZEBRA_DEBUG_RIB_Q)
93bdadae 1269 zlog_debug ("%s: %s/%d: rn %p dequeued", __func__, buf, rn->p.prefixlen, rn);
9fd92e3c
AS
1270
1271 /*
1272 * Check if the dest can be deleted now.
1273 */
1274 rib_gc_dest (rn);
e96f9203
DO
1275}
1276
5110a0c6
SH
1277/* Take a list of route_node structs and return 1, if there was a record
1278 * picked from it and processed by rib_process(). Don't process more,
1279 * than one RN record; operate only in the specified sub-queue.
e96f9203 1280 */
ef9b113e 1281static unsigned int
e96f9203
DO
1282process_subq (struct list * subq, u_char qindex)
1283{
5110a0c6 1284 struct listnode *lnode = listhead (subq);
e96f9203 1285 struct route_node *rnode;
5110a0c6
SH
1286
1287 if (!lnode)
e96f9203 1288 return 0;
5110a0c6 1289
e96f9203
DO
1290 rnode = listgetdata (lnode);
1291 rib_process (rnode);
5110a0c6 1292
9fd92e3c
AS
1293 if (rnode->info)
1294 UNSET_FLAG (rib_dest_from_rnode (rnode)->flags, RIB_ROUTE_QUEUED (qindex));
1295
67b9467f 1296#if 0
5110a0c6
SH
1297 else
1298 {
1299 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1300 __func__, rnode, rnode->lock);
1301 zlog_backtrace(LOG_DEBUG);
1302 }
67b9467f 1303#endif
e96f9203
DO
1304 route_unlock_node (rnode);
1305 list_delete_node (subq, lnode);
1306 return 1;
1307}
1308
1309/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1310 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1311 * is pointed to the meta queue structure.
1312 */
1313static wq_item_status
1314meta_queue_process (struct work_queue *dummy, void *data)
1315{
1316 struct meta_queue * mq = data;
5110a0c6
SH
1317 unsigned i;
1318
e96f9203
DO
1319 for (i = 0; i < MQ_SIZE; i++)
1320 if (process_subq (mq->subq[i], i))
5110a0c6
SH
1321 {
1322 mq->size--;
1323 break;
1324 }
e96f9203
DO
1325 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1326}
1327
9fd92e3c
AS
1328/*
1329 * Map from rib types to queue type (priority) in meta queue
1330 */
5110a0c6
SH
1331static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
1332 [ZEBRA_ROUTE_SYSTEM] = 4,
1333 [ZEBRA_ROUTE_KERNEL] = 0,
1334 [ZEBRA_ROUTE_CONNECT] = 0,
1335 [ZEBRA_ROUTE_STATIC] = 1,
1336 [ZEBRA_ROUTE_RIP] = 2,
1337 [ZEBRA_ROUTE_RIPNG] = 2,
1338 [ZEBRA_ROUTE_OSPF] = 2,
1339 [ZEBRA_ROUTE_OSPF6] = 2,
1340 [ZEBRA_ROUTE_ISIS] = 2,
1341 [ZEBRA_ROUTE_BGP] = 3,
1342 [ZEBRA_ROUTE_HSLS] = 4,
5734509c 1343 [ZEBRA_ROUTE_BABEL] = 2,
5110a0c6
SH
1344};
1345
1346/* Look into the RN and queue it into one or more priority queues,
1347 * increasing the size for each data push done.
e96f9203 1348 */
ef9b113e
SH
1349static void
1350rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
e96f9203 1351{
e96f9203
DO
1352 struct rib *rib;
1353 char buf[INET6_ADDRSTRLEN];
5110a0c6 1354
e96f9203
DO
1355 if (IS_ZEBRA_DEBUG_RIB_Q)
1356 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
5110a0c6 1357
9fd92e3c 1358 RNODE_FOREACH_RIB (rn, rib)
e96f9203 1359 {
5110a0c6
SH
1360 u_char qindex = meta_queue_map[rib->type];
1361
1362 /* Invariant: at this point we always have rn->info set. */
9fd92e3c
AS
1363 if (CHECK_FLAG (rib_dest_from_rnode (rn)->flags,
1364 RIB_ROUTE_QUEUED (qindex)))
5110a0c6
SH
1365 {
1366 if (IS_ZEBRA_DEBUG_RIB_Q)
1367 zlog_debug ("%s: %s/%d: rn %p is already queued in sub-queue %u",
1368 __func__, buf, rn->p.prefixlen, rn, qindex);
1369 continue;
1370 }
1371
9fd92e3c 1372 SET_FLAG (rib_dest_from_rnode (rn)->flags, RIB_ROUTE_QUEUED (qindex));
5110a0c6
SH
1373 listnode_add (mq->subq[qindex], rn);
1374 route_lock_node (rn);
1375 mq->size++;
1376
e96f9203 1377 if (IS_ZEBRA_DEBUG_RIB_Q)
5110a0c6
SH
1378 zlog_debug ("%s: %s/%d: queued rn %p into sub-queue %u",
1379 __func__, buf, rn->p.prefixlen, rn, qindex);
e96f9203 1380 }
4d38fdb4 1381}
1382
6d691129 1383/* Add route_node to work queue and schedule processing */
a1ac18c4 1384static void
6d691129 1385rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
4d38fdb4 1386{
fc328ac9
SV
1387 char buf[INET_ADDRSTRLEN];
1388 assert (zebra && rn);
4d38fdb4 1389
93bdadae 1390 if (IS_ZEBRA_DEBUG_RIB_Q)
fc328ac9
SV
1391 inet_ntop (AF_INET, &rn->p.u.prefix, buf, INET_ADDRSTRLEN);
1392
1393 /* Pointless to queue a route_node with no RIB entries to add or remove */
9fd92e3c 1394 if (!rnode_to_ribs (rn))
6d691129 1395 {
fc328ac9
SV
1396 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1397 __func__, rn, rn->lock);
1398 zlog_backtrace(LOG_DEBUG);
1399 return;
1400 }
1401
1402 if (IS_ZEBRA_DEBUG_RIB_Q)
1403 zlog_info ("%s: %s/%d: work queue added", __func__, buf, rn->p.prefixlen);
1404
1405 assert (zebra);
4d38fdb4 1406
fc328ac9
SV
1407 if (zebra->ribq == NULL)
1408 {
1409 zlog_err ("%s: work_queue does not exist!", __func__);
1410 return;
4d38fdb4 1411 }
4d38fdb4 1412
cc2dd928
SH
1413 /*
1414 * The RIB queue should normally be either empty or holding the only
1415 * work_queue_item element. In the latter case this element would
1416 * hold a pointer to the meta queue structure, which must be used to
1417 * actually queue the route nodes to process. So create the MQ
1418 * holder, if necessary, then push the work into it in any case.
e96f9203
DO
1419 * This semantics was introduced after 0.99.9 release.
1420 */
e96f9203
DO
1421 if (!zebra->ribq->items->count)
1422 work_queue_add (zebra->ribq, zebra->mq);
1423
1424 rib_meta_queue_add (zebra->mq, rn);
fc328ac9
SV
1425
1426 if (IS_ZEBRA_DEBUG_RIB_Q)
1427 zlog_debug ("%s: %s/%d: rn %p queued", __func__, buf, rn->p.prefixlen, rn);
1428
1429 return;
4d38fdb4 1430}
1431
5110a0c6
SH
1432/* Create new meta queue.
1433 A destructor function doesn't seem to be necessary here.
1434 */
ef9b113e
SH
1435static struct meta_queue *
1436meta_queue_new (void)
e96f9203
DO
1437{
1438 struct meta_queue *new;
5110a0c6
SH
1439 unsigned i;
1440
1441 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1442 assert(new);
e96f9203 1443
e96f9203 1444 for (i = 0; i < MQ_SIZE; i++)
5110a0c6
SH
1445 {
1446 new->subq[i] = list_new ();
1447 assert(new->subq[i]);
1448 }
1449
e96f9203
DO
1450 return new;
1451}
1452
4d38fdb4 1453/* initialise zebra rib work queue */
a1ac18c4 1454static void
4d38fdb4 1455rib_queue_init (struct zebra_t *zebra)
1456{
fc328ac9
SV
1457 assert (zebra);
1458
4d38fdb4 1459 if (! (zebra->ribq = work_queue_new (zebra->master,
6d691129 1460 "route_node processing")))
4d38fdb4 1461 {
6d691129 1462 zlog_err ("%s: could not initialise work queue!", __func__);
4d38fdb4 1463 return;
1464 }
1465
1466 /* fill in the work queue spec */
e96f9203 1467 zebra->ribq->spec.workfunc = &meta_queue_process;
4d38fdb4 1468 zebra->ribq->spec.errorfunc = NULL;
4d38fdb4 1469 /* XXX: TODO: These should be runtime configurable via vty */
1470 zebra->ribq->spec.max_retries = 3;
457eb9af 1471 zebra->ribq->spec.hold = rib_process_hold_time;
4d38fdb4 1472
e96f9203 1473 if (!(zebra->mq = meta_queue_new ()))
fc328ac9 1474 {
e96f9203 1475 zlog_err ("%s: could not initialise meta queue!", __func__);
fc328ac9
SV
1476 return;
1477 }
1478 return;
718e3744 1479}
1480
6d691129
PJ
1481/* RIB updates are processed via a queue of pointers to route_nodes.
1482 *
1483 * The queue length is bounded by the maximal size of the routing table,
1484 * as a route_node will not be requeued, if already queued.
1485 *
3c0755dc
PJ
1486 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1487 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1488 * and then submit route_node to queue for best-path selection later.
1489 * Order of add/delete state changes are preserved for any given RIB.
6d691129
PJ
1490 *
1491 * Deleted RIBs are reaped during best-path selection.
1492 *
1493 * rib_addnode
1494 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
3c0755dc
PJ
1495 * |-------->| | best RIB, if required
1496 * | |
1497 * static_install->|->rib_addqueue...... -> rib_process
1498 * | |
1499 * |-------->| |-> rib_unlink
6d691129
PJ
1500 * |-> set RIB_ENTRY_REMOVE |
1501 * rib_delnode (RIB freed)
1502 *
9fd92e3c
AS
1503 * The 'info' pointer of a route_node points to a rib_dest_t
1504 * ('dest'). Queueing state for a route_node is kept on the dest. The
1505 * dest is created on-demand by rib_link() and is kept around at least
1506 * as long as there are ribs hanging off it (@see rib_gc_dest()).
6d691129
PJ
1507 *
1508 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1509 *
1510 * - route_nodes: refcounted by:
9fd92e3c
AS
1511 * - dest attached to route_node:
1512 * - managed by: rib_link/rib_gc_dest
6d691129
PJ
1513 * - route_node processing queue
1514 * - managed by: rib_addqueue, rib_process.
1515 *
1516 */
1517
718e3744 1518/* Add RIB to head of the route node. */
a1ac18c4 1519static void
6d691129 1520rib_link (struct route_node *rn, struct rib *rib)
718e3744 1521{
1522 struct rib *head;
9fd92e3c 1523 rib_dest_t *dest;
f304cb48 1524 char buf[INET6_ADDRSTRLEN];
9fd92e3c 1525
4d38fdb4 1526 assert (rib && rn);
1527
6d691129 1528 if (IS_ZEBRA_DEBUG_RIB)
93bdadae 1529 {
f304cb48 1530 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
93bdadae
PJ
1531 zlog_debug ("%s: %s/%d: rn %p, rib %p", __func__,
1532 buf, rn->p.prefixlen, rn, rib);
1533 }
6d691129 1534
9fd92e3c
AS
1535 dest = rib_dest_from_rnode (rn);
1536 if (!dest)
6d691129
PJ
1537 {
1538 if (IS_ZEBRA_DEBUG_RIB)
9fd92e3c
AS
1539 {
1540 zlog_debug ("%s: %s/%d: adding dest to table", __func__,
1541 buf, rn->p.prefixlen);
1542 }
1543
1544 dest = XCALLOC (MTYPE_RIB_DEST, sizeof (rib_dest_t));
1545 route_lock_node (rn); /* rn route table reference */
1546 rn->info = dest;
1547 dest->rnode = rn;
1548 }
1549
1550 head = dest->routes;
1551 if (head)
1552 {
6d691129 1553 head->prev = rib;
6d691129 1554 }
718e3744 1555 rib->next = head;
9fd92e3c 1556 dest->routes = rib;
6d691129 1557 rib_queue_add (&zebrad, rn);
718e3744 1558}
1559
a1ac18c4 1560static void
6d691129 1561rib_addnode (struct route_node *rn, struct rib *rib)
718e3744 1562{
6d691129
PJ
1563 /* RIB node has been un-removed before route-node is processed.
1564 * route_node must hence already be on the queue for processing..
1565 */
1566 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1567 {
1568 if (IS_ZEBRA_DEBUG_RIB)
93bdadae 1569 {
f304cb48
DO
1570 char buf[INET6_ADDRSTRLEN];
1571 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
93bdadae
PJ
1572 zlog_debug ("%s: %s/%d: rn %p, un-removed rib %p",
1573 __func__, buf, rn->p.prefixlen, rn, rib);
1574 }
6d691129
PJ
1575 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1576 return;
1577 }
1578 rib_link (rn, rib);
1579}
1580
9fd92e3c
AS
1581/*
1582 * rib_unlink
1583 *
1584 * Detach a rib structure from a route_node.
1585 *
1586 * Note that a call to rib_unlink() should be followed by a call to
1587 * rib_gc_dest() at some point. This allows a rib_dest_t that is no
1588 * longer required to be deleted.
1589 */
6d691129
PJ
1590static void
1591rib_unlink (struct route_node *rn, struct rib *rib)
1592{
1593 struct nexthop *nexthop, *next;
f304cb48 1594 char buf[INET6_ADDRSTRLEN];
9fd92e3c 1595 rib_dest_t *dest;
6d691129 1596
4d38fdb4 1597 assert (rn && rib);
6d691129
PJ
1598
1599 if (IS_ZEBRA_DEBUG_RIB)
93bdadae 1600 {
f304cb48 1601 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
93bdadae
PJ
1602 zlog_debug ("%s: %s/%d: rn %p, rib %p",
1603 __func__, buf, rn->p.prefixlen, rn, rib);
1604 }
6d691129 1605
9fd92e3c
AS
1606 dest = rib_dest_from_rnode (rn);
1607
718e3744 1608 if (rib->next)
1609 rib->next->prev = rib->prev;
6d691129 1610
718e3744 1611 if (rib->prev)
1612 rib->prev->next = rib->next;
1613 else
6d691129 1614 {
9fd92e3c 1615 dest->routes = rib->next;
6d691129
PJ
1616 }
1617
1618 /* free RIB and nexthops */
1619 for (nexthop = rib->nexthop; nexthop; nexthop = next)
1620 {
1621 next = nexthop->next;
1622 nexthop_free (nexthop);
1623 }
1624 XFREE (MTYPE_RIB, rib);
1625
6d691129
PJ
1626}
1627
1628static void
1629rib_delnode (struct route_node *rn, struct rib *rib)
1630{
1631 if (IS_ZEBRA_DEBUG_RIB)
93bdadae 1632 {
f304cb48
DO
1633 char buf[INET6_ADDRSTRLEN];
1634 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
93bdadae
PJ
1635 zlog_debug ("%s: %s/%d: rn %p, rib %p, removing", __func__,
1636 buf, rn->p.prefixlen, rn, rib);
1637 }
6d691129
PJ
1638 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1639 rib_queue_add (&zebrad, rn);
718e3744 1640}
1641
1642int
1643rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
7514fb77
PJ
1644 struct in_addr *gate, struct in_addr *src,
1645 unsigned int ifindex, u_int32_t vrf_id,
cddf391b 1646 u_int32_t metric, u_char distance, safi_t safi)
718e3744 1647{
1648 struct rib *rib;
1649 struct rib *same = NULL;
1650 struct route_table *table;
1651 struct route_node *rn;
1652 struct nexthop *nexthop;
1653
1654 /* Lookup table. */
cddf391b 1655 table = vrf_table (AFI_IP, safi, 0);
718e3744 1656 if (! table)
1657 return 0;
1658
1659 /* Make it sure prefixlen is applied to the prefix. */
1660 apply_mask_ipv4 (p);
1661
1662 /* Set default distance by route type. */
1663 if (distance == 0)
1664 {
837d16cc 1665 if ((unsigned)type >= array_size(route_info))
7052f228
DL
1666 distance = 150;
1667 else
1668 distance = route_info[type].distance;
718e3744 1669
1670 /* iBGP distance is 200. */
1671 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1672 distance = 200;
1673 }
1674
1675 /* Lookup route node.*/
1676 rn = route_node_get (table, (struct prefix *) p);
1677
1678 /* If same type of route are installed, treat it as a implicit
1679 withdraw. */
9fd92e3c 1680 RNODE_FOREACH_RIB (rn, rib)
718e3744 1681 {
6d691129
PJ
1682 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1683 continue;
1684
ebf1ead0 1685 if (rib->type != type)
1686 continue;
1687 if (rib->type != ZEBRA_ROUTE_CONNECT)
4d38fdb4 1688 {
1689 same = rib;
1690 break;
1691 }
ebf1ead0 1692 /* Duplicate connected route comes in. */
1693 else if ((nexthop = rib->nexthop) &&
1694 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
6d691129
PJ
1695 nexthop->ifindex == ifindex &&
1696 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
ebf1ead0 1697 {
1698 rib->refcnt++;
1699 return 0 ;
1700 }
718e3744 1701 }
1702
1703 /* Allocate new rib structure. */
4d38fdb4 1704 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
718e3744 1705 rib->type = type;
1706 rib->distance = distance;
1707 rib->flags = flags;
1708 rib->metric = metric;
b5f45021 1709 rib->table = vrf_id;
718e3744 1710 rib->nexthop_num = 0;
1711 rib->uptime = time (NULL);
1712
1713 /* Nexthop settings. */
1714 if (gate)
1715 {
1716 if (ifindex)
7514fb77 1717 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
718e3744 1718 else
7514fb77 1719 nexthop_ipv4_add (rib, gate, src);
718e3744 1720 }
1721 else
1722 nexthop_ifindex_add (rib, ifindex);
1723
1724 /* If this route is kernel route, set FIB flag to the route. */
1725 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1726 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1727 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1728
1729 /* Link new rib to node.*/
dc95824a
DO
1730 if (IS_ZEBRA_DEBUG_RIB)
1731 zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
718e3744 1732 rib_addnode (rn, rib);
4d38fdb4 1733
718e3744 1734 /* Free implicit route.*/
1735 if (same)
dc95824a
DO
1736 {
1737 if (IS_ZEBRA_DEBUG_RIB)
1738 zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
4d38fdb4 1739 rib_delnode (rn, same);
dc95824a 1740 }
4d38fdb4 1741
1742 route_unlock_node (rn);
718e3744 1743 return 0;
1744}
1745
dc95824a
DO
1746/* This function dumps the contents of a given RIB entry into
1747 * standard debug log. Calling function name and IP prefix in
1748 * question are passed as 1st and 2nd arguments.
1749 */
1750
1751void rib_dump (const char * func, const struct prefix_ipv4 * p, const struct rib * rib)
1752{
1753 char straddr1[INET_ADDRSTRLEN], straddr2[INET_ADDRSTRLEN];
1754 struct nexthop *nexthop;
1755
1756 inet_ntop (AF_INET, &p->prefix, straddr1, INET_ADDRSTRLEN);
1757 zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr1, p->prefixlen);
1758 zlog_debug
1759 (
d02c56cd 1760 "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
dc95824a
DO
1761 func,
1762 rib->refcnt,
d02c56cd 1763 (unsigned long) rib->uptime,
dc95824a
DO
1764 rib->type,
1765 rib->table
1766 );
1767 zlog_debug
1768 (
1769 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1770 func,
1771 rib->metric,
1772 rib->distance,
1773 rib->flags,
1774 rib->status
1775 );
1776 zlog_debug
1777 (
1778 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1779 func,
1780 rib->nexthop_num,
1781 rib->nexthop_active_num,
1782 rib->nexthop_fib_num
1783 );
1784 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1785 {
1786 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, straddr1, INET_ADDRSTRLEN);
1787 inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, straddr2, INET_ADDRSTRLEN);
1788 zlog_debug
1789 (
1790 "%s: NH %s (%s) with flags %s%s%s",
1791 func,
1792 straddr1,
1793 straddr2,
1794 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1795 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1796 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1797 );
1798 }
1799 zlog_debug ("%s: dump complete", func);
1800}
1801
1802/* This is an exported helper to rtm_read() to dump the strange
1803 * RIB entry found by rib_lookup_ipv4_route()
1804 */
1805
1806void rib_lookup_and_dump (struct prefix_ipv4 * p)
1807{
1808 struct route_table *table;
1809 struct route_node *rn;
1810 struct rib *rib;
1811 char prefix_buf[INET_ADDRSTRLEN];
1812
1813 /* Lookup table. */
1814 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1815 if (! table)
1816 {
1817 zlog_err ("%s: vrf_table() returned NULL", __func__);
1818 return;
1819 }
1820
1821 inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
1822 /* Scan the RIB table for exactly matching RIB entry. */
1823 rn = route_node_lookup (table, (struct prefix *) p);
1824
1825 /* No route for this prefix. */
1826 if (! rn)
1827 {
1828 zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
1829 return;
1830 }
1831
1832 /* Unlock node. */
1833 route_unlock_node (rn);
1834
1835 /* let's go */
9fd92e3c 1836 RNODE_FOREACH_RIB (rn, rib)
dc95824a
DO
1837 {
1838 zlog_debug
1839 (
1840 "%s: rn %p, rib %p: %s, %s",
1841 __func__,
1842 rn,
1843 rib,
1844 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
1845 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
1846 );
1847 rib_dump (__func__, p, rib);
1848 }
1849}
1850
20e5ff0a
DO
1851/* Check if requested address assignment will fail due to another
1852 * route being installed by zebra in FIB already. Take necessary
1853 * actions, if needed: remove such a route from FIB and deSELECT
1854 * corresponding RIB entry. Then put affected RN into RIBQ head.
1855 */
1856void rib_lookup_and_pushup (struct prefix_ipv4 * p)
1857{
1858 struct route_table *table;
1859 struct route_node *rn;
1860 struct rib *rib;
1861 unsigned changed = 0;
1862
1863 if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
1864 {
1865 zlog_err ("%s: vrf_table() returned NULL", __func__);
1866 return;
1867 }
1868
1869 /* No matches would be the simplest case. */
1870 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
1871 return;
1872
1873 /* Unlock node. */
1874 route_unlock_node (rn);
1875
1876 /* Check all RIB entries. In case any changes have to be done, requeue
1877 * the RN into RIBQ head. If the routing message about the new connected
1878 * route (generated by the IP address we are going to assign very soon)
1879 * comes before the RIBQ is processed, the new RIB entry will join
1880 * RIBQ record already on head. This is necessary for proper revalidation
1881 * of the rest of the RIB.
1882 */
9fd92e3c 1883 RNODE_FOREACH_RIB (rn, rib)
20e5ff0a
DO
1884 {
1885 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
1886 ! RIB_SYSTEM_ROUTE (rib))
1887 {
1888 changed = 1;
1889 if (IS_ZEBRA_DEBUG_RIB)
1890 {
1891 char buf[INET_ADDRSTRLEN];
1892 inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
1893 zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
1894 rib_dump (__func__, (struct prefix_ipv4 *)&rn->p, rib);
1895 }
1896 rib_uninstall (rn, rib);
1897 }
1898 }
1899 if (changed)
20e5ff0a 1900 rib_queue_add (&zebrad, rn);
20e5ff0a
DO
1901}
1902
718e3744 1903int
cddf391b 1904rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
718e3744 1905{
1906 struct route_table *table;
1907 struct route_node *rn;
1908 struct rib *same;
1909 struct nexthop *nexthop;
4d38fdb4 1910
718e3744 1911 /* Lookup table. */
cddf391b 1912 table = vrf_table (AFI_IP, safi, 0);
718e3744 1913 if (! table)
1914 return 0;
cddf391b 1915
718e3744 1916 /* Make it sure prefixlen is applied to the prefix. */
1917 apply_mask_ipv4 (p);
1918
1919 /* Set default distance by route type. */
1920 if (rib->distance == 0)
1921 {
1922 rib->distance = route_info[rib->type].distance;
1923
1924 /* iBGP distance is 200. */
1925 if (rib->type == ZEBRA_ROUTE_BGP
1926 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1927 rib->distance = 200;
1928 }
1929
1930 /* Lookup route node.*/
1931 rn = route_node_get (table, (struct prefix *) p);
1932
1933 /* If same type of route are installed, treat it as a implicit
1934 withdraw. */
9fd92e3c 1935 RNODE_FOREACH_RIB (rn, same)
718e3744 1936 {
0b8c4f1d 1937 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
6d691129
PJ
1938 continue;
1939
718e3744 1940 if (same->type == rib->type && same->table == rib->table
1941 && same->type != ZEBRA_ROUTE_CONNECT)
4d38fdb4 1942 break;
718e3744 1943 }
4d38fdb4 1944
718e3744 1945 /* If this route is kernel route, set FIB flag to the route. */
1946 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
1947 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1948 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1949
1950 /* Link new rib to node.*/
1951 rib_addnode (rn, rib);
dc95824a
DO
1952 if (IS_ZEBRA_DEBUG_RIB)
1953 {
1954 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
1955 __func__, rn, rib);
1956 rib_dump (__func__, p, rib);
1957 }
718e3744 1958
718e3744 1959 /* Free implicit route.*/
1960 if (same)
dc95824a
DO
1961 {
1962 if (IS_ZEBRA_DEBUG_RIB)
1963 {
1964 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
1965 __func__, rn, same);
1966 rib_dump (__func__, p, same);
1967 }
4d38fdb4 1968 rib_delnode (rn, same);
dc95824a 1969 }
4d38fdb4 1970
1971 route_unlock_node (rn);
718e3744 1972 return 0;
1973}
1974
ebf1ead0 1975/* XXX factor with rib_delete_ipv6 */
718e3744 1976int
1977rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
cddf391b 1978 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
718e3744 1979{
1980 struct route_table *table;
1981 struct route_node *rn;
1982 struct rib *rib;
1983 struct rib *fib = NULL;
1984 struct rib *same = NULL;
1985 struct nexthop *nexthop;
81cce018
SH
1986 char buf1[INET_ADDRSTRLEN];
1987 char buf2[INET_ADDRSTRLEN];
718e3744 1988
1989 /* Lookup table. */
cddf391b 1990 table = vrf_table (AFI_IP, safi, 0);
718e3744 1991 if (! table)
1992 return 0;
1993
1994 /* Apply mask. */
1995 apply_mask_ipv4 (p);
1996
5ec90d28 1997 if (IS_ZEBRA_DEBUG_KERNEL && gate)
b6178002 1998 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
81cce018 1999 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
5ec90d28 2000 p->prefixlen,
2001 inet_ntoa (*gate),
2002 ifindex);
2003
718e3744 2004 /* Lookup route node. */
2005 rn = route_node_lookup (table, (struct prefix *) p);
2006 if (! rn)
2007 {
2008 if (IS_ZEBRA_DEBUG_KERNEL)
2009 {
2010 if (gate)
b6178002 2011 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
81cce018 2012 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
718e3744 2013 p->prefixlen,
81cce018 2014 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
718e3744 2015 ifindex);
2016 else
b6178002 2017 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
81cce018 2018 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
718e3744 2019 p->prefixlen,
2020 ifindex);
2021 }
2022 return ZEBRA_ERR_RTNOEXIST;
2023 }
2024
2025 /* Lookup same type route. */
9fd92e3c 2026 RNODE_FOREACH_RIB (rn, rib)
718e3744 2027 {
6d691129
PJ
2028 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2029 continue;
2030
718e3744 2031 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2032 fib = rib;
2033
ebf1ead0 2034 if (rib->type != type)
2035 continue;
2036 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
4f1735fd 2037 nexthop->type == NEXTHOP_TYPE_IFINDEX)
718e3744 2038 {
4f1735fd
MF
2039 if (nexthop->ifindex != ifindex)
2040 continue;
ebf1ead0 2041 if (rib->refcnt)
718e3744 2042 {
ebf1ead0 2043 rib->refcnt--;
2044 route_unlock_node (rn);
2045 route_unlock_node (rn);
2046 return 0;
718e3744 2047 }
ebf1ead0 2048 same = rib;
2049 break;
718e3744 2050 }
ebf1ead0 2051 /* Make sure that the route found has the same gateway. */
2052 else if (gate == NULL ||
2053 ((nexthop = rib->nexthop) &&
2054 (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
2055 IPV4_ADDR_SAME (&nexthop->rgate.ipv4, gate))))
5ec90d28 2056 {
ebf1ead0 2057 same = rib;
2058 break;
718e3744 2059 }
2060 }
2061
2062 /* If same type of route can't be found and this message is from
2063 kernel. */
2064 if (! same)
2065 {
2066 if (fib && type == ZEBRA_ROUTE_KERNEL)
2067 {
2068 /* Unset flags. */
2069 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2070 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2071
2072 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2073 }
2074 else
2075 {
2076 if (IS_ZEBRA_DEBUG_KERNEL)
2077 {
2078 if (gate)
b6178002 2079 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
81cce018 2080 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
718e3744 2081 p->prefixlen,
81cce018 2082 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
718e3744 2083 ifindex,
2084 type);
2085 else
b6178002 2086 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
81cce018 2087 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
718e3744 2088 p->prefixlen,
2089 ifindex,
2090 type);
2091 }
2092 route_unlock_node (rn);
2093 return ZEBRA_ERR_RTNOEXIST;
2094 }
2095 }
4d38fdb4 2096
718e3744 2097 if (same)
4d38fdb4 2098 rib_delnode (rn, same);
2099
718e3744 2100 route_unlock_node (rn);
718e3744 2101 return 0;
2102}
2103\f
2104/* Install static route into rib. */
a1ac18c4 2105static void
718e3744 2106static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
2107{
2108 struct rib *rib;
2109 struct route_node *rn;
2110 struct route_table *table;
2111
2112 /* Lookup table. */
2113 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2114 if (! table)
2115 return;
2116
2117 /* Lookup existing route */
2118 rn = route_node_get (table, p);
9fd92e3c 2119 RNODE_FOREACH_RIB (rn, rib)
6d691129
PJ
2120 {
2121 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2122 continue;
2123
2124 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2125 break;
2126 }
718e3744 2127
2128 if (rib)
2129 {
2130 /* Same distance static route is there. Update it with new
2131 nexthop. */
718e3744 2132 route_unlock_node (rn);
718e3744 2133 switch (si->type)
7021c425 2134 {
2135 case STATIC_IPV4_GATEWAY:
7514fb77 2136 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
7021c425 2137 break;
2138 case STATIC_IPV4_IFNAME:
2139 nexthop_ifname_add (rib, si->gate.ifname);
2140 break;
2141 case STATIC_IPV4_BLACKHOLE:
2142 nexthop_blackhole_add (rib);
2143 break;
4d38fdb4 2144 }
3c0755dc 2145 rib_queue_add (&zebrad, rn);
718e3744 2146 }
2147 else
2148 {
2149 /* This is new static route. */
4d38fdb4 2150 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2151
718e3744 2152 rib->type = ZEBRA_ROUTE_STATIC;
2153 rib->distance = si->distance;
2154 rib->metric = 0;
b0145ddb 2155 rib->table = zebrad.rtm_table_default;
718e3744 2156 rib->nexthop_num = 0;
2157
2158 switch (si->type)
7021c425 2159 {
2160 case STATIC_IPV4_GATEWAY:
7514fb77 2161 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
7021c425 2162 break;
2163 case STATIC_IPV4_IFNAME:
2164 nexthop_ifname_add (rib, si->gate.ifname);
2165 break;
2166 case STATIC_IPV4_BLACKHOLE:
2167 nexthop_blackhole_add (rib);
2168 break;
2169 }
718e3744 2170
81dfcaa2 2171 /* Save the flags of this static routes (reject, blackhole) */
2172 rib->flags = si->flags;
2173
718e3744 2174 /* Link this rib to the tree. */
2175 rib_addnode (rn, rib);
718e3744 2176 }
2177}
2178
a1ac18c4 2179static int
718e3744 2180static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2181{
2182 if (nexthop->type == NEXTHOP_TYPE_IPV4
2183 && si->type == STATIC_IPV4_GATEWAY
2184 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2185 return 1;
2186 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2187 && si->type == STATIC_IPV4_IFNAME
2188 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2189 return 1;
595db7f1 2190 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2191 && si->type == STATIC_IPV4_BLACKHOLE)
2192 return 1;
e8e1946e 2193 return 0;
718e3744 2194}
2195
2196/* Uninstall static route from RIB. */
a1ac18c4 2197static void
718e3744 2198static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
2199{
2200 struct route_node *rn;
2201 struct rib *rib;
2202 struct nexthop *nexthop;
2203 struct route_table *table;
2204
2205 /* Lookup table. */
2206 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2207 if (! table)
2208 return;
4d38fdb4 2209
718e3744 2210 /* Lookup existing route with type and distance. */
2211 rn = route_node_lookup (table, p);
2212 if (! rn)
2213 return;
2214
9fd92e3c 2215 RNODE_FOREACH_RIB (rn, rib)
6d691129
PJ
2216 {
2217 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2218 continue;
2219
2220 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2221 break;
2222 }
718e3744 2223
2224 if (! rib)
2225 {
2226 route_unlock_node (rn);
2227 return;
2228 }
2229
2230 /* Lookup nexthop. */
2231 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2232 if (static_ipv4_nexthop_same (nexthop, si))
2233 break;
2234
2235 /* Can't find nexthop. */
2236 if (! nexthop)
2237 {
2238 route_unlock_node (rn);
2239 return;
2240 }
2241
2242 /* Check nexthop. */
2243 if (rib->nexthop_num == 1)
6d691129 2244 rib_delnode (rn, rib);
718e3744 2245 else
2246 {
6baeb988 2247 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2248 rib_uninstall (rn, rib);
319572cc 2249 nexthop_delete (rib, nexthop);
2250 nexthop_free (nexthop);
6d691129 2251 rib_queue_add (&zebrad, rn);
718e3744 2252 }
718e3744 2253 /* Unlock node. */
2254 route_unlock_node (rn);
2255}
2256
2257/* Add static route into static route configuration. */
2258int
39db97e4 2259static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
81dfcaa2 2260 u_char flags, u_char distance, u_int32_t vrf_id)
718e3744 2261{
2262 u_char type = 0;
2263 struct route_node *rn;
2264 struct static_ipv4 *si;
2265 struct static_ipv4 *pp;
2266 struct static_ipv4 *cp;
2267 struct static_ipv4 *update = NULL;
2268 struct route_table *stable;
2269
2270 /* Lookup table. */
2271 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2272 if (! stable)
2273 return -1;
2274
2275 /* Lookup static route prefix. */
2276 rn = route_node_get (stable, p);
2277
2278 /* Make flags. */
2279 if (gate)
2280 type = STATIC_IPV4_GATEWAY;
368aa3f0 2281 else if (ifname)
718e3744 2282 type = STATIC_IPV4_IFNAME;
595db7f1 2283 else
2284 type = STATIC_IPV4_BLACKHOLE;
718e3744 2285
2286 /* Do nothing if there is a same static route. */
2287 for (si = rn->info; si; si = si->next)
2288 {
2289 if (type == si->type
2290 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2291 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2292 {
2293 if (distance == si->distance)
2294 {
2295 route_unlock_node (rn);
2296 return 0;
2297 }
2298 else
2299 update = si;
2300 }
2301 }
2302
3c0755dc 2303 /* Distance changed. */
718e3744 2304 if (update)
2305 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
2306
2307 /* Make new static route structure. */
393deb9b 2308 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
718e3744 2309
2310 si->type = type;
2311 si->distance = distance;
81dfcaa2 2312 si->flags = flags;
718e3744 2313
2314 if (gate)
2315 si->gate.ipv4 = *gate;
2316 if (ifname)
2317 si->gate.ifname = XSTRDUP (0, ifname);
2318
2319 /* Add new static route information to the tree with sort by
2320 distance value and gateway address. */
2321 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2322 {
2323 if (si->distance < cp->distance)
2324 break;
2325 if (si->distance > cp->distance)
2326 continue;
2327 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2328 {
2329 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2330 break;
2331 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2332 continue;
2333 }
2334 }
2335
2336 /* Make linked list. */
2337 if (pp)
2338 pp->next = si;
2339 else
2340 rn->info = si;
2341 if (cp)
2342 cp->prev = si;
2343 si->prev = pp;
2344 si->next = cp;
2345
2346 /* Install into rib. */
2347 static_install_ipv4 (p, si);
2348
2349 return 1;
2350}
2351
2352/* Delete static route from static route configuration. */
2353int
39db97e4 2354static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
718e3744 2355 u_char distance, u_int32_t vrf_id)
2356{
2357 u_char type = 0;
2358 struct route_node *rn;
2359 struct static_ipv4 *si;
2360 struct route_table *stable;
2361
2362 /* Lookup table. */
2363 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2364 if (! stable)
2365 return -1;
2366
2367 /* Lookup static route prefix. */
2368 rn = route_node_lookup (stable, p);
2369 if (! rn)
2370 return 0;
2371
2372 /* Make flags. */
2373 if (gate)
2374 type = STATIC_IPV4_GATEWAY;
2375 else if (ifname)
2376 type = STATIC_IPV4_IFNAME;
595db7f1 2377 else
2378 type = STATIC_IPV4_BLACKHOLE;
718e3744 2379
2380 /* Find same static route is the tree */
2381 for (si = rn->info; si; si = si->next)
2382 if (type == si->type
2383 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2384 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2385 break;
2386
2387 /* Can't find static route. */
2388 if (! si)
2389 {
2390 route_unlock_node (rn);
2391 return 0;
2392 }
2393
2394 /* Install into rib. */
2395 static_uninstall_ipv4 (p, si);
2396
2397 /* Unlink static route from linked list. */
2398 if (si->prev)
2399 si->prev->next = si->next;
2400 else
2401 rn->info = si->next;
2402 if (si->next)
2403 si->next->prev = si->prev;
143a385f 2404 route_unlock_node (rn);
718e3744 2405
2406 /* Free static route configuration. */
a0f6acd8 2407 if (ifname)
2408 XFREE (0, si->gate.ifname);
718e3744 2409 XFREE (MTYPE_STATIC_IPV4, si);
2410
143a385f 2411 route_unlock_node (rn);
2412
718e3744 2413 return 1;
2414}
2415
2416\f
2417#ifdef HAVE_IPV6
a1ac18c4 2418static int
718e3744 2419rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2420 struct in6_addr *gate, unsigned int ifindex, int table)
2421{
726f9b2b 2422 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2423#if defined (MUSICA) || defined (LINUX)
2424 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2425 if (p->prefixlen == 96)
2426 return 0;
2427#endif /* MUSICA */
718e3744 2428 return 1;
726f9b2b 2429 }
718e3744 2430 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
2431 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
2432 {
2433 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
2434 return 1;
2435 }
2436 return 0;
2437}
2438
2439int
2440rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
be61c4eb 2441 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
f768f367 2442 u_int32_t metric, u_char distance, safi_t safi)
718e3744 2443{
2444 struct rib *rib;
2445 struct rib *same = NULL;
2446 struct route_table *table;
2447 struct route_node *rn;
2448 struct nexthop *nexthop;
2449
718e3744 2450 /* Lookup table. */
f768f367 2451 table = vrf_table (AFI_IP6, safi, 0);
718e3744 2452 if (! table)
2453 return 0;
2454
2455 /* Make sure mask is applied. */
2456 apply_mask_ipv6 (p);
2457
2458 /* Set default distance by route type. */
be61c4eb 2459 if (!distance)
2460 distance = route_info[type].distance;
718e3744 2461
2462 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2463 distance = 200;
2464
2465 /* Filter bogus route. */
2466 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
2467 return 0;
2468
2469 /* Lookup route node.*/
2470 rn = route_node_get (table, (struct prefix *) p);
2471
2472 /* If same type of route are installed, treat it as a implicit
2473 withdraw. */
9fd92e3c 2474 RNODE_FOREACH_RIB (rn, rib)
718e3744 2475 {
6d691129
PJ
2476 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2477 continue;
2478
ebf1ead0 2479 if (rib->type != type)
2480 continue;
2481 if (rib->type != ZEBRA_ROUTE_CONNECT)
718e3744 2482 {
2483 same = rib;
718e3744 2484 break;
2485 }
ebf1ead0 2486 else if ((nexthop = rib->nexthop) &&
2487 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2488 nexthop->ifindex == ifindex)
2489 {
2490 rib->refcnt++;
2491 return 0;
2492 }
718e3744 2493 }
2494
2495 /* Allocate new rib structure. */
4d38fdb4 2496 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2497
718e3744 2498 rib->type = type;
2499 rib->distance = distance;
2500 rib->flags = flags;
2501 rib->metric = metric;
b5f45021 2502 rib->table = vrf_id;
718e3744 2503 rib->nexthop_num = 0;
2504 rib->uptime = time (NULL);
2505
2506 /* Nexthop settings. */
2507 if (gate)
2508 {
2509 if (ifindex)
2510 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2511 else
2512 nexthop_ipv6_add (rib, gate);
2513 }
2514 else
2515 nexthop_ifindex_add (rib, ifindex);
2516
2517 /* If this route is kernel route, set FIB flag to the route. */
2518 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2519 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2520 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2521
2522 /* Link new rib to node.*/
2523 rib_addnode (rn, rib);
2524
718e3744 2525 /* Free implicit route.*/
2526 if (same)
4d38fdb4 2527 rib_delnode (rn, same);
2528
2529 route_unlock_node (rn);
718e3744 2530 return 0;
2531}
2532
ebf1ead0 2533/* XXX factor with rib_delete_ipv6 */
718e3744 2534int
2535rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
f768f367 2536 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
718e3744 2537{
2538 struct route_table *table;
2539 struct route_node *rn;
2540 struct rib *rib;
2541 struct rib *fib = NULL;
2542 struct rib *same = NULL;
2543 struct nexthop *nexthop;
81cce018
SH
2544 char buf1[INET6_ADDRSTRLEN];
2545 char buf2[INET6_ADDRSTRLEN];
718e3744 2546
2547 /* Apply mask. */
2548 apply_mask_ipv6 (p);
2549
2550 /* Lookup table. */
f768f367 2551 table = vrf_table (AFI_IP6, safi, 0);
718e3744 2552 if (! table)
2553 return 0;
4d38fdb4 2554
718e3744 2555 /* Lookup route node. */
2556 rn = route_node_lookup (table, (struct prefix *) p);
2557 if (! rn)
2558 {
2559 if (IS_ZEBRA_DEBUG_KERNEL)
2560 {
2561 if (gate)
b6178002 2562 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
81cce018 2563 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
718e3744 2564 p->prefixlen,
81cce018 2565 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
718e3744 2566 ifindex);
2567 else
b6178002 2568 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
81cce018 2569 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
718e3744 2570 p->prefixlen,
2571 ifindex);
2572 }
2573 return ZEBRA_ERR_RTNOEXIST;
2574 }
2575
2576 /* Lookup same type route. */
9fd92e3c 2577 RNODE_FOREACH_RIB (rn, rib)
718e3744 2578 {
6d691129
PJ
2579 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2580 continue;
2581
718e3744 2582 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2583 fib = rib;
2584
ebf1ead0 2585 if (rib->type != type)
2586 continue;
2587 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
4f1735fd 2588 nexthop->type == NEXTHOP_TYPE_IFINDEX)
718e3744 2589 {
4f1735fd
MF
2590 if (nexthop->ifindex != ifindex)
2591 continue;
ebf1ead0 2592 if (rib->refcnt)
718e3744 2593 {
ebf1ead0 2594 rib->refcnt--;
2595 route_unlock_node (rn);
2596 route_unlock_node (rn);
2597 return 0;
718e3744 2598 }
ebf1ead0 2599 same = rib;
2600 break;
718e3744 2601 }
ebf1ead0 2602 /* Make sure that the route found has the same gateway. */
2603 else if (gate == NULL ||
2604 ((nexthop = rib->nexthop) &&
2605 (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate) ||
2606 IPV6_ADDR_SAME (&nexthop->rgate.ipv6, gate))))
718e3744 2607 {
ebf1ead0 2608 same = rib;
2609 break;
718e3744 2610 }
2611 }
2612
2613 /* If same type of route can't be found and this message is from
2614 kernel. */
2615 if (! same)
2616 {
2617 if (fib && type == ZEBRA_ROUTE_KERNEL)
2618 {
2619 /* Unset flags. */
2620 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2621 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2622
2623 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2624 }
2625 else
2626 {
2627 if (IS_ZEBRA_DEBUG_KERNEL)
2628 {
2629 if (gate)
b6178002 2630 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
81cce018 2631 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
718e3744 2632 p->prefixlen,
81cce018 2633 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
718e3744 2634 ifindex,
2635 type);
2636 else
b6178002 2637 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
81cce018 2638 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
718e3744 2639 p->prefixlen,
2640 ifindex,
2641 type);
2642 }
2643 route_unlock_node (rn);
2644 return ZEBRA_ERR_RTNOEXIST;
2645 }
2646 }
2647
718e3744 2648 if (same)
4d38fdb4 2649 rib_delnode (rn, same);
2650
718e3744 2651 route_unlock_node (rn);
718e3744 2652 return 0;
2653}
2654\f
2655/* Install static route into rib. */
a1ac18c4 2656static void
718e3744 2657static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2658{
2659 struct rib *rib;
2660 struct route_table *table;
2661 struct route_node *rn;
2662
2663 /* Lookup table. */
2664 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2665 if (! table)
2666 return;
2667
2668 /* Lookup existing route */
2669 rn = route_node_get (table, p);
9fd92e3c 2670 RNODE_FOREACH_RIB (rn, rib)
6d691129
PJ
2671 {
2672 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2673 continue;
2674
2675 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2676 break;
2677 }
718e3744 2678
2679 if (rib)
2680 {
2681 /* Same distance static route is there. Update it with new
2682 nexthop. */
718e3744 2683 route_unlock_node (rn);
2684
2685 switch (si->type)
2686 {
2687 case STATIC_IPV6_GATEWAY:
2688 nexthop_ipv6_add (rib, &si->ipv6);
2689 break;
2690 case STATIC_IPV6_IFNAME:
2691 nexthop_ifname_add (rib, si->ifname);
2692 break;
2693 case STATIC_IPV6_GATEWAY_IFNAME:
2694 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2695 break;
2696 }
3c0755dc 2697 rib_queue_add (&zebrad, rn);
718e3744 2698 }
2699 else
2700 {
2701 /* This is new static route. */
4d38fdb4 2702 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2703
718e3744 2704 rib->type = ZEBRA_ROUTE_STATIC;
2705 rib->distance = si->distance;
2706 rib->metric = 0;
2707 rib->nexthop_num = 0;
2708
2709 switch (si->type)
2710 {
2711 case STATIC_IPV6_GATEWAY:
2712 nexthop_ipv6_add (rib, &si->ipv6);
2713 break;
2714 case STATIC_IPV6_IFNAME:
2715 nexthop_ifname_add (rib, si->ifname);
2716 break;
2717 case STATIC_IPV6_GATEWAY_IFNAME:
2718 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2719 break;
2720 }
2721
81dfcaa2 2722 /* Save the flags of this static routes (reject, blackhole) */
2723 rib->flags = si->flags;
2724
718e3744 2725 /* Link this rib to the tree. */
2726 rib_addnode (rn, rib);
718e3744 2727 }
2728}
2729
a1ac18c4 2730static int
718e3744 2731static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2732{
2733 if (nexthop->type == NEXTHOP_TYPE_IPV6
2734 && si->type == STATIC_IPV6_GATEWAY
2735 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2736 return 1;
2737 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2738 && si->type == STATIC_IPV6_IFNAME
2739 && strcmp (nexthop->ifname, si->ifname) == 0)
2740 return 1;
2741 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2742 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2743 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2744 && strcmp (nexthop->ifname, si->ifname) == 0)
2745 return 1;
e8e1946e 2746 return 0;
718e3744 2747}
2748
a1ac18c4 2749static void
718e3744 2750static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2751{
2752 struct route_table *table;
2753 struct route_node *rn;
2754 struct rib *rib;
2755 struct nexthop *nexthop;
2756
2757 /* Lookup table. */
2758 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2759 if (! table)
2760 return;
2761
2762 /* Lookup existing route with type and distance. */
2763 rn = route_node_lookup (table, (struct prefix *) p);
2764 if (! rn)
2765 return;
2766
9fd92e3c 2767 RNODE_FOREACH_RIB (rn, rib)
6d691129
PJ
2768 {
2769 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2770 continue;
2771
2772 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2773 break;
2774 }
2775
718e3744 2776 if (! rib)
2777 {
2778 route_unlock_node (rn);
2779 return;
2780 }
2781
2782 /* Lookup nexthop. */
2783 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2784 if (static_ipv6_nexthop_same (nexthop, si))
2785 break;
2786
2787 /* Can't find nexthop. */
2788 if (! nexthop)
2789 {
2790 route_unlock_node (rn);
2791 return;
2792 }
2793
2794 /* Check nexthop. */
2795 if (rib->nexthop_num == 1)
2796 {
2797 rib_delnode (rn, rib);
718e3744 2798 }
2799 else
2800 {
6baeb988 2801 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2802 rib_uninstall (rn, rib);
319572cc 2803 nexthop_delete (rib, nexthop);
2804 nexthop_free (nexthop);
6d691129 2805 rib_queue_add (&zebrad, rn);
718e3744 2806 }
718e3744 2807 /* Unlock node. */
2808 route_unlock_node (rn);
2809}
2810
2811/* Add static route into static route configuration. */
2812int
2813static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
39db97e4 2814 const char *ifname, u_char flags, u_char distance,
2815 u_int32_t vrf_id)
718e3744 2816{
2817 struct route_node *rn;
2818 struct static_ipv6 *si;
2819 struct static_ipv6 *pp;
2820 struct static_ipv6 *cp;
2821 struct route_table *stable;
2822
2823 /* Lookup table. */
2824 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2825 if (! stable)
2826 return -1;
27b47253
PJ
2827
2828 if (!gate &&
2829 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
2830 return -1;
2831
2832 if (!ifname &&
2833 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
2834 return -1;
718e3744 2835
2836 /* Lookup static route prefix. */
2837 rn = route_node_get (stable, p);
2838
2839 /* Do nothing if there is a same static route. */
2840 for (si = rn->info; si; si = si->next)
2841 {
2842 if (distance == si->distance
2843 && type == si->type
2844 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2845 && (! ifname || strcmp (ifname, si->ifname) == 0))
2846 {
2847 route_unlock_node (rn);
2848 return 0;
2849 }
2850 }
2851
2852 /* Make new static route structure. */
393deb9b 2853 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
718e3744 2854
2855 si->type = type;
2856 si->distance = distance;
81dfcaa2 2857 si->flags = flags;
718e3744 2858
2859 switch (type)
2860 {
2861 case STATIC_IPV6_GATEWAY:
2862 si->ipv6 = *gate;
2863 break;
2864 case STATIC_IPV6_IFNAME:
2865 si->ifname = XSTRDUP (0, ifname);
2866 break;
2867 case STATIC_IPV6_GATEWAY_IFNAME:
2868 si->ipv6 = *gate;
2869 si->ifname = XSTRDUP (0, ifname);
2870 break;
2871 }
2872
2873 /* Add new static route information to the tree with sort by
2874 distance value and gateway address. */
2875 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2876 {
2877 if (si->distance < cp->distance)
2878 break;
2879 if (si->distance > cp->distance)
2880 continue;
2881 }
2882
2883 /* Make linked list. */
2884 if (pp)
2885 pp->next = si;
2886 else
2887 rn->info = si;
2888 if (cp)
2889 cp->prev = si;
2890 si->prev = pp;
2891 si->next = cp;
2892
2893 /* Install into rib. */
2894 static_install_ipv6 (p, si);
2895
2896 return 1;
2897}
2898
2899/* Delete static route from static route configuration. */
2900int
2901static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
39db97e4 2902 const char *ifname, u_char distance, u_int32_t vrf_id)
718e3744 2903{
2904 struct route_node *rn;
2905 struct static_ipv6 *si;
2906 struct route_table *stable;
2907
2908 /* Lookup table. */
2909 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2910 if (! stable)
2911 return -1;
2912
2913 /* Lookup static route prefix. */
2914 rn = route_node_lookup (stable, p);
2915 if (! rn)
2916 return 0;
2917
2918 /* Find same static route is the tree */
2919 for (si = rn->info; si; si = si->next)
2920 if (distance == si->distance
2921 && type == si->type
2922 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2923 && (! ifname || strcmp (ifname, si->ifname) == 0))
2924 break;
2925
2926 /* Can't find static route. */
2927 if (! si)
2928 {
2929 route_unlock_node (rn);
2930 return 0;
2931 }
2932
2933 /* Install into rib. */
2934 static_uninstall_ipv6 (p, si);
2935
2936 /* Unlink static route from linked list. */
2937 if (si->prev)
2938 si->prev->next = si->next;
2939 else
2940 rn->info = si->next;
2941 if (si->next)
2942 si->next->prev = si->prev;
2943
2944 /* Free static route configuration. */
a0f6acd8 2945 if (ifname)
2946 XFREE (0, si->ifname);
718e3744 2947 XFREE (MTYPE_STATIC_IPV6, si);
2948
2949 return 1;
2950}
2951#endif /* HAVE_IPV6 */
2952\f
2953/* RIB update function. */
2954void
a1ac18c4 2955rib_update (void)
718e3744 2956{
2957 struct route_node *rn;
2958 struct route_table *table;
4d38fdb4 2959
718e3744 2960 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2961 if (table)
2962 for (rn = route_top (table); rn; rn = route_next (rn))
9fd92e3c 2963 if (rnode_to_ribs (rn))
6d691129 2964 rib_queue_add (&zebrad, rn);
718e3744 2965
2966 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2967 if (table)
2968 for (rn = route_top (table); rn; rn = route_next (rn))
9fd92e3c 2969 if (rnode_to_ribs (rn))
6d691129 2970 rib_queue_add (&zebrad, rn);
718e3744 2971}
2972
718e3744 2973\f
2974/* Remove all routes which comes from non main table. */
a1ac18c4 2975static void
718e3744 2976rib_weed_table (struct route_table *table)
2977{
2978 struct route_node *rn;
2979 struct rib *rib;
2980 struct rib *next;
2981
2982 if (table)
2983 for (rn = route_top (table); rn; rn = route_next (rn))
9fd92e3c 2984 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
718e3744 2985 {
6d691129
PJ
2986 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2987 continue;
2988
b21b19c5 2989 if (rib->table != zebrad.rtm_table_default &&
718e3744 2990 rib->table != RT_TABLE_MAIN)
4d38fdb4 2991 rib_delnode (rn, rib);
718e3744 2992 }
2993}
2994
2995/* Delete all routes from non main table. */
2996void
a1ac18c4 2997rib_weed_tables (void)
718e3744 2998{
2999 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3000 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3001}
3002\f
3003/* Delete self installed routes after zebra is relaunched. */
a1ac18c4 3004static void
718e3744 3005rib_sweep_table (struct route_table *table)
3006{
3007 struct route_node *rn;
3008 struct rib *rib;
3009 struct rib *next;
3010 int ret = 0;
3011
3012 if (table)
3013 for (rn = route_top (table); rn; rn = route_next (rn))
9fd92e3c 3014 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
718e3744 3015 {
6d691129
PJ
3016 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3017 continue;
3018
718e3744 3019 if (rib->type == ZEBRA_ROUTE_KERNEL &&
3020 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
3021 {
3022 ret = rib_uninstall_kernel (rn, rib);
3023 if (! ret)
4d38fdb4 3024 rib_delnode (rn, rib);
718e3744 3025 }
3026 }
3027}
3028
3029/* Sweep all RIB tables. */
3030void
a1ac18c4 3031rib_sweep_route (void)
718e3744 3032{
3033 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3034 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3035}
2ea1ab1c
VT
3036
3037/* Remove specific by protocol routes from 'table'. */
3038static unsigned long
3039rib_score_proto_table (u_char proto, struct route_table *table)
3040{
3041 struct route_node *rn;
3042 struct rib *rib;
3043 struct rib *next;
3044 unsigned long n = 0;
3045
3046 if (table)
3047 for (rn = route_top (table); rn; rn = route_next (rn))
9fd92e3c 3048 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
2ea1ab1c 3049 {
2ea1ab1c
VT
3050 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3051 continue;
3052 if (rib->type == proto)
3053 {
3054 rib_delnode (rn, rib);
3055 n++;
3056 }
3057 }
3058
3059 return n;
3060}
3061
3062/* Remove specific by protocol routes. */
3063unsigned long
3064rib_score_proto (u_char proto)
3065{
3066 return rib_score_proto_table (proto, vrf_table (AFI_IP, SAFI_UNICAST, 0))
3067 +rib_score_proto_table (proto, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3068}
3069
718e3744 3070/* Close RIB and clean up kernel routes. */
a1ac18c4 3071static void
718e3744 3072rib_close_table (struct route_table *table)
3073{
3074 struct route_node *rn;
3075 struct rib *rib;
3076
3077 if (table)
3078 for (rn = route_top (table); rn; rn = route_next (rn))
9fd92e3c 3079 RNODE_FOREACH_RIB (rn, rib)
6d691129 3080 {
9fd92e3c
AS
3081 if (!CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
3082 continue;
3083
3084 if (! RIB_SYSTEM_ROUTE (rib))
3085 rib_uninstall_kernel (rn, rib);
6d691129 3086 }
718e3744 3087}
3088
3089/* Close all RIB tables. */
3090void
a1ac18c4 3091rib_close (void)
718e3744 3092{
3093 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3094 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3095}
3096\f
3097/* Routing information base initialize. */
3098void
a1ac18c4 3099rib_init (void)
718e3744 3100{
4d38fdb4 3101 rib_queue_init (&zebrad);
718e3744 3102 /* VRF initialization. */
3103 vrf_init ();
3104}
0915bb0c
AS
3105
3106/*
3107 * vrf_id_get_next
3108 *
3109 * Get the first vrf id that is greater than the given vrf id if any.
3110 *
3111 * Returns TRUE if a vrf id was found, FALSE otherwise.
3112 */
3113static inline int
3114vrf_id_get_next (uint32_t id, uint32_t *next_id_p)
3115{
3116 while (++id < vector_active (vrf_vector))
3117 {
3118 if (vrf_lookup (id))
3119 {
3120 *next_id_p = id;
3121 return 1;
3122 }
3123 }
3124
3125 return 0;
3126}
3127
3128/*
3129 * rib_tables_iter_next
3130 *
3131 * Returns the next table in the iteration.
3132 */
3133struct route_table *
3134rib_tables_iter_next (rib_tables_iter_t *iter)
3135{
3136 struct route_table *table;
3137
3138 /*
3139 * Array that helps us go over all AFI/SAFI combinations via one
3140 * index.
3141 */
3142 static struct {
3143 afi_t afi;
3144 safi_t safi;
3145 } afi_safis[] = {
3146 { AFI_IP, SAFI_UNICAST },
3147 { AFI_IP, SAFI_MULTICAST },
3148 { AFI_IP6, SAFI_UNICAST },
3149 { AFI_IP6, SAFI_MULTICAST },
3150 };
3151
3152 table = NULL;
3153
3154 switch (iter->state)
3155 {
3156
3157 case RIB_TABLES_ITER_S_INIT:
3158 iter->vrf_id = 0;
3159 iter->afi_safi_ix = -1;
3160
3161 /* Fall through */
3162
3163 case RIB_TABLES_ITER_S_ITERATING:
3164 iter->afi_safi_ix++;
3165 while (1)
3166 {
3167
3168 while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
3169 {
3170 table = vrf_table (afi_safis[iter->afi_safi_ix].afi,
3171 afi_safis[iter->afi_safi_ix].safi,
3172 iter->vrf_id);
3173 if (table)
3174 break;
3175
3176 iter->afi_safi_ix++;
3177 }
3178
3179 /*
3180 * Found another table in this vrf.
3181 */
3182 if (table)
3183 break;
3184
3185 /*
3186 * Done with all tables in the current vrf, go to the next
3187 * one.
3188 */
3189 if (!vrf_id_get_next (iter->vrf_id, &iter->vrf_id))
3190 break;
3191
3192 iter->afi_safi_ix = 0;
3193 }
3194
3195 break;
3196
3197 case RIB_TABLES_ITER_S_DONE:
3198 return NULL;
3199 }
3200
3201 if (table)
3202 iter->state = RIB_TABLES_ITER_S_ITERATING;
3203 else
3204 iter->state = RIB_TABLES_ITER_S_DONE;
3205
3206 return table;
3207}