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