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