]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_rib.c
Tiny fixes from 6Wind patch.
[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"
32
33#include "zebra/rib.h"
34#include "zebra/rt.h"
35#include "zebra/zserv.h"
36#include "zebra/redistribute.h"
37#include "zebra/debug.h"
38
39/* Default rtm_table for all clients */
40extern int rtm_table_default;
41
42/* Each route type's string and default distance value. */
43struct
44{
45 int key;
46 int distance;
47} route_info[] =
48{
49 {ZEBRA_ROUTE_SYSTEM, 0},
50 {ZEBRA_ROUTE_KERNEL, 0},
51 {ZEBRA_ROUTE_CONNECT, 0},
52 {ZEBRA_ROUTE_STATIC, 1},
53 {ZEBRA_ROUTE_RIP, 120},
54 {ZEBRA_ROUTE_RIPNG, 120},
55 {ZEBRA_ROUTE_OSPF, 110},
56 {ZEBRA_ROUTE_OSPF6, 110},
57 {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */}
58};
59\f
60/* Vector for routing table. */
61vector vrf_vector;
62
63/* Allocate new VRF. */
64struct vrf *
65vrf_alloc (char *name)
66{
67 struct vrf *vrf;
68
69 vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
70
71 /* Put name. */
72 if (name)
73 vrf->name = XSTRDUP (MTYPE_VRF_NAME, name);
74
75 /* Allocate routing table and static table. */
76 vrf->table[AFI_IP][SAFI_UNICAST] = route_table_init ();
77 vrf->table[AFI_IP6][SAFI_UNICAST] = route_table_init ();
78 vrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
79 vrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
80
81 return vrf;
82}
83
84/* Free VRF. */
85void
86vrf_free (struct vrf *vrf)
87{
88 if (vrf->name)
89 XFREE (MTYPE_VRF_NAME, vrf->name);
90 XFREE (MTYPE_VRF, vrf);
91}
92
93/* Lookup VRF by identifier. */
94struct vrf *
95vrf_lookup (u_int32_t id)
96{
97 return vector_lookup (vrf_vector, id);
98}
99
100/* Lookup VRF by name. */
101struct vrf *
102vrf_lookup_by_name (char *name)
103{
104 int i;
105 struct vrf *vrf;
106
107 for (i = 0; i < vector_max (vrf_vector); i++)
108 if ((vrf = vector_slot (vrf_vector, i)) != NULL)
109 if (vrf->name && name && strcmp (vrf->name, name) == 0)
110 return vrf;
111 return NULL;
112}
113
114/* Initialize VRF. */
115void
116vrf_init ()
117{
118 struct vrf *default_table;
119
120 /* Allocate VRF vector. */
121 vrf_vector = vector_init (1);
122
123 /* Allocate default main table. */
124 default_table = vrf_alloc ("Default-IP-Routing-Table");
125
126 /* Default table index must be 0. */
127 vector_set_index (vrf_vector, 0, default_table);
128}
129
130/* Lookup route table. */
131struct route_table *
132vrf_table (afi_t afi, safi_t safi, u_int32_t id)
133{
134 struct vrf *vrf;
135
136 vrf = vrf_lookup (id);
137 if (! vrf)
138 return NULL;
139
140 return vrf->table[afi][safi];
141}
142
143/* Lookup static route table. */
144struct route_table *
145vrf_static_table (afi_t afi, safi_t safi, u_int32_t id)
146{
147 struct vrf *vrf;
148
149 vrf = vrf_lookup (id);
150 if (! vrf)
151 return NULL;
152
153 return vrf->stable[afi][safi];
154}
155\f
156/* Add nexthop to the end of the list. */
157void
158nexthop_add (struct rib *rib, struct nexthop *nexthop)
159{
160 struct nexthop *last;
161
162 for (last = rib->nexthop; last && last->next; last = last->next)
163 ;
164 if (last)
165 last->next = nexthop;
166 else
167 rib->nexthop = nexthop;
168 nexthop->prev = last;
169
170 rib->nexthop_num++;
171}
172
173/* Delete specified nexthop from the list. */
174void
175nexthop_delete (struct rib *rib, struct nexthop *nexthop)
176{
177 if (nexthop->next)
178 nexthop->next->prev = nexthop->prev;
179 if (nexthop->prev)
180 nexthop->prev->next = nexthop->next;
181 else
182 rib->nexthop = nexthop->next;
183 rib->nexthop_num--;
184}
185
186/* Free nexthop. */
187void
188nexthop_free (struct nexthop *nexthop)
189{
a4b70768 190 if (nexthop->ifname)
191 XFREE (0, nexthop->ifname);
718e3744 192 XFREE (MTYPE_NEXTHOP, nexthop);
193}
194
195struct nexthop *
196nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
197{
198 struct nexthop *nexthop;
199
200 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
201 memset (nexthop, 0, sizeof (struct nexthop));
202 nexthop->type = NEXTHOP_TYPE_IFINDEX;
203 nexthop->ifindex = ifindex;
204
205 nexthop_add (rib, nexthop);
206
207 return nexthop;
208}
209
210struct nexthop *
211nexthop_ifname_add (struct rib *rib, char *ifname)
212{
213 struct nexthop *nexthop;
214
215 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
216 memset (nexthop, 0, sizeof (struct nexthop));
217 nexthop->type = NEXTHOP_TYPE_IFNAME;
a4b70768 218 nexthop->ifname = XSTRDUP (0, ifname);
718e3744 219
220 nexthop_add (rib, nexthop);
221
222 return nexthop;
223}
224
225struct nexthop *
226nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4)
227{
228 struct nexthop *nexthop;
229
230 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
231 memset (nexthop, 0, sizeof (struct nexthop));
232 nexthop->type = NEXTHOP_TYPE_IPV4;
233 nexthop->gate.ipv4 = *ipv4;
234
235 nexthop_add (rib, nexthop);
236
237 return nexthop;
238}
239
240struct nexthop *
241nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
242 unsigned int ifindex)
243{
244 struct nexthop *nexthop;
245
246 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
247 memset (nexthop, 0, sizeof (struct nexthop));
248 nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
249 nexthop->gate.ipv4 = *ipv4;
250 nexthop->ifindex = ifindex;
251
252 nexthop_add (rib, nexthop);
253
254 return nexthop;
255}
256
257#ifdef HAVE_IPV6
258struct nexthop *
259nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
260{
261 struct nexthop *nexthop;
262
263 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
264 memset (nexthop, 0, sizeof (struct nexthop));
265 nexthop->type = NEXTHOP_TYPE_IPV6;
266 nexthop->gate.ipv6 = *ipv6;
267
268 nexthop_add (rib, nexthop);
269
270 return nexthop;
271}
272
273struct nexthop *
274nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
275 char *ifname)
276{
277 struct nexthop *nexthop;
278
279 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
280 memset (nexthop, 0, sizeof (struct nexthop));
281 nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
282 nexthop->gate.ipv6 = *ipv6;
283 nexthop->ifname = XSTRDUP (0, ifname);
284
285 nexthop_add (rib, nexthop);
286
287 return nexthop;
288}
289
290struct nexthop *
291nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
292 unsigned int ifindex)
293{
294 struct nexthop *nexthop;
295
296 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
297 memset (nexthop, 0, sizeof (struct nexthop));
298 nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
299 nexthop->gate.ipv6 = *ipv6;
300 nexthop->ifindex = ifindex;
301
302 nexthop_add (rib, nexthop);
303
304 return nexthop;
305}
306#endif /* HAVE_IPV6 */
307
595db7f1 308struct nexthop *
309nexthop_blackhole_add (struct rib *rib)
310{
311 struct nexthop *nexthop;
312
313 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
314 memset (nexthop, 0, sizeof (struct nexthop));
315 nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
316 SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
317
318 nexthop_add (rib, nexthop);
319
320 return nexthop;
321}
322
718e3744 323/* If force flag is not set, do not modify falgs at all for uninstall
324 the route from FIB. */
325int
326nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
327 struct route_node *top)
328{
329 struct prefix_ipv4 p;
330 struct route_table *table;
331 struct route_node *rn;
332 struct rib *match;
333 struct nexthop *newhop;
334
335 if (nexthop->type == NEXTHOP_TYPE_IPV4)
336 nexthop->ifindex = 0;
337
338 if (set)
339 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
340
341 /* Make lookup prefix. */
342 memset (&p, 0, sizeof (struct prefix_ipv4));
343 p.family = AF_INET;
344 p.prefixlen = IPV4_MAX_PREFIXLEN;
345 p.prefix = nexthop->gate.ipv4;
346
347 /* Lookup table. */
348 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
349 if (! table)
350 return 0;
351
352 rn = route_node_match (table, (struct prefix *) &p);
353 while (rn)
354 {
355 route_unlock_node (rn);
356
357 /* If lookup self prefix return immidiately. */
358 if (rn == top)
359 return 0;
360
361 /* Pick up selected route. */
362 for (match = rn->info; match; match = match->next)
363 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
364 break;
365
366 /* If there is no selected route or matched route is EGP, go up
367 tree. */
368 if (! match
369 || match->type == ZEBRA_ROUTE_BGP)
370 {
371 do {
372 rn = rn->parent;
373 } while (rn && rn->info == NULL);
374 if (rn)
375 route_lock_node (rn);
376 }
377 else
378 {
379 if (match->type == ZEBRA_ROUTE_CONNECT)
380 {
381 /* Directly point connected route. */
382 newhop = match->nexthop;
383 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
384 nexthop->ifindex = newhop->ifindex;
385
386 return 1;
387 }
388 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
389 {
390 for (newhop = match->nexthop; newhop; newhop = newhop->next)
391 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
392 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
393 {
394 if (set)
395 {
396 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
397 nexthop->rtype = newhop->type;
398 if (newhop->type == NEXTHOP_TYPE_IPV4 ||
399 newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
400 nexthop->rgate.ipv4 = newhop->gate.ipv4;
401 if (newhop->type == NEXTHOP_TYPE_IFINDEX
402 || newhop->type == NEXTHOP_TYPE_IFNAME
403 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
404 nexthop->rifindex = newhop->ifindex;
405 }
406 return 1;
407 }
408 return 0;
409 }
410 else
411 {
412 return 0;
413 }
414 }
415 }
416 return 0;
417}
418
419#ifdef HAVE_IPV6
420/* If force flag is not set, do not modify falgs at all for uninstall
421 the route from FIB. */
422int
423nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
424 struct route_node *top)
425{
426 struct prefix_ipv6 p;
427 struct route_table *table;
428 struct route_node *rn;
429 struct rib *match;
430 struct nexthop *newhop;
431
432 if (nexthop->type == NEXTHOP_TYPE_IPV6)
433 nexthop->ifindex = 0;
434
435 if (set)
436 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
437
438 /* Make lookup prefix. */
439 memset (&p, 0, sizeof (struct prefix_ipv6));
440 p.family = AF_INET6;
441 p.prefixlen = IPV6_MAX_PREFIXLEN;
442 p.prefix = nexthop->gate.ipv6;
443
444 /* Lookup table. */
445 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
446 if (! table)
447 return 0;
448
449 rn = route_node_match (table, (struct prefix *) &p);
450 while (rn)
451 {
452 route_unlock_node (rn);
453
454 /* If lookup self prefix return immidiately. */
455 if (rn == top)
456 return 0;
457
458 /* Pick up selected route. */
459 for (match = rn->info; match; match = match->next)
460 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
461 break;
462
463 /* If there is no selected route or matched route is EGP, go up
464 tree. */
465 if (! match
466 || match->type == ZEBRA_ROUTE_BGP)
467 {
468 do {
469 rn = rn->parent;
470 } while (rn && rn->info == NULL);
471 if (rn)
472 route_lock_node (rn);
473 }
474 else
475 {
476 if (match->type == ZEBRA_ROUTE_CONNECT)
477 {
478 /* Directly point connected route. */
479 newhop = match->nexthop;
480
481 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
482 nexthop->ifindex = newhop->ifindex;
483
484 return 1;
485 }
486 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
487 {
488 for (newhop = match->nexthop; newhop; newhop = newhop->next)
489 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
490 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
491 {
492 if (set)
493 {
494 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
495 nexthop->rtype = newhop->type;
496 if (newhop->type == NEXTHOP_TYPE_IPV6
497 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
498 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
499 nexthop->rgate.ipv6 = newhop->gate.ipv6;
500 if (newhop->type == NEXTHOP_TYPE_IFINDEX
501 || newhop->type == NEXTHOP_TYPE_IFNAME
502 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
503 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
504 nexthop->rifindex = newhop->ifindex;
505 }
506 return 1;
507 }
508 return 0;
509 }
510 else
511 {
512 return 0;
513 }
514 }
515 }
516 return 0;
517}
518#endif /* HAVE_IPV6 */
519
520struct rib *
521rib_match_ipv4 (struct in_addr addr)
522{
523 struct prefix_ipv4 p;
524 struct route_table *table;
525 struct route_node *rn;
526 struct rib *match;
527 struct nexthop *newhop;
528
529 /* Lookup table. */
530 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
531 if (! table)
532 return 0;
533
534 memset (&p, 0, sizeof (struct prefix_ipv4));
535 p.family = AF_INET;
536 p.prefixlen = IPV4_MAX_PREFIXLEN;
537 p.prefix = addr;
538
539 rn = route_node_match (table, (struct prefix *) &p);
540
541 while (rn)
542 {
543 route_unlock_node (rn);
544
545 /* Pick up selected route. */
546 for (match = rn->info; match; match = match->next)
547 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
548 break;
549
550 /* If there is no selected route or matched route is EGP, go up
551 tree. */
552 if (! match
553 || match->type == ZEBRA_ROUTE_BGP)
554 {
555 do {
556 rn = rn->parent;
557 } while (rn && rn->info == NULL);
558 if (rn)
559 route_lock_node (rn);
560 }
561 else
562 {
563 if (match->type == ZEBRA_ROUTE_CONNECT)
564 /* Directly point connected route. */
565 return match;
566 else
567 {
568 for (newhop = match->nexthop; newhop; newhop = newhop->next)
569 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
570 return match;
571 return NULL;
572 }
573 }
574 }
575 return NULL;
576}
577
578struct rib *
579rib_lookup_ipv4 (struct prefix_ipv4 *p)
580{
581 struct route_table *table;
582 struct route_node *rn;
583 struct rib *match;
584 struct nexthop *nexthop;
585
586 /* Lookup table. */
587 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
588 if (! table)
589 return 0;
590
591 rn = route_node_lookup (table, (struct prefix *) p);
592
593 /* No route for this prefix. */
594 if (! rn)
595 return NULL;
596
597 /* Unlock node. */
598 route_unlock_node (rn);
599
600 /* Pick up selected route. */
601 for (match = rn->info; match; match = match->next)
602 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
603 break;
604
605 if (! match || match->type == ZEBRA_ROUTE_BGP)
606 return NULL;
607
608 if (match->type == ZEBRA_ROUTE_CONNECT)
609 return match;
610
611 for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
612 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
613 return match;
614
615 return NULL;
616}
617
618#ifdef HAVE_IPV6
619struct rib *
620rib_match_ipv6 (struct in6_addr *addr)
621{
622 struct prefix_ipv6 p;
623 struct route_table *table;
624 struct route_node *rn;
625 struct rib *match;
626 struct nexthop *newhop;
627
628 /* Lookup table. */
629 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
630 if (! table)
631 return 0;
632
633 memset (&p, 0, sizeof (struct prefix_ipv6));
634 p.family = AF_INET6;
635 p.prefixlen = IPV6_MAX_PREFIXLEN;
636 IPV6_ADDR_COPY (&p.prefix, addr);
637
638 rn = route_node_match (table, (struct prefix *) &p);
639
640 while (rn)
641 {
642 route_unlock_node (rn);
643
644 /* Pick up selected route. */
645 for (match = rn->info; match; match = match->next)
646 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
647 break;
648
649 /* If there is no selected route or matched route is EGP, go up
650 tree. */
651 if (! match
652 || match->type == ZEBRA_ROUTE_BGP)
653 {
654 do {
655 rn = rn->parent;
656 } while (rn && rn->info == NULL);
657 if (rn)
658 route_lock_node (rn);
659 }
660 else
661 {
662 if (match->type == ZEBRA_ROUTE_CONNECT)
663 /* Directly point connected route. */
664 return match;
665 else
666 {
667 for (newhop = match->nexthop; newhop; newhop = newhop->next)
668 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
669 return match;
670 return NULL;
671 }
672 }
673 }
674 return NULL;
675}
676#endif /* HAVE_IPV6 */
677
678int
679nexthop_active_check (struct route_node *rn, struct rib *rib,
680 struct nexthop *nexthop, int set)
681{
682 struct interface *ifp;
683
684 switch (nexthop->type)
685 {
686 case NEXTHOP_TYPE_IFINDEX:
687 ifp = if_lookup_by_index (nexthop->ifindex);
688 if (ifp && if_is_up (ifp))
689 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
690 else
691 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
692 break;
693 case NEXTHOP_TYPE_IFNAME:
694 case NEXTHOP_TYPE_IPV6_IFNAME:
695 ifp = if_lookup_by_name (nexthop->ifname);
696 if (ifp && if_is_up (ifp))
697 {
698 if (set)
699 nexthop->ifindex = ifp->ifindex;
700 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
701 }
702 else
703 {
704 if (set)
705 nexthop->ifindex = 0;
706 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
707 }
708 break;
709 case NEXTHOP_TYPE_IPV4:
710 case NEXTHOP_TYPE_IPV4_IFINDEX:
711 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
712 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
713 else
714 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
715 break;
716#ifdef HAVE_IPV6
717 case NEXTHOP_TYPE_IPV6:
718 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
719 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
720 else
721 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
722 break;
723 case NEXTHOP_TYPE_IPV6_IFINDEX:
724 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
725 {
726 ifp = if_lookup_by_index (nexthop->ifindex);
727 if (ifp && if_is_up (ifp))
728 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
729 else
730 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
731 }
732 else
733 {
734 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
735 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
736 else
737 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
738 }
739 break;
740#endif /* HAVE_IPV6 */
595db7f1 741 case NEXTHOP_TYPE_BLACKHOLE:
742 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
743 break;
718e3744 744 default:
745 break;
746 }
747 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
748}
749
750int
751nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
752{
753 struct nexthop *nexthop;
754 int active;
755
756 rib->nexthop_active_num = 0;
757 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
758
759 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
760 {
761 active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
762 rib->nexthop_active_num += nexthop_active_check (rn, rib, nexthop, set);
763 if (active != CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
764 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
765 }
766 return rib->nexthop_active_num;
767}
768\f
769#define RIB_SYSTEM_ROUTE(R) \
770 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
771
772void
773newrib_free (struct rib *rib)
774{
775 struct nexthop *nexthop;
776 struct nexthop *next;
777
778 for (nexthop = rib->nexthop; nexthop; nexthop = next)
779 {
780 next = nexthop->next;
781 nexthop_free (nexthop);
782 }
783 XFREE (MTYPE_RIB, rib);
784}
785
786void
787rib_install_kernel (struct route_node *rn, struct rib *rib)
788{
789 int ret = 0;
790 struct nexthop *nexthop;
791
792 switch (PREFIX_FAMILY (&rn->p))
793 {
794 case AF_INET:
795 ret = kernel_add_ipv4 (&rn->p, rib);
796 break;
797#ifdef HAVE_IPV6
798 case AF_INET6:
799 ret = kernel_add_ipv6 (&rn->p, rib);
800 break;
801#endif /* HAVE_IPV6 */
802 }
803
804 if (ret < 0)
805 {
806 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
807 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
808 }
809}
810
811/* Uninstall the route from kernel. */
812int
813rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
814{
815 int ret = 0;
816 struct nexthop *nexthop;
817
818 switch (PREFIX_FAMILY (&rn->p))
819 {
820 case AF_INET:
821 ret = kernel_delete_ipv4 (&rn->p, rib);
822 break;
823#ifdef HAVE_IPV6
824 case AF_INET6:
825 ret = kernel_delete_ipv6 (&rn->p, rib);
826 break;
827#endif /* HAVE_IPV6 */
828 }
829
830 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
831 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
832
833 return ret;
834}
835
836/* Uninstall the route from kernel. */
837void
838rib_uninstall (struct route_node *rn, struct rib *rib)
839{
840 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
841 {
842 redistribute_delete (&rn->p, rib);
843 if (! RIB_SYSTEM_ROUTE (rib))
844 rib_uninstall_kernel (rn, rib);
845 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
846 }
847}
848
849/* Core function for processing routing information base. */
850void
851rib_process (struct route_node *rn, struct rib *del)
852{
853 struct rib *rib;
854 struct rib *next;
855 struct rib *fib = NULL;
856 struct rib *select = NULL;
d753e9ee 857 int installed = 0;
858 struct nexthop *nexthop = NULL;
718e3744 859
860 for (rib = rn->info; rib; rib = next)
861 {
862 next = rib->next;
d753e9ee 863
718e3744 864 /* Currently installed rib. */
865 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
866 fib = rib;
867
868 /* Skip unreachable nexthop. */
869 if (! nexthop_active_update (rn, rib, 0))
870 continue;
871
872 /* Infinit distance. */
873 if (rib->distance == DISTANCE_INFINITY)
874 continue;
875
876 /* Newly selected rib. */
877 if (! select || rib->distance < select->distance
878 || rib->type == ZEBRA_ROUTE_CONNECT)
879 select = rib;
880 }
881
882 /* Deleted route check. */
883 if (del && CHECK_FLAG (del->flags, ZEBRA_FLAG_SELECTED))
884 fib = del;
885
886 /* Same route is selected. */
887 if (select && select == fib)
888 {
889 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
890 {
891 redistribute_delete (&rn->p, select);
892 if (! RIB_SYSTEM_ROUTE (select))
893 rib_uninstall_kernel (rn, select);
894
895 /* Set real nexthop. */
896 nexthop_active_update (rn, select, 1);
897
898 if (! RIB_SYSTEM_ROUTE (select))
899 rib_install_kernel (rn, select);
900 redistribute_add (&rn->p, select);
901 }
d753e9ee 902 else if (! RIB_SYSTEM_ROUTE (select))
903 {
904 /* Housekeeping code to deal with
905 race conditions in kernel with linux
906 netlink reporting interface up before IPv4 or IPv6 protocol
907 is ready to add routes.
908 This makes sure the routes are IN the kernel.
909 */
910
911 for (nexthop = select->nexthop; nexthop; nexthop = nexthop->next)
912 {
913 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
914 installed = 1;
915 }
916 if (! installed) rib_install_kernel (rn, select);
917 }
718e3744 918 return;
919 }
920
921 /* Uninstall old rib from forwarding table. */
922 if (fib)
923 {
924 redistribute_delete (&rn->p, fib);
925 if (! RIB_SYSTEM_ROUTE (fib))
926 rib_uninstall_kernel (rn, fib);
927 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
928
929 /* Set real nexthop. */
930 nexthop_active_update (rn, fib, 1);
931 }
932
933 /* Install new rib into forwarding table. */
934 if (select)
935 {
936 /* Set real nexthop. */
937 nexthop_active_update (rn, select, 1);
938
939 if (! RIB_SYSTEM_ROUTE (select))
940 rib_install_kernel (rn, select);
941 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
942 redistribute_add (&rn->p, select);
943 }
944}
945
946/* Add RIB to head of the route node. */
947void
948rib_addnode (struct route_node *rn, struct rib *rib)
949{
950 struct rib *head;
951
952 head = rn->info;
953 if (head)
954 head->prev = rib;
955 rib->next = head;
956 rn->info = rib;
957}
958
959void
960rib_delnode (struct route_node *rn, struct rib *rib)
961{
962 if (rib->next)
963 rib->next->prev = rib->prev;
964 if (rib->prev)
965 rib->prev->next = rib->next;
966 else
967 rn->info = rib->next;
968}
969
970int
971rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
972 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
973 u_int32_t metric, u_char distance)
974{
975 struct rib *rib;
976 struct rib *same = NULL;
977 struct route_table *table;
978 struct route_node *rn;
979 struct nexthop *nexthop;
980
981 /* Lookup table. */
982 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
983 if (! table)
984 return 0;
985
986 /* Make it sure prefixlen is applied to the prefix. */
987 apply_mask_ipv4 (p);
988
989 /* Set default distance by route type. */
990 if (distance == 0)
991 {
992 distance = route_info[type].distance;
993
994 /* iBGP distance is 200. */
995 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
996 distance = 200;
997 }
998
999 /* Lookup route node.*/
1000 rn = route_node_get (table, (struct prefix *) p);
1001
1002 /* If same type of route are installed, treat it as a implicit
1003 withdraw. */
1004 for (rib = rn->info; rib; rib = rib->next)
1005 {
1006 if (rib->type == ZEBRA_ROUTE_CONNECT)
1007 {
1008 nexthop = rib->nexthop;
1009
1010 /* Duplicate connected route comes in. */
1011 if (rib->type == type
1012 && nexthop && nexthop->type == NEXTHOP_TYPE_IFINDEX
1013 && nexthop->ifindex == ifindex)
1014 {
1015 rib->refcnt++;
1016 return 0 ;
1017 }
1018 }
1019 else if (rib->type == type)
1020 {
1021 same = rib;
1022 rib_delnode (rn, same);
1023 route_unlock_node (rn);
1024 break;
1025 }
1026 }
1027
1028 /* Allocate new rib structure. */
1029 rib = XMALLOC (MTYPE_RIB, sizeof (struct rib));
1030 memset (rib, 0, sizeof (struct rib));
1031 rib->type = type;
1032 rib->distance = distance;
1033 rib->flags = flags;
1034 rib->metric = metric;
1035 rib->nexthop_num = 0;
1036 rib->uptime = time (NULL);
1037
1038 /* Nexthop settings. */
1039 if (gate)
1040 {
1041 if (ifindex)
1042 nexthop_ipv4_ifindex_add (rib, gate, ifindex);
1043 else
1044 nexthop_ipv4_add (rib, gate);
1045 }
1046 else
1047 nexthop_ifindex_add (rib, ifindex);
1048
1049 /* If this route is kernel route, set FIB flag to the route. */
1050 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1051 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1052 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1053
1054 /* Link new rib to node.*/
1055 rib_addnode (rn, rib);
1056
1057 /* Process this route node. */
1058 rib_process (rn, same);
1059
1060 /* Free implicit route.*/
1061 if (same)
1062 newrib_free (same);
1063
1064 return 0;
1065}
1066
1067int
1068rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib)
1069{
1070 struct route_table *table;
1071 struct route_node *rn;
1072 struct rib *same;
1073 struct nexthop *nexthop;
1074
1075 /* Lookup table. */
1076 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1077 if (! table)
1078 return 0;
1079
1080 /* Make it sure prefixlen is applied to the prefix. */
1081 apply_mask_ipv4 (p);
1082
1083 /* Set default distance by route type. */
1084 if (rib->distance == 0)
1085 {
1086 rib->distance = route_info[rib->type].distance;
1087
1088 /* iBGP distance is 200. */
1089 if (rib->type == ZEBRA_ROUTE_BGP
1090 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1091 rib->distance = 200;
1092 }
1093
1094 /* Lookup route node.*/
1095 rn = route_node_get (table, (struct prefix *) p);
1096
1097 /* If same type of route are installed, treat it as a implicit
1098 withdraw. */
1099 for (same = rn->info; same; same = same->next)
1100 {
1101 if (same->type == rib->type && same->table == rib->table
1102 && same->type != ZEBRA_ROUTE_CONNECT)
1103 {
1104 rib_delnode (rn, same);
1105 route_unlock_node (rn);
1106 break;
1107 }
1108 }
1109
1110 /* If this route is kernel route, set FIB flag to the route. */
1111 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
1112 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1113 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1114
1115 /* Link new rib to node.*/
1116 rib_addnode (rn, rib);
1117
1118 /* Process this route node. */
1119 rib_process (rn, same);
1120
1121 /* Free implicit route.*/
1122 if (same)
1123 newrib_free (same);
1124
1125 return 0;
1126}
1127
1128int
1129rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
1130 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1131{
1132 struct route_table *table;
1133 struct route_node *rn;
1134 struct rib *rib;
1135 struct rib *fib = NULL;
1136 struct rib *same = NULL;
1137 struct nexthop *nexthop;
1138 char buf1[BUFSIZ];
1139 char buf2[BUFSIZ];
1140
1141 /* Lookup table. */
1142 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1143 if (! table)
1144 return 0;
1145
1146 /* Apply mask. */
1147 apply_mask_ipv4 (p);
1148
1149 /* Lookup route node. */
1150 rn = route_node_lookup (table, (struct prefix *) p);
1151 if (! rn)
1152 {
1153 if (IS_ZEBRA_DEBUG_KERNEL)
1154 {
1155 if (gate)
1156 zlog_info ("route %s/%d via %s ifindex %d doesn't exist in rib",
1157 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1158 p->prefixlen,
1159 inet_ntop (AF_INET, gate, buf2, BUFSIZ),
1160 ifindex);
1161 else
1162 zlog_info ("route %s/%d ifindex %d doesn't exist in rib",
1163 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1164 p->prefixlen,
1165 ifindex);
1166 }
1167 return ZEBRA_ERR_RTNOEXIST;
1168 }
1169
1170 /* Lookup same type route. */
1171 for (rib = rn->info; rib; rib = rib->next)
1172 {
1173 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1174 fib = rib;
1175
1176 if (rib->type == ZEBRA_ROUTE_CONNECT)
1177 {
1178 nexthop = rib->nexthop;
1179
1180 if (rib->type == type
1181 && nexthop && nexthop->type == NEXTHOP_TYPE_IFINDEX
1182 && nexthop->ifindex == ifindex)
1183 {
1184 if (rib->refcnt)
1185 {
1186 rib->refcnt--;
1187 route_unlock_node (rn);
1188 route_unlock_node (rn);
1189 return 0;
1190 }
1191 same = rib;
1192 break;
1193 }
1194 }
1195 else
1196 {
1197 if (rib->type == type)
1198 {
1199 same = rib;
1200 break;
1201 }
1202 }
1203 }
1204
1205 /* If same type of route can't be found and this message is from
1206 kernel. */
1207 if (! same)
1208 {
1209 if (fib && type == ZEBRA_ROUTE_KERNEL)
1210 {
1211 /* Unset flags. */
1212 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1213 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1214
1215 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1216 }
1217 else
1218 {
1219 if (IS_ZEBRA_DEBUG_KERNEL)
1220 {
1221 if (gate)
1222 zlog_info ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
1223 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1224 p->prefixlen,
1225 inet_ntop (AF_INET, gate, buf2, BUFSIZ),
1226 ifindex,
1227 type);
1228 else
1229 zlog_info ("route %s/%d ifindex %d type %d doesn't exist in rib",
1230 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1231 p->prefixlen,
1232 ifindex,
1233 type);
1234 }
1235 route_unlock_node (rn);
1236 return ZEBRA_ERR_RTNOEXIST;
1237 }
1238 }
1239
1240 if (same)
1241 rib_delnode (rn, same);
1242
1243 /* Process changes. */
1244 rib_process (rn, same);
1245
1246 if (same)
1247 {
1248 newrib_free (same);
1249 route_unlock_node (rn);
1250 }
1251
1252 route_unlock_node (rn);
1253
1254 return 0;
1255}
1256\f
1257/* Install static route into rib. */
1258void
1259static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
1260{
1261 struct rib *rib;
1262 struct route_node *rn;
1263 struct route_table *table;
1264
1265 /* Lookup table. */
1266 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1267 if (! table)
1268 return;
1269
1270 /* Lookup existing route */
1271 rn = route_node_get (table, p);
1272 for (rib = rn->info; rib; rib = rib->next)
1273 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1274 break;
1275
1276 if (rib)
1277 {
1278 /* Same distance static route is there. Update it with new
1279 nexthop. */
1280 rib_uninstall (rn, rib);
1281 route_unlock_node (rn);
1282
1283 switch (si->type)
1284 {
1285 case STATIC_IPV4_GATEWAY:
1286 nexthop_ipv4_add (rib, &si->gate.ipv4);
1287 break;
1288 case STATIC_IPV4_IFNAME:
1289 nexthop_ifname_add (rib, si->gate.ifname);
1290 break;
595db7f1 1291 case STATIC_IPV4_BLACKHOLE:
1292 nexthop_blackhole_add (rib);
1293 break;
718e3744 1294 }
1295 rib_process (rn, NULL);
1296 }
1297 else
1298 {
1299 /* This is new static route. */
1300 rib = XMALLOC (MTYPE_RIB, sizeof (struct rib));
1301 memset (rib, 0, sizeof (struct rib));
1302
1303 rib->type = ZEBRA_ROUTE_STATIC;
1304 rib->distance = si->distance;
1305 rib->metric = 0;
1306 rib->nexthop_num = 0;
1307
1308 switch (si->type)
1309 {
1310 case STATIC_IPV4_GATEWAY:
1311 nexthop_ipv4_add (rib, &si->gate.ipv4);
1312 break;
1313 case STATIC_IPV4_IFNAME:
1314 nexthop_ifname_add (rib, si->gate.ifname);
1315 break;
595db7f1 1316 case STATIC_IPV4_BLACKHOLE:
1317 nexthop_blackhole_add (rib);
1318 break;
718e3744 1319 }
1320
81dfcaa2 1321 /* Save the flags of this static routes (reject, blackhole) */
1322 rib->flags = si->flags;
1323
718e3744 1324 /* Link this rib to the tree. */
1325 rib_addnode (rn, rib);
1326
1327 /* Process this prefix. */
1328 rib_process (rn, NULL);
1329 }
1330}
1331
1332int
1333static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
1334{
1335 if (nexthop->type == NEXTHOP_TYPE_IPV4
1336 && si->type == STATIC_IPV4_GATEWAY
1337 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
1338 return 1;
1339 if (nexthop->type == NEXTHOP_TYPE_IFNAME
1340 && si->type == STATIC_IPV4_IFNAME
1341 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
1342 return 1;
595db7f1 1343 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
1344 && si->type == STATIC_IPV4_BLACKHOLE)
1345 return 1;
718e3744 1346 return 0;;
1347}
1348
1349/* Uninstall static route from RIB. */
1350void
1351static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
1352{
1353 struct route_node *rn;
1354 struct rib *rib;
1355 struct nexthop *nexthop;
1356 struct route_table *table;
1357
1358 /* Lookup table. */
1359 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1360 if (! table)
1361 return;
1362
1363 /* Lookup existing route with type and distance. */
1364 rn = route_node_lookup (table, p);
1365 if (! rn)
1366 return;
1367
1368 for (rib = rn->info; rib; rib = rib->next)
1369 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1370 break;
1371
1372 if (! rib)
1373 {
1374 route_unlock_node (rn);
1375 return;
1376 }
1377
1378 /* Lookup nexthop. */
1379 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1380 if (static_ipv4_nexthop_same (nexthop, si))
1381 break;
1382
1383 /* Can't find nexthop. */
1384 if (! nexthop)
1385 {
1386 route_unlock_node (rn);
1387 return;
1388 }
1389
1390 /* Check nexthop. */
1391 if (rib->nexthop_num == 1)
1392 {
1393 rib_delnode (rn, rib);
1394 rib_process (rn, rib);
1395 newrib_free (rib);
1396 route_unlock_node (rn);
1397 }
1398 else
1399 {
1400 rib_uninstall (rn, rib);
1401 nexthop_delete (rib, nexthop);
1402 nexthop_free (nexthop);
1403 rib_process (rn, rib);
1404 }
1405
1406 /* Unlock node. */
1407 route_unlock_node (rn);
1408}
1409
1410/* Add static route into static route configuration. */
1411int
1412static_add_ipv4 (struct prefix *p, struct in_addr *gate, char *ifname,
81dfcaa2 1413 u_char flags, u_char distance, u_int32_t vrf_id)
718e3744 1414{
1415 u_char type = 0;
1416 struct route_node *rn;
1417 struct static_ipv4 *si;
1418 struct static_ipv4 *pp;
1419 struct static_ipv4 *cp;
1420 struct static_ipv4 *update = NULL;
1421 struct route_table *stable;
1422
1423 /* Lookup table. */
1424 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
1425 if (! stable)
1426 return -1;
1427
1428 /* Lookup static route prefix. */
1429 rn = route_node_get (stable, p);
1430
1431 /* Make flags. */
1432 if (gate)
1433 type = STATIC_IPV4_GATEWAY;
81dfcaa2 1434 if (ifname)
718e3744 1435 type = STATIC_IPV4_IFNAME;
595db7f1 1436 else
1437 type = STATIC_IPV4_BLACKHOLE;
718e3744 1438
1439 /* Do nothing if there is a same static route. */
1440 for (si = rn->info; si; si = si->next)
1441 {
1442 if (type == si->type
1443 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
1444 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
1445 {
1446 if (distance == si->distance)
1447 {
1448 route_unlock_node (rn);
1449 return 0;
1450 }
1451 else
1452 update = si;
1453 }
1454 }
1455
1456 /* Distance chaged. */
1457 if (update)
1458 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
1459
1460 /* Make new static route structure. */
1461 si = XMALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
1462 memset (si, 0, sizeof (struct static_ipv4));
1463
1464 si->type = type;
1465 si->distance = distance;
81dfcaa2 1466 si->flags = flags;
718e3744 1467
1468 if (gate)
1469 si->gate.ipv4 = *gate;
1470 if (ifname)
1471 si->gate.ifname = XSTRDUP (0, ifname);
1472
1473 /* Add new static route information to the tree with sort by
1474 distance value and gateway address. */
1475 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
1476 {
1477 if (si->distance < cp->distance)
1478 break;
1479 if (si->distance > cp->distance)
1480 continue;
1481 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
1482 {
1483 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
1484 break;
1485 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
1486 continue;
1487 }
1488 }
1489
1490 /* Make linked list. */
1491 if (pp)
1492 pp->next = si;
1493 else
1494 rn->info = si;
1495 if (cp)
1496 cp->prev = si;
1497 si->prev = pp;
1498 si->next = cp;
1499
1500 /* Install into rib. */
1501 static_install_ipv4 (p, si);
1502
1503 return 1;
1504}
1505
1506/* Delete static route from static route configuration. */
1507int
1508static_delete_ipv4 (struct prefix *p, struct in_addr *gate, char *ifname,
1509 u_char distance, u_int32_t vrf_id)
1510{
1511 u_char type = 0;
1512 struct route_node *rn;
1513 struct static_ipv4 *si;
1514 struct route_table *stable;
1515
1516 /* Lookup table. */
1517 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
1518 if (! stable)
1519 return -1;
1520
1521 /* Lookup static route prefix. */
1522 rn = route_node_lookup (stable, p);
1523 if (! rn)
1524 return 0;
1525
1526 /* Make flags. */
1527 if (gate)
1528 type = STATIC_IPV4_GATEWAY;
1529 else if (ifname)
1530 type = STATIC_IPV4_IFNAME;
595db7f1 1531 else
1532 type = STATIC_IPV4_BLACKHOLE;
718e3744 1533
1534 /* Find same static route is the tree */
1535 for (si = rn->info; si; si = si->next)
1536 if (type == si->type
1537 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
1538 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
1539 break;
1540
1541 /* Can't find static route. */
1542 if (! si)
1543 {
1544 route_unlock_node (rn);
1545 return 0;
1546 }
1547
1548 /* Install into rib. */
1549 static_uninstall_ipv4 (p, si);
1550
1551 /* Unlink static route from linked list. */
1552 if (si->prev)
1553 si->prev->next = si->next;
1554 else
1555 rn->info = si->next;
1556 if (si->next)
1557 si->next->prev = si->prev;
1558
1559 /* Free static route configuration. */
a0f6acd8 1560 if (ifname)
1561 XFREE (0, si->gate.ifname);
718e3744 1562 XFREE (MTYPE_STATIC_IPV4, si);
1563
1564 return 1;
1565}
1566
1567\f
1568#ifdef HAVE_IPV6
1569int
1570rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
1571 struct in6_addr *gate, unsigned int ifindex, int table)
1572{
726f9b2b 1573 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
1574#if defined (MUSICA) || defined (LINUX)
1575 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
1576 if (p->prefixlen == 96)
1577 return 0;
1578#endif /* MUSICA */
718e3744 1579 return 1;
726f9b2b 1580 }
718e3744 1581 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
1582 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
1583 {
1584 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
1585 return 1;
1586 }
1587 return 0;
1588}
1589
1590int
1591rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
1592 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1593{
1594 struct rib *rib;
1595 struct rib *same = NULL;
1596 struct route_table *table;
1597 struct route_node *rn;
1598 struct nexthop *nexthop;
1599
1600 int distance;
1601 u_int32_t metric = 0;
1602
1603 /* Lookup table. */
1604 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1605 if (! table)
1606 return 0;
1607
1608 /* Make sure mask is applied. */
1609 apply_mask_ipv6 (p);
1610
1611 /* Set default distance by route type. */
1612 distance = route_info[type].distance;
1613
1614 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1615 distance = 200;
1616
1617 /* Filter bogus route. */
1618 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
1619 return 0;
1620
1621 /* Lookup route node.*/
1622 rn = route_node_get (table, (struct prefix *) p);
1623
1624 /* If same type of route are installed, treat it as a implicit
1625 withdraw. */
1626 for (rib = rn->info; rib; rib = rib->next)
1627 {
1628 if (rib->type == ZEBRA_ROUTE_CONNECT)
1629 {
1630 nexthop = rib->nexthop;
1631
1632 if (rib->type == type
1633 && nexthop && nexthop->type == NEXTHOP_TYPE_IFINDEX
1634 && nexthop->ifindex == ifindex)
1635 {
1636 rib->refcnt++;
1637 return 0;
1638 }
1639 }
1640 else if (rib->type == type)
1641 {
1642 same = rib;
1643 rib_delnode (rn, same);
1644 route_unlock_node (rn);
1645 break;
1646 }
1647 }
1648
1649 /* Allocate new rib structure. */
1650 rib = XMALLOC (MTYPE_RIB, sizeof (struct rib));
1651 memset (rib, 0, sizeof (struct rib));
1652 rib->type = type;
1653 rib->distance = distance;
1654 rib->flags = flags;
1655 rib->metric = metric;
1656 rib->nexthop_num = 0;
1657 rib->uptime = time (NULL);
1658
1659 /* Nexthop settings. */
1660 if (gate)
1661 {
1662 if (ifindex)
1663 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
1664 else
1665 nexthop_ipv6_add (rib, gate);
1666 }
1667 else
1668 nexthop_ifindex_add (rib, ifindex);
1669
1670 /* If this route is kernel route, set FIB flag to the route. */
1671 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1672 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1673 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1674
1675 /* Link new rib to node.*/
1676 rib_addnode (rn, rib);
1677
1678 /* Process this route node. */
1679 rib_process (rn, same);
1680
1681 /* Free implicit route.*/
1682 if (same)
1683 newrib_free (same);
1684
1685 return 0;
1686}
1687
1688int
1689rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
1690 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1691{
1692 struct route_table *table;
1693 struct route_node *rn;
1694 struct rib *rib;
1695 struct rib *fib = NULL;
1696 struct rib *same = NULL;
1697 struct nexthop *nexthop;
1698 char buf1[BUFSIZ];
1699 char buf2[BUFSIZ];
1700
1701 /* Apply mask. */
1702 apply_mask_ipv6 (p);
1703
1704 /* Lookup table. */
1705 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1706 if (! table)
1707 return 0;
1708
1709 /* Lookup route node. */
1710 rn = route_node_lookup (table, (struct prefix *) p);
1711 if (! rn)
1712 {
1713 if (IS_ZEBRA_DEBUG_KERNEL)
1714 {
1715 if (gate)
1716 zlog_info ("route %s/%d via %s ifindex %d doesn't exist in rib",
1717 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1718 p->prefixlen,
1719 inet_ntop (AF_INET6, gate, buf2, BUFSIZ),
1720 ifindex);
1721 else
1722 zlog_info ("route %s/%d ifindex %d doesn't exist in rib",
1723 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1724 p->prefixlen,
1725 ifindex);
1726 }
1727 return ZEBRA_ERR_RTNOEXIST;
1728 }
1729
1730 /* Lookup same type route. */
1731 for (rib = rn->info; rib; rib = rib->next)
1732 {
1733 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1734 fib = rib;
1735
1736 if (rib->type == ZEBRA_ROUTE_CONNECT)
1737 {
1738 nexthop = rib->nexthop;
1739
1740 if (rib->type == type
1741 && nexthop && nexthop->type == NEXTHOP_TYPE_IFINDEX
1742 && nexthop->ifindex == ifindex)
1743 {
1744 if (rib->refcnt)
1745 {
1746 rib->refcnt--;
1747 route_unlock_node (rn);
1748 route_unlock_node (rn);
1749 return 0;
1750 }
1751 same = rib;
1752 break;
1753 }
1754 }
1755 else
1756 {
1757 if (rib->type == type)
1758 {
1759 same = rib;
1760 break;
1761 }
1762 }
1763 }
1764
1765 /* If same type of route can't be found and this message is from
1766 kernel. */
1767 if (! same)
1768 {
1769 if (fib && type == ZEBRA_ROUTE_KERNEL)
1770 {
1771 /* Unset flags. */
1772 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1773 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1774
1775 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1776 }
1777 else
1778 {
1779 if (IS_ZEBRA_DEBUG_KERNEL)
1780 {
1781 if (gate)
1782 zlog_info ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
1783 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1784 p->prefixlen,
1785 inet_ntop (AF_INET6, gate, buf2, BUFSIZ),
1786 ifindex,
1787 type);
1788 else
1789 zlog_info ("route %s/%d ifindex %d type %d doesn't exist in rib",
1790 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1791 p->prefixlen,
1792 ifindex,
1793 type);
1794 }
1795 route_unlock_node (rn);
1796 return ZEBRA_ERR_RTNOEXIST;
1797 }
1798 }
1799
1800 if (same)
1801 rib_delnode (rn, same);
1802
1803 /* Process changes. */
1804 rib_process (rn, same);
1805
1806 if (same)
1807 {
1808 newrib_free (same);
1809 route_unlock_node (rn);
1810 }
1811
1812 route_unlock_node (rn);
1813
1814 return 0;
1815}
1816\f
1817/* Install static route into rib. */
1818void
1819static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
1820{
1821 struct rib *rib;
1822 struct route_table *table;
1823 struct route_node *rn;
1824
1825 /* Lookup table. */
1826 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1827 if (! table)
1828 return;
1829
1830 /* Lookup existing route */
1831 rn = route_node_get (table, p);
1832 for (rib = rn->info; rib; rib = rib->next)
1833 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1834 break;
1835
1836 if (rib)
1837 {
1838 /* Same distance static route is there. Update it with new
1839 nexthop. */
1840 rib_uninstall (rn, rib);
1841 route_unlock_node (rn);
1842
1843 switch (si->type)
1844 {
1845 case STATIC_IPV6_GATEWAY:
1846 nexthop_ipv6_add (rib, &si->ipv6);
1847 break;
1848 case STATIC_IPV6_IFNAME:
1849 nexthop_ifname_add (rib, si->ifname);
1850 break;
1851 case STATIC_IPV6_GATEWAY_IFNAME:
1852 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
1853 break;
1854 }
1855 rib_process (rn, NULL);
1856 }
1857 else
1858 {
1859 /* This is new static route. */
1860 rib = XMALLOC (MTYPE_RIB, sizeof (struct rib));
1861 memset (rib, 0, sizeof (struct rib));
1862
1863 rib->type = ZEBRA_ROUTE_STATIC;
1864 rib->distance = si->distance;
1865 rib->metric = 0;
1866 rib->nexthop_num = 0;
1867
1868 switch (si->type)
1869 {
1870 case STATIC_IPV6_GATEWAY:
1871 nexthop_ipv6_add (rib, &si->ipv6);
1872 break;
1873 case STATIC_IPV6_IFNAME:
1874 nexthop_ifname_add (rib, si->ifname);
1875 break;
1876 case STATIC_IPV6_GATEWAY_IFNAME:
1877 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
1878 break;
1879 }
1880
81dfcaa2 1881 /* Save the flags of this static routes (reject, blackhole) */
1882 rib->flags = si->flags;
1883
718e3744 1884 /* Link this rib to the tree. */
1885 rib_addnode (rn, rib);
1886
1887 /* Process this prefix. */
1888 rib_process (rn, NULL);
1889 }
1890}
1891
1892int
1893static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
1894{
1895 if (nexthop->type == NEXTHOP_TYPE_IPV6
1896 && si->type == STATIC_IPV6_GATEWAY
1897 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
1898 return 1;
1899 if (nexthop->type == NEXTHOP_TYPE_IFNAME
1900 && si->type == STATIC_IPV6_IFNAME
1901 && strcmp (nexthop->ifname, si->ifname) == 0)
1902 return 1;
1903 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
1904 && si->type == STATIC_IPV6_GATEWAY_IFNAME
1905 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
1906 && strcmp (nexthop->ifname, si->ifname) == 0)
1907 return 1;
1908 return 0;;
1909}
1910
1911void
1912static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
1913{
1914 struct route_table *table;
1915 struct route_node *rn;
1916 struct rib *rib;
1917 struct nexthop *nexthop;
1918
1919 /* Lookup table. */
1920 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1921 if (! table)
1922 return;
1923
1924 /* Lookup existing route with type and distance. */
1925 rn = route_node_lookup (table, (struct prefix *) p);
1926 if (! rn)
1927 return;
1928
1929 for (rib = rn->info; rib; rib = rib->next)
1930 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1931 break;
1932 if (! rib)
1933 {
1934 route_unlock_node (rn);
1935 return;
1936 }
1937
1938 /* Lookup nexthop. */
1939 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1940 if (static_ipv6_nexthop_same (nexthop, si))
1941 break;
1942
1943 /* Can't find nexthop. */
1944 if (! nexthop)
1945 {
1946 route_unlock_node (rn);
1947 return;
1948 }
1949
1950 /* Check nexthop. */
1951 if (rib->nexthop_num == 1)
1952 {
1953 rib_delnode (rn, rib);
1954 rib_process (rn, rib);
1955 newrib_free (rib);
1956 route_unlock_node (rn);
1957 }
1958 else
1959 {
1960 rib_uninstall (rn, rib);
1961 nexthop_delete (rib, nexthop);
1962 nexthop_free (nexthop);
1963 rib_process (rn, rib);
1964 }
1965
1966 /* Unlock node. */
1967 route_unlock_node (rn);
1968}
1969
1970/* Add static route into static route configuration. */
1971int
1972static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
81dfcaa2 1973 char *ifname, u_char flags, u_char distance, u_int32_t vrf_id)
718e3744 1974{
1975 struct route_node *rn;
1976 struct static_ipv6 *si;
1977 struct static_ipv6 *pp;
1978 struct static_ipv6 *cp;
1979 struct route_table *stable;
1980
1981 /* Lookup table. */
1982 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
1983 if (! stable)
1984 return -1;
1985
1986 /* Lookup static route prefix. */
1987 rn = route_node_get (stable, p);
1988
1989 /* Do nothing if there is a same static route. */
1990 for (si = rn->info; si; si = si->next)
1991 {
1992 if (distance == si->distance
1993 && type == si->type
1994 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
1995 && (! ifname || strcmp (ifname, si->ifname) == 0))
1996 {
1997 route_unlock_node (rn);
1998 return 0;
1999 }
2000 }
2001
2002 /* Make new static route structure. */
2003 si = XMALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
2004 memset (si, 0, sizeof (struct static_ipv6));
2005
2006 si->type = type;
2007 si->distance = distance;
81dfcaa2 2008 si->flags = flags;
718e3744 2009
2010 switch (type)
2011 {
2012 case STATIC_IPV6_GATEWAY:
2013 si->ipv6 = *gate;
2014 break;
2015 case STATIC_IPV6_IFNAME:
2016 si->ifname = XSTRDUP (0, ifname);
2017 break;
2018 case STATIC_IPV6_GATEWAY_IFNAME:
2019 si->ipv6 = *gate;
2020 si->ifname = XSTRDUP (0, ifname);
2021 break;
2022 }
2023
2024 /* Add new static route information to the tree with sort by
2025 distance value and gateway address. */
2026 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2027 {
2028 if (si->distance < cp->distance)
2029 break;
2030 if (si->distance > cp->distance)
2031 continue;
2032 }
2033
2034 /* Make linked list. */
2035 if (pp)
2036 pp->next = si;
2037 else
2038 rn->info = si;
2039 if (cp)
2040 cp->prev = si;
2041 si->prev = pp;
2042 si->next = cp;
2043
2044 /* Install into rib. */
2045 static_install_ipv6 (p, si);
2046
2047 return 1;
2048}
2049
2050/* Delete static route from static route configuration. */
2051int
2052static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
2053 char *ifname, u_char distance, u_int32_t vrf_id)
2054{
2055 struct route_node *rn;
2056 struct static_ipv6 *si;
2057 struct route_table *stable;
2058
2059 /* Lookup table. */
2060 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2061 if (! stable)
2062 return -1;
2063
2064 /* Lookup static route prefix. */
2065 rn = route_node_lookup (stable, p);
2066 if (! rn)
2067 return 0;
2068
2069 /* Find same static route is the tree */
2070 for (si = rn->info; si; si = si->next)
2071 if (distance == si->distance
2072 && type == si->type
2073 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2074 && (! ifname || strcmp (ifname, si->ifname) == 0))
2075 break;
2076
2077 /* Can't find static route. */
2078 if (! si)
2079 {
2080 route_unlock_node (rn);
2081 return 0;
2082 }
2083
2084 /* Install into rib. */
2085 static_uninstall_ipv6 (p, si);
2086
2087 /* Unlink static route from linked list. */
2088 if (si->prev)
2089 si->prev->next = si->next;
2090 else
2091 rn->info = si->next;
2092 if (si->next)
2093 si->next->prev = si->prev;
2094
2095 /* Free static route configuration. */
a0f6acd8 2096 if (ifname)
2097 XFREE (0, si->ifname);
718e3744 2098 XFREE (MTYPE_STATIC_IPV6, si);
2099
2100 return 1;
2101}
2102#endif /* HAVE_IPV6 */
2103\f
2104/* RIB update function. */
2105void
2106rib_update ()
2107{
2108 struct route_node *rn;
2109 struct route_table *table;
2110
2111 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2112 if (table)
2113 for (rn = route_top (table); rn; rn = route_next (rn))
2114 rib_process (rn, NULL);
2115
2116 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2117 if (table)
2118 for (rn = route_top (table); rn; rn = route_next (rn))
2119 rib_process (rn, NULL);
2120}
2121
2122/* Interface goes up. */
2123void
2124rib_if_up (struct interface *ifp)
2125{
2126 rib_update ();
2127}
2128
2129/* Interface goes down. */
2130void
2131rib_if_down (struct interface *ifp)
2132{
2133 rib_update ();
2134}
2135\f
2136/* Remove all routes which comes from non main table. */
2137void
2138rib_weed_table (struct route_table *table)
2139{
2140 struct route_node *rn;
2141 struct rib *rib;
2142 struct rib *next;
2143
2144 if (table)
2145 for (rn = route_top (table); rn; rn = route_next (rn))
2146 for (rib = rn->info; rib; rib = next)
2147 {
2148 next = rib->next;
2149
2150 if (rib->table != rtm_table_default &&
2151 rib->table != RT_TABLE_MAIN)
2152 {
2153 rib_delnode (rn, rib);
2154 newrib_free (rib);
2155 route_unlock_node (rn);
2156 }
2157 }
2158}
2159
2160/* Delete all routes from non main table. */
2161void
2162rib_weed_tables ()
2163{
2164 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2165 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2166}
2167\f
2168/* Delete self installed routes after zebra is relaunched. */
2169void
2170rib_sweep_table (struct route_table *table)
2171{
2172 struct route_node *rn;
2173 struct rib *rib;
2174 struct rib *next;
2175 int ret = 0;
2176
2177 if (table)
2178 for (rn = route_top (table); rn; rn = route_next (rn))
2179 for (rib = rn->info; rib; rib = next)
2180 {
2181 next = rib->next;
2182
2183 if (rib->type == ZEBRA_ROUTE_KERNEL &&
2184 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
2185 {
2186 ret = rib_uninstall_kernel (rn, rib);
2187 if (! ret)
2188 {
2189 rib_delnode (rn, rib);
2190 newrib_free (rib);
2191 route_unlock_node (rn);
2192 }
2193 }
2194 }
2195}
2196
2197/* Sweep all RIB tables. */
2198void
2199rib_sweep_route ()
2200{
2201 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2202 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2203}
2204\f
2205/* Close RIB and clean up kernel routes. */
2206void
2207rib_close_table (struct route_table *table)
2208{
2209 struct route_node *rn;
2210 struct rib *rib;
2211
2212 if (table)
2213 for (rn = route_top (table); rn; rn = route_next (rn))
2214 for (rib = rn->info; rib; rib = rib->next)
2215 if (! RIB_SYSTEM_ROUTE (rib)
2216 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2217 rib_uninstall_kernel (rn, rib);
2218}
2219
2220/* Close all RIB tables. */
2221void
2222rib_close ()
2223{
2224 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2225 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2226}
2227\f
2228/* Routing information base initialize. */
2229void
2230rib_init ()
2231{
2232 /* VRF initialization. */
2233 vrf_init ();
2234}