blob: 63d0d1073c566d0de1110785dd2ab55dfa7714f4 [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 */
paulb21b19c2003-06-15 01:28:29 +000040extern struct zebra_t zebrad;
paul718e3742002-12-13 20:15:29 +000041
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
paul595db7f2003-05-25 21:35:06 +0000308struct 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
paul718e3742002-12-13 20:15:29 +0000323/* 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 */
paul595db7f2003-05-25 21:35:06 +0000741 case NEXTHOP_TYPE_BLACKHOLE:
742 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
743 break;
paul718e3742002-12-13 20:15:29 +0000744 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
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;
pauld753e9e2003-01-22 19:45:50 +0000857 int installed = 0;
858 struct nexthop *nexthop = NULL;
paul718e3742002-12-13 20:15:29 +0000859
860 for (rib = rn->info; rib; rib = next)
861 {
862 next = rib->next;
pauld753e9e2003-01-22 19:45:50 +0000863
paul718e3742002-12-13 20:15:29 +0000864 /* Currently installed rib. */
865 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
paul7021c422003-07-15 12:52:22 +0000866 fib = rib;
paul718e3742002-12-13 20:15:29 +0000867
868 /* Skip unreachable nexthop. */
869 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +0000870 continue;
paul718e3742002-12-13 20:15:29 +0000871
872 /* Infinit distance. */
873 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +0000874 continue;
paul718e3742002-12-13 20:15:29 +0000875
876 /* Newly selected rib. */
877 if (! select || rib->distance < select->distance
paul7021c422003-07-15 12:52:22 +0000878 || rib->type == ZEBRA_ROUTE_CONNECT)
879 select = rib;
paul718e3742002-12-13 20:15:29 +0000880 }
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 }
pauld753e9e2003-01-22 19:45:50 +0000902 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 }
paul718e3742002-12-13 20:15:29 +0000918 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
paul5ec90d22003-06-19 01:41:37 +00001149 if (IS_ZEBRA_DEBUG_KERNEL && gate)
1150 zlog_info ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
1151 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1152 p->prefixlen,
1153 inet_ntoa (*gate),
1154 ifindex);
1155
paul718e3742002-12-13 20:15:29 +00001156 /* Lookup route node. */
1157 rn = route_node_lookup (table, (struct prefix *) p);
1158 if (! rn)
1159 {
1160 if (IS_ZEBRA_DEBUG_KERNEL)
1161 {
1162 if (gate)
1163 zlog_info ("route %s/%d via %s ifindex %d doesn't exist in rib",
1164 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1165 p->prefixlen,
1166 inet_ntop (AF_INET, gate, buf2, BUFSIZ),
1167 ifindex);
1168 else
1169 zlog_info ("route %s/%d ifindex %d doesn't exist in rib",
1170 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1171 p->prefixlen,
1172 ifindex);
1173 }
1174 return ZEBRA_ERR_RTNOEXIST;
1175 }
1176
1177 /* Lookup same type route. */
1178 for (rib = rn->info; rib; rib = rib->next)
1179 {
1180 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1181 fib = rib;
1182
1183 if (rib->type == ZEBRA_ROUTE_CONNECT)
1184 {
1185 nexthop = rib->nexthop;
1186
1187 if (rib->type == type
1188 && nexthop && nexthop->type == NEXTHOP_TYPE_IFINDEX
1189 && nexthop->ifindex == ifindex)
1190 {
1191 if (rib->refcnt)
1192 {
1193 rib->refcnt--;
1194 route_unlock_node (rn);
1195 route_unlock_node (rn);
1196 return 0;
1197 }
1198 same = rib;
1199 break;
1200 }
1201 }
paul5ec90d22003-06-19 01:41:37 +00001202 else if (gate)
1203 {
1204 nexthop = rib->nexthop;
1205
1206 /* Make sure that the route found has the same gateway. */
1207 if (rib->type == type
1208 && nexthop &&
1209 (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
1210 IPV4_ADDR_SAME (&nexthop->rgate.ipv4, gate)) )
1211 {
1212 same = rib;
1213 break;
1214 }
1215 }
paul718e3742002-12-13 20:15:29 +00001216 else
1217 {
1218 if (rib->type == type)
1219 {
1220 same = rib;
1221 break;
1222 }
1223 }
1224 }
1225
1226 /* If same type of route can't be found and this message is from
1227 kernel. */
1228 if (! same)
1229 {
1230 if (fib && type == ZEBRA_ROUTE_KERNEL)
1231 {
1232 /* Unset flags. */
1233 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1234 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1235
1236 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1237 }
1238 else
1239 {
1240 if (IS_ZEBRA_DEBUG_KERNEL)
1241 {
1242 if (gate)
1243 zlog_info ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
1244 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1245 p->prefixlen,
1246 inet_ntop (AF_INET, gate, buf2, BUFSIZ),
1247 ifindex,
1248 type);
1249 else
1250 zlog_info ("route %s/%d ifindex %d type %d doesn't exist in rib",
1251 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1252 p->prefixlen,
1253 ifindex,
1254 type);
1255 }
1256 route_unlock_node (rn);
1257 return ZEBRA_ERR_RTNOEXIST;
1258 }
1259 }
1260
1261 if (same)
1262 rib_delnode (rn, same);
1263
1264 /* Process changes. */
1265 rib_process (rn, same);
1266
1267 if (same)
1268 {
1269 newrib_free (same);
1270 route_unlock_node (rn);
1271 }
1272
1273 route_unlock_node (rn);
1274
1275 return 0;
1276}
1277
1278/* Install static route into rib. */
1279void
1280static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
1281{
1282 struct rib *rib;
1283 struct route_node *rn;
1284 struct route_table *table;
1285
1286 /* Lookup table. */
1287 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1288 if (! table)
1289 return;
1290
1291 /* Lookup existing route */
1292 rn = route_node_get (table, p);
1293 for (rib = rn->info; rib; rib = rib->next)
1294 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1295 break;
1296
1297 if (rib)
1298 {
1299 /* Same distance static route is there. Update it with new
1300 nexthop. */
1301 rib_uninstall (rn, rib);
1302 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001303 switch (si->type)
paul7021c422003-07-15 12:52:22 +00001304 {
1305 case STATIC_IPV4_GATEWAY:
1306 nexthop_ipv4_add (rib, &si->gate.ipv4);
1307 break;
1308 case STATIC_IPV4_IFNAME:
1309 nexthop_ifname_add (rib, si->gate.ifname);
1310 break;
1311 case STATIC_IPV4_BLACKHOLE:
1312 nexthop_blackhole_add (rib);
1313 break;
1314 }
paul718e3742002-12-13 20:15:29 +00001315 rib_process (rn, NULL);
1316 }
1317 else
1318 {
1319 /* This is new static route. */
1320 rib = XMALLOC (MTYPE_RIB, sizeof (struct rib));
1321 memset (rib, 0, sizeof (struct rib));
1322
1323 rib->type = ZEBRA_ROUTE_STATIC;
1324 rib->distance = si->distance;
1325 rib->metric = 0;
1326 rib->nexthop_num = 0;
1327
1328 switch (si->type)
paul7021c422003-07-15 12:52:22 +00001329 {
1330 case STATIC_IPV4_GATEWAY:
1331 nexthop_ipv4_add (rib, &si->gate.ipv4);
1332 break;
1333 case STATIC_IPV4_IFNAME:
1334 nexthop_ifname_add (rib, si->gate.ifname);
1335 break;
1336 case STATIC_IPV4_BLACKHOLE:
1337 nexthop_blackhole_add (rib);
1338 break;
1339 }
paul718e3742002-12-13 20:15:29 +00001340
hasso81dfcaa2003-05-25 19:21:25 +00001341 /* Save the flags of this static routes (reject, blackhole) */
1342 rib->flags = si->flags;
1343
paul718e3742002-12-13 20:15:29 +00001344 /* Link this rib to the tree. */
1345 rib_addnode (rn, rib);
1346
1347 /* Process this prefix. */
1348 rib_process (rn, NULL);
1349 }
1350}
1351
1352int
1353static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
1354{
1355 if (nexthop->type == NEXTHOP_TYPE_IPV4
1356 && si->type == STATIC_IPV4_GATEWAY
1357 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
1358 return 1;
1359 if (nexthop->type == NEXTHOP_TYPE_IFNAME
1360 && si->type == STATIC_IPV4_IFNAME
1361 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
1362 return 1;
paul595db7f2003-05-25 21:35:06 +00001363 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
1364 && si->type == STATIC_IPV4_BLACKHOLE)
1365 return 1;
paul718e3742002-12-13 20:15:29 +00001366 return 0;;
1367}
1368
1369/* Uninstall static route from RIB. */
1370void
1371static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
1372{
1373 struct route_node *rn;
1374 struct rib *rib;
1375 struct nexthop *nexthop;
1376 struct route_table *table;
1377
1378 /* Lookup table. */
1379 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1380 if (! table)
1381 return;
1382
1383 /* Lookup existing route with type and distance. */
1384 rn = route_node_lookup (table, p);
1385 if (! rn)
1386 return;
1387
1388 for (rib = rn->info; rib; rib = rib->next)
1389 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1390 break;
1391
1392 if (! rib)
1393 {
1394 route_unlock_node (rn);
1395 return;
1396 }
1397
1398 /* Lookup nexthop. */
1399 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1400 if (static_ipv4_nexthop_same (nexthop, si))
1401 break;
1402
1403 /* Can't find nexthop. */
1404 if (! nexthop)
1405 {
1406 route_unlock_node (rn);
1407 return;
1408 }
1409
1410 /* Check nexthop. */
1411 if (rib->nexthop_num == 1)
1412 {
1413 rib_delnode (rn, rib);
1414 rib_process (rn, rib);
1415 newrib_free (rib);
1416 route_unlock_node (rn);
1417 }
1418 else
1419 {
1420 rib_uninstall (rn, rib);
1421 nexthop_delete (rib, nexthop);
1422 nexthop_free (nexthop);
1423 rib_process (rn, rib);
1424 }
1425
1426 /* Unlock node. */
1427 route_unlock_node (rn);
1428}
1429
1430/* Add static route into static route configuration. */
1431int
1432static_add_ipv4 (struct prefix *p, struct in_addr *gate, char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00001433 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001434{
1435 u_char type = 0;
1436 struct route_node *rn;
1437 struct static_ipv4 *si;
1438 struct static_ipv4 *pp;
1439 struct static_ipv4 *cp;
1440 struct static_ipv4 *update = NULL;
1441 struct route_table *stable;
1442
1443 /* Lookup table. */
1444 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
1445 if (! stable)
1446 return -1;
1447
1448 /* Lookup static route prefix. */
1449 rn = route_node_get (stable, p);
1450
1451 /* Make flags. */
1452 if (gate)
1453 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00001454 else if (ifname)
paul718e3742002-12-13 20:15:29 +00001455 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00001456 else
1457 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00001458
1459 /* Do nothing if there is a same static route. */
1460 for (si = rn->info; si; si = si->next)
1461 {
1462 if (type == si->type
1463 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
1464 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
1465 {
1466 if (distance == si->distance)
1467 {
1468 route_unlock_node (rn);
1469 return 0;
1470 }
1471 else
1472 update = si;
1473 }
1474 }
1475
1476 /* Distance chaged. */
1477 if (update)
1478 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
1479
1480 /* Make new static route structure. */
1481 si = XMALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
1482 memset (si, 0, sizeof (struct static_ipv4));
1483
1484 si->type = type;
1485 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00001486 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00001487
1488 if (gate)
1489 si->gate.ipv4 = *gate;
1490 if (ifname)
1491 si->gate.ifname = XSTRDUP (0, ifname);
1492
1493 /* Add new static route information to the tree with sort by
1494 distance value and gateway address. */
1495 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
1496 {
1497 if (si->distance < cp->distance)
1498 break;
1499 if (si->distance > cp->distance)
1500 continue;
1501 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
1502 {
1503 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
1504 break;
1505 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
1506 continue;
1507 }
1508 }
1509
1510 /* Make linked list. */
1511 if (pp)
1512 pp->next = si;
1513 else
1514 rn->info = si;
1515 if (cp)
1516 cp->prev = si;
1517 si->prev = pp;
1518 si->next = cp;
1519
1520 /* Install into rib. */
1521 static_install_ipv4 (p, si);
1522
1523 return 1;
1524}
1525
1526/* Delete static route from static route configuration. */
1527int
1528static_delete_ipv4 (struct prefix *p, struct in_addr *gate, char *ifname,
1529 u_char distance, u_int32_t vrf_id)
1530{
1531 u_char type = 0;
1532 struct route_node *rn;
1533 struct static_ipv4 *si;
1534 struct route_table *stable;
1535
1536 /* Lookup table. */
1537 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
1538 if (! stable)
1539 return -1;
1540
1541 /* Lookup static route prefix. */
1542 rn = route_node_lookup (stable, p);
1543 if (! rn)
1544 return 0;
1545
1546 /* Make flags. */
1547 if (gate)
1548 type = STATIC_IPV4_GATEWAY;
1549 else if (ifname)
1550 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00001551 else
1552 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00001553
1554 /* Find same static route is the tree */
1555 for (si = rn->info; si; si = si->next)
1556 if (type == si->type
1557 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
1558 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
1559 break;
1560
1561 /* Can't find static route. */
1562 if (! si)
1563 {
1564 route_unlock_node (rn);
1565 return 0;
1566 }
1567
1568 /* Install into rib. */
1569 static_uninstall_ipv4 (p, si);
1570
1571 /* Unlink static route from linked list. */
1572 if (si->prev)
1573 si->prev->next = si->next;
1574 else
1575 rn->info = si->next;
1576 if (si->next)
1577 si->next->prev = si->prev;
1578
1579 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00001580 if (ifname)
1581 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00001582 XFREE (MTYPE_STATIC_IPV4, si);
1583
1584 return 1;
1585}
1586
1587
1588#ifdef HAVE_IPV6
1589int
1590rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
1591 struct in6_addr *gate, unsigned int ifindex, int table)
1592{
hasso726f9b22003-05-25 21:04:54 +00001593 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
1594#if defined (MUSICA) || defined (LINUX)
1595 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
1596 if (p->prefixlen == 96)
1597 return 0;
1598#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00001599 return 1;
hasso726f9b22003-05-25 21:04:54 +00001600 }
paul718e3742002-12-13 20:15:29 +00001601 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
1602 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
1603 {
1604 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
1605 return 1;
1606 }
1607 return 0;
1608}
1609
1610int
1611rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
1612 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1613{
1614 struct rib *rib;
1615 struct rib *same = NULL;
1616 struct route_table *table;
1617 struct route_node *rn;
1618 struct nexthop *nexthop;
1619
1620 int distance;
1621 u_int32_t metric = 0;
1622
1623 /* Lookup table. */
1624 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1625 if (! table)
1626 return 0;
1627
1628 /* Make sure mask is applied. */
1629 apply_mask_ipv6 (p);
1630
1631 /* Set default distance by route type. */
1632 distance = route_info[type].distance;
1633
1634 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1635 distance = 200;
1636
1637 /* Filter bogus route. */
1638 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
1639 return 0;
1640
1641 /* Lookup route node.*/
1642 rn = route_node_get (table, (struct prefix *) p);
1643
1644 /* If same type of route are installed, treat it as a implicit
1645 withdraw. */
1646 for (rib = rn->info; rib; rib = rib->next)
1647 {
1648 if (rib->type == ZEBRA_ROUTE_CONNECT)
1649 {
1650 nexthop = rib->nexthop;
1651
1652 if (rib->type == type
1653 && nexthop && nexthop->type == NEXTHOP_TYPE_IFINDEX
1654 && nexthop->ifindex == ifindex)
1655 {
1656 rib->refcnt++;
1657 return 0;
1658 }
1659 }
1660 else if (rib->type == type)
1661 {
1662 same = rib;
1663 rib_delnode (rn, same);
1664 route_unlock_node (rn);
1665 break;
1666 }
1667 }
1668
1669 /* Allocate new rib structure. */
1670 rib = XMALLOC (MTYPE_RIB, sizeof (struct rib));
1671 memset (rib, 0, sizeof (struct rib));
1672 rib->type = type;
1673 rib->distance = distance;
1674 rib->flags = flags;
1675 rib->metric = metric;
1676 rib->nexthop_num = 0;
1677 rib->uptime = time (NULL);
1678
1679 /* Nexthop settings. */
1680 if (gate)
1681 {
1682 if (ifindex)
1683 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
1684 else
1685 nexthop_ipv6_add (rib, gate);
1686 }
1687 else
1688 nexthop_ifindex_add (rib, ifindex);
1689
1690 /* If this route is kernel route, set FIB flag to the route. */
1691 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1692 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1693 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1694
1695 /* Link new rib to node.*/
1696 rib_addnode (rn, rib);
1697
1698 /* Process this route node. */
1699 rib_process (rn, same);
1700
1701 /* Free implicit route.*/
1702 if (same)
1703 newrib_free (same);
1704
1705 return 0;
1706}
1707
1708int
1709rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
1710 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1711{
1712 struct route_table *table;
1713 struct route_node *rn;
1714 struct rib *rib;
1715 struct rib *fib = NULL;
1716 struct rib *same = NULL;
1717 struct nexthop *nexthop;
1718 char buf1[BUFSIZ];
1719 char buf2[BUFSIZ];
1720
1721 /* Apply mask. */
1722 apply_mask_ipv6 (p);
1723
1724 /* Lookup table. */
1725 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1726 if (! table)
1727 return 0;
1728
1729 /* Lookup route node. */
1730 rn = route_node_lookup (table, (struct prefix *) p);
1731 if (! rn)
1732 {
1733 if (IS_ZEBRA_DEBUG_KERNEL)
1734 {
1735 if (gate)
1736 zlog_info ("route %s/%d via %s ifindex %d doesn't exist in rib",
1737 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1738 p->prefixlen,
1739 inet_ntop (AF_INET6, gate, buf2, BUFSIZ),
1740 ifindex);
1741 else
1742 zlog_info ("route %s/%d ifindex %d doesn't exist in rib",
1743 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1744 p->prefixlen,
1745 ifindex);
1746 }
1747 return ZEBRA_ERR_RTNOEXIST;
1748 }
1749
1750 /* Lookup same type route. */
1751 for (rib = rn->info; rib; rib = rib->next)
1752 {
1753 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1754 fib = rib;
1755
1756 if (rib->type == ZEBRA_ROUTE_CONNECT)
1757 {
1758 nexthop = rib->nexthop;
1759
1760 if (rib->type == type
1761 && nexthop && nexthop->type == NEXTHOP_TYPE_IFINDEX
1762 && nexthop->ifindex == ifindex)
1763 {
1764 if (rib->refcnt)
1765 {
1766 rib->refcnt--;
1767 route_unlock_node (rn);
1768 route_unlock_node (rn);
1769 return 0;
1770 }
1771 same = rib;
1772 break;
1773 }
1774 }
1775 else
1776 {
1777 if (rib->type == type)
1778 {
1779 same = rib;
1780 break;
1781 }
1782 }
1783 }
1784
1785 /* If same type of route can't be found and this message is from
1786 kernel. */
1787 if (! same)
1788 {
1789 if (fib && type == ZEBRA_ROUTE_KERNEL)
1790 {
1791 /* Unset flags. */
1792 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1793 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1794
1795 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1796 }
1797 else
1798 {
1799 if (IS_ZEBRA_DEBUG_KERNEL)
1800 {
1801 if (gate)
1802 zlog_info ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
1803 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1804 p->prefixlen,
1805 inet_ntop (AF_INET6, gate, buf2, BUFSIZ),
1806 ifindex,
1807 type);
1808 else
1809 zlog_info ("route %s/%d ifindex %d type %d doesn't exist in rib",
1810 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1811 p->prefixlen,
1812 ifindex,
1813 type);
1814 }
1815 route_unlock_node (rn);
1816 return ZEBRA_ERR_RTNOEXIST;
1817 }
1818 }
1819
1820 if (same)
1821 rib_delnode (rn, same);
1822
1823 /* Process changes. */
1824 rib_process (rn, same);
1825
1826 if (same)
1827 {
1828 newrib_free (same);
1829 route_unlock_node (rn);
1830 }
1831
1832 route_unlock_node (rn);
1833
1834 return 0;
1835}
1836
1837/* Install static route into rib. */
1838void
1839static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
1840{
1841 struct rib *rib;
1842 struct route_table *table;
1843 struct route_node *rn;
1844
1845 /* Lookup table. */
1846 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1847 if (! table)
1848 return;
1849
1850 /* Lookup existing route */
1851 rn = route_node_get (table, p);
1852 for (rib = rn->info; rib; rib = rib->next)
1853 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1854 break;
1855
1856 if (rib)
1857 {
1858 /* Same distance static route is there. Update it with new
1859 nexthop. */
1860 rib_uninstall (rn, rib);
1861 route_unlock_node (rn);
1862
1863 switch (si->type)
1864 {
1865 case STATIC_IPV6_GATEWAY:
1866 nexthop_ipv6_add (rib, &si->ipv6);
1867 break;
1868 case STATIC_IPV6_IFNAME:
1869 nexthop_ifname_add (rib, si->ifname);
1870 break;
1871 case STATIC_IPV6_GATEWAY_IFNAME:
1872 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
1873 break;
1874 }
1875 rib_process (rn, NULL);
1876 }
1877 else
1878 {
1879 /* This is new static route. */
1880 rib = XMALLOC (MTYPE_RIB, sizeof (struct rib));
1881 memset (rib, 0, sizeof (struct rib));
1882
1883 rib->type = ZEBRA_ROUTE_STATIC;
1884 rib->distance = si->distance;
1885 rib->metric = 0;
1886 rib->nexthop_num = 0;
1887
1888 switch (si->type)
1889 {
1890 case STATIC_IPV6_GATEWAY:
1891 nexthop_ipv6_add (rib, &si->ipv6);
1892 break;
1893 case STATIC_IPV6_IFNAME:
1894 nexthop_ifname_add (rib, si->ifname);
1895 break;
1896 case STATIC_IPV6_GATEWAY_IFNAME:
1897 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
1898 break;
1899 }
1900
hasso81dfcaa2003-05-25 19:21:25 +00001901 /* Save the flags of this static routes (reject, blackhole) */
1902 rib->flags = si->flags;
1903
paul718e3742002-12-13 20:15:29 +00001904 /* Link this rib to the tree. */
1905 rib_addnode (rn, rib);
1906
1907 /* Process this prefix. */
1908 rib_process (rn, NULL);
1909 }
1910}
1911
1912int
1913static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
1914{
1915 if (nexthop->type == NEXTHOP_TYPE_IPV6
1916 && si->type == STATIC_IPV6_GATEWAY
1917 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
1918 return 1;
1919 if (nexthop->type == NEXTHOP_TYPE_IFNAME
1920 && si->type == STATIC_IPV6_IFNAME
1921 && strcmp (nexthop->ifname, si->ifname) == 0)
1922 return 1;
1923 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
1924 && si->type == STATIC_IPV6_GATEWAY_IFNAME
1925 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
1926 && strcmp (nexthop->ifname, si->ifname) == 0)
1927 return 1;
1928 return 0;;
1929}
1930
1931void
1932static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
1933{
1934 struct route_table *table;
1935 struct route_node *rn;
1936 struct rib *rib;
1937 struct nexthop *nexthop;
1938
1939 /* Lookup table. */
1940 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1941 if (! table)
1942 return;
1943
1944 /* Lookup existing route with type and distance. */
1945 rn = route_node_lookup (table, (struct prefix *) p);
1946 if (! rn)
1947 return;
1948
1949 for (rib = rn->info; rib; rib = rib->next)
1950 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1951 break;
1952 if (! rib)
1953 {
1954 route_unlock_node (rn);
1955 return;
1956 }
1957
1958 /* Lookup nexthop. */
1959 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1960 if (static_ipv6_nexthop_same (nexthop, si))
1961 break;
1962
1963 /* Can't find nexthop. */
1964 if (! nexthop)
1965 {
1966 route_unlock_node (rn);
1967 return;
1968 }
1969
1970 /* Check nexthop. */
1971 if (rib->nexthop_num == 1)
1972 {
1973 rib_delnode (rn, rib);
1974 rib_process (rn, rib);
1975 newrib_free (rib);
1976 route_unlock_node (rn);
1977 }
1978 else
1979 {
1980 rib_uninstall (rn, rib);
1981 nexthop_delete (rib, nexthop);
1982 nexthop_free (nexthop);
1983 rib_process (rn, rib);
1984 }
1985
1986 /* Unlock node. */
1987 route_unlock_node (rn);
1988}
1989
1990/* Add static route into static route configuration. */
1991int
1992static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso81dfcaa2003-05-25 19:21:25 +00001993 char *ifname, u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001994{
1995 struct route_node *rn;
1996 struct static_ipv6 *si;
1997 struct static_ipv6 *pp;
1998 struct static_ipv6 *cp;
1999 struct route_table *stable;
2000
2001 /* Lookup table. */
2002 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2003 if (! stable)
2004 return -1;
2005
2006 /* Lookup static route prefix. */
2007 rn = route_node_get (stable, p);
2008
2009 /* Do nothing if there is a same static route. */
2010 for (si = rn->info; si; si = si->next)
2011 {
2012 if (distance == si->distance
2013 && type == si->type
2014 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2015 && (! ifname || strcmp (ifname, si->ifname) == 0))
2016 {
2017 route_unlock_node (rn);
2018 return 0;
2019 }
2020 }
2021
2022 /* Make new static route structure. */
2023 si = XMALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
2024 memset (si, 0, sizeof (struct static_ipv6));
2025
2026 si->type = type;
2027 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002028 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002029
2030 switch (type)
2031 {
2032 case STATIC_IPV6_GATEWAY:
2033 si->ipv6 = *gate;
2034 break;
2035 case STATIC_IPV6_IFNAME:
2036 si->ifname = XSTRDUP (0, ifname);
2037 break;
2038 case STATIC_IPV6_GATEWAY_IFNAME:
2039 si->ipv6 = *gate;
2040 si->ifname = XSTRDUP (0, ifname);
2041 break;
2042 }
2043
2044 /* Add new static route information to the tree with sort by
2045 distance value and gateway address. */
2046 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2047 {
2048 if (si->distance < cp->distance)
2049 break;
2050 if (si->distance > cp->distance)
2051 continue;
2052 }
2053
2054 /* Make linked list. */
2055 if (pp)
2056 pp->next = si;
2057 else
2058 rn->info = si;
2059 if (cp)
2060 cp->prev = si;
2061 si->prev = pp;
2062 si->next = cp;
2063
2064 /* Install into rib. */
2065 static_install_ipv6 (p, si);
2066
2067 return 1;
2068}
2069
2070/* Delete static route from static route configuration. */
2071int
2072static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
2073 char *ifname, u_char distance, u_int32_t vrf_id)
2074{
2075 struct route_node *rn;
2076 struct static_ipv6 *si;
2077 struct route_table *stable;
2078
2079 /* Lookup table. */
2080 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2081 if (! stable)
2082 return -1;
2083
2084 /* Lookup static route prefix. */
2085 rn = route_node_lookup (stable, p);
2086 if (! rn)
2087 return 0;
2088
2089 /* Find same static route is the tree */
2090 for (si = rn->info; si; si = si->next)
2091 if (distance == si->distance
2092 && type == si->type
2093 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2094 && (! ifname || strcmp (ifname, si->ifname) == 0))
2095 break;
2096
2097 /* Can't find static route. */
2098 if (! si)
2099 {
2100 route_unlock_node (rn);
2101 return 0;
2102 }
2103
2104 /* Install into rib. */
2105 static_uninstall_ipv6 (p, si);
2106
2107 /* Unlink static route from linked list. */
2108 if (si->prev)
2109 si->prev->next = si->next;
2110 else
2111 rn->info = si->next;
2112 if (si->next)
2113 si->next->prev = si->prev;
2114
2115 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002116 if (ifname)
2117 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00002118 XFREE (MTYPE_STATIC_IPV6, si);
2119
2120 return 1;
2121}
2122#endif /* HAVE_IPV6 */
2123
2124/* RIB update function. */
2125void
2126rib_update ()
2127{
2128 struct route_node *rn;
2129 struct route_table *table;
2130
2131 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2132 if (table)
2133 for (rn = route_top (table); rn; rn = route_next (rn))
2134 rib_process (rn, NULL);
2135
2136 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2137 if (table)
2138 for (rn = route_top (table); rn; rn = route_next (rn))
2139 rib_process (rn, NULL);
2140}
2141
2142/* Interface goes up. */
2143void
2144rib_if_up (struct interface *ifp)
2145{
2146 rib_update ();
2147}
2148
2149/* Interface goes down. */
2150void
2151rib_if_down (struct interface *ifp)
2152{
2153 rib_update ();
2154}
2155
2156/* Remove all routes which comes from non main table. */
2157void
2158rib_weed_table (struct route_table *table)
2159{
2160 struct route_node *rn;
2161 struct rib *rib;
2162 struct rib *next;
2163
2164 if (table)
2165 for (rn = route_top (table); rn; rn = route_next (rn))
2166 for (rib = rn->info; rib; rib = next)
2167 {
2168 next = rib->next;
2169
paulb21b19c2003-06-15 01:28:29 +00002170 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00002171 rib->table != RT_TABLE_MAIN)
2172 {
2173 rib_delnode (rn, rib);
2174 newrib_free (rib);
2175 route_unlock_node (rn);
2176 }
2177 }
2178}
2179
2180/* Delete all routes from non main table. */
2181void
2182rib_weed_tables ()
2183{
2184 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2185 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2186}
2187
2188/* Delete self installed routes after zebra is relaunched. */
2189void
2190rib_sweep_table (struct route_table *table)
2191{
2192 struct route_node *rn;
2193 struct rib *rib;
2194 struct rib *next;
2195 int ret = 0;
2196
2197 if (table)
2198 for (rn = route_top (table); rn; rn = route_next (rn))
2199 for (rib = rn->info; rib; rib = next)
2200 {
2201 next = rib->next;
2202
2203 if (rib->type == ZEBRA_ROUTE_KERNEL &&
2204 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
2205 {
2206 ret = rib_uninstall_kernel (rn, rib);
2207 if (! ret)
2208 {
2209 rib_delnode (rn, rib);
2210 newrib_free (rib);
2211 route_unlock_node (rn);
2212 }
2213 }
2214 }
2215}
2216
2217/* Sweep all RIB tables. */
2218void
2219rib_sweep_route ()
2220{
2221 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2222 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2223}
2224
2225/* Close RIB and clean up kernel routes. */
2226void
2227rib_close_table (struct route_table *table)
2228{
2229 struct route_node *rn;
2230 struct rib *rib;
2231
2232 if (table)
2233 for (rn = route_top (table); rn; rn = route_next (rn))
2234 for (rib = rn->info; rib; rib = rib->next)
2235 if (! RIB_SYSTEM_ROUTE (rib)
2236 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2237 rib_uninstall_kernel (rn, rib);
2238}
2239
2240/* Close all RIB tables. */
2241void
2242rib_close ()
2243{
2244 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2245 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2246}
2247
2248/* Routing information base initialize. */
2249void
2250rib_init ()
2251{
2252 /* VRF initialization. */
2253 vrf_init ();
2254}