blob: ec07e2e3a0b5e6f2aedb555ea716ccce22f9cb65 [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{
190 if (nexthop->type == NEXTHOP_TYPE_IFNAME && nexthop->ifname)
191 free (nexthop->ifname);
192 XFREE (MTYPE_NEXTHOP, nexthop);
193}
194
195struct nexthop *
196nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
197{
198 struct nexthop *nexthop;
199
200 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
201 memset (nexthop, 0, sizeof (struct nexthop));
202 nexthop->type = NEXTHOP_TYPE_IFINDEX;
203 nexthop->ifindex = ifindex;
204
205 nexthop_add (rib, nexthop);
206
207 return nexthop;
208}
209
210struct nexthop *
211nexthop_ifname_add (struct rib *rib, char *ifname)
212{
213 struct nexthop *nexthop;
214
215 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
216 memset (nexthop, 0, sizeof (struct nexthop));
217 nexthop->type = NEXTHOP_TYPE_IFNAME;
218 nexthop->ifname = strdup (ifname);
219
220 nexthop_add (rib, nexthop);
221
222 return nexthop;
223}
224
225struct nexthop *
226nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4)
227{
228 struct nexthop *nexthop;
229
230 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
231 memset (nexthop, 0, sizeof (struct nexthop));
232 nexthop->type = NEXTHOP_TYPE_IPV4;
233 nexthop->gate.ipv4 = *ipv4;
234
235 nexthop_add (rib, nexthop);
236
237 return nexthop;
238}
239
240struct nexthop *
241nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
242 unsigned int ifindex)
243{
244 struct nexthop *nexthop;
245
246 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
247 memset (nexthop, 0, sizeof (struct nexthop));
248 nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
249 nexthop->gate.ipv4 = *ipv4;
250 nexthop->ifindex = ifindex;
251
252 nexthop_add (rib, nexthop);
253
254 return nexthop;
255}
256
257#ifdef HAVE_IPV6
258struct nexthop *
259nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
260{
261 struct nexthop *nexthop;
262
263 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
264 memset (nexthop, 0, sizeof (struct nexthop));
265 nexthop->type = NEXTHOP_TYPE_IPV6;
266 nexthop->gate.ipv6 = *ipv6;
267
268 nexthop_add (rib, nexthop);
269
270 return nexthop;
271}
272
273struct nexthop *
274nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
275 char *ifname)
276{
277 struct nexthop *nexthop;
278
279 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
280 memset (nexthop, 0, sizeof (struct nexthop));
281 nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
282 nexthop->gate.ipv6 = *ipv6;
283 nexthop->ifname = XSTRDUP (0, ifname);
284
285 nexthop_add (rib, nexthop);
286
287 return nexthop;
288}
289
290struct nexthop *
291nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
292 unsigned int ifindex)
293{
294 struct nexthop *nexthop;
295
296 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
297 memset (nexthop, 0, sizeof (struct nexthop));
298 nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
299 nexthop->gate.ipv6 = *ipv6;
300 nexthop->ifindex = ifindex;
301
302 nexthop_add (rib, nexthop);
303
304 return nexthop;
305}
306#endif /* HAVE_IPV6 */
307
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;
858
859 for (rib = rn->info; rib; rib = next)
860 {
861 next = rib->next;
862
863 /* Currently installed rib. */
864 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
865 fib = rib;
866
867 /* Skip unreachable nexthop. */
868 if (! nexthop_active_update (rn, rib, 0))
869 continue;
870
871 /* Infinit distance. */
872 if (rib->distance == DISTANCE_INFINITY)
873 continue;
874
875 /* Newly selected rib. */
876 if (! select || rib->distance < select->distance
877 || rib->type == ZEBRA_ROUTE_CONNECT)
878 select = rib;
879 }
880
881 /* Deleted route check. */
882 if (del && CHECK_FLAG (del->flags, ZEBRA_FLAG_SELECTED))
883 fib = del;
884
885 /* Same route is selected. */
886 if (select && select == fib)
887 {
888 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
889 {
890 redistribute_delete (&rn->p, select);
891 if (! RIB_SYSTEM_ROUTE (select))
892 rib_uninstall_kernel (rn, select);
893
894 /* Set real nexthop. */
895 nexthop_active_update (rn, select, 1);
896
897 if (! RIB_SYSTEM_ROUTE (select))
898 rib_install_kernel (rn, select);
899 redistribute_add (&rn->p, select);
900 }
901 return;
902 }
903
904 /* Uninstall old rib from forwarding table. */
905 if (fib)
906 {
907 redistribute_delete (&rn->p, fib);
908 if (! RIB_SYSTEM_ROUTE (fib))
909 rib_uninstall_kernel (rn, fib);
910 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
911
912 /* Set real nexthop. */
913 nexthop_active_update (rn, fib, 1);
914 }
915
916 /* Install new rib into forwarding table. */
917 if (select)
918 {
919 /* Set real nexthop. */
920 nexthop_active_update (rn, select, 1);
921
922 if (! RIB_SYSTEM_ROUTE (select))
923 rib_install_kernel (rn, select);
924 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
925 redistribute_add (&rn->p, select);
926 }
927}
928
929/* Add RIB to head of the route node. */
930void
931rib_addnode (struct route_node *rn, struct rib *rib)
932{
933 struct rib *head;
934
935 head = rn->info;
936 if (head)
937 head->prev = rib;
938 rib->next = head;
939 rn->info = rib;
940}
941
942void
943rib_delnode (struct route_node *rn, struct rib *rib)
944{
945 if (rib->next)
946 rib->next->prev = rib->prev;
947 if (rib->prev)
948 rib->prev->next = rib->next;
949 else
950 rn->info = rib->next;
951}
952
953int
954rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
955 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
956 u_int32_t metric, u_char distance)
957{
958 struct rib *rib;
959 struct rib *same = NULL;
960 struct route_table *table;
961 struct route_node *rn;
962 struct nexthop *nexthop;
963
964 /* Lookup table. */
965 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
966 if (! table)
967 return 0;
968
969 /* Make it sure prefixlen is applied to the prefix. */
970 apply_mask_ipv4 (p);
971
972 /* Set default distance by route type. */
973 if (distance == 0)
974 {
975 distance = route_info[type].distance;
976
977 /* iBGP distance is 200. */
978 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
979 distance = 200;
980 }
981
982 /* Lookup route node.*/
983 rn = route_node_get (table, (struct prefix *) p);
984
985 /* If same type of route are installed, treat it as a implicit
986 withdraw. */
987 for (rib = rn->info; rib; rib = rib->next)
988 {
989 if (rib->type == ZEBRA_ROUTE_CONNECT)
990 {
991 nexthop = rib->nexthop;
992
993 /* Duplicate connected route comes in. */
994 if (rib->type == type
995 && nexthop && nexthop->type == NEXTHOP_TYPE_IFINDEX
996 && nexthop->ifindex == ifindex)
997 {
998 rib->refcnt++;
999 return 0 ;
1000 }
1001 }
1002 else if (rib->type == type)
1003 {
1004 same = rib;
1005 rib_delnode (rn, same);
1006 route_unlock_node (rn);
1007 break;
1008 }
1009 }
1010
1011 /* Allocate new rib structure. */
1012 rib = XMALLOC (MTYPE_RIB, sizeof (struct rib));
1013 memset (rib, 0, sizeof (struct rib));
1014 rib->type = type;
1015 rib->distance = distance;
1016 rib->flags = flags;
1017 rib->metric = metric;
1018 rib->nexthop_num = 0;
1019 rib->uptime = time (NULL);
1020
1021 /* Nexthop settings. */
1022 if (gate)
1023 {
1024 if (ifindex)
1025 nexthop_ipv4_ifindex_add (rib, gate, ifindex);
1026 else
1027 nexthop_ipv4_add (rib, gate);
1028 }
1029 else
1030 nexthop_ifindex_add (rib, ifindex);
1031
1032 /* If this route is kernel route, set FIB flag to the route. */
1033 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1034 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1035 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1036
1037 /* Link new rib to node.*/
1038 rib_addnode (rn, rib);
1039
1040 /* Process this route node. */
1041 rib_process (rn, same);
1042
1043 /* Free implicit route.*/
1044 if (same)
1045 newrib_free (same);
1046
1047 return 0;
1048}
1049
1050int
1051rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib)
1052{
1053 struct route_table *table;
1054 struct route_node *rn;
1055 struct rib *same;
1056 struct nexthop *nexthop;
1057
1058 /* Lookup table. */
1059 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1060 if (! table)
1061 return 0;
1062
1063 /* Make it sure prefixlen is applied to the prefix. */
1064 apply_mask_ipv4 (p);
1065
1066 /* Set default distance by route type. */
1067 if (rib->distance == 0)
1068 {
1069 rib->distance = route_info[rib->type].distance;
1070
1071 /* iBGP distance is 200. */
1072 if (rib->type == ZEBRA_ROUTE_BGP
1073 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1074 rib->distance = 200;
1075 }
1076
1077 /* Lookup route node.*/
1078 rn = route_node_get (table, (struct prefix *) p);
1079
1080 /* If same type of route are installed, treat it as a implicit
1081 withdraw. */
1082 for (same = rn->info; same; same = same->next)
1083 {
1084 if (same->type == rib->type && same->table == rib->table
1085 && same->type != ZEBRA_ROUTE_CONNECT)
1086 {
1087 rib_delnode (rn, same);
1088 route_unlock_node (rn);
1089 break;
1090 }
1091 }
1092
1093 /* If this route is kernel route, set FIB flag to the route. */
1094 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
1095 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1096 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1097
1098 /* Link new rib to node.*/
1099 rib_addnode (rn, rib);
1100
1101 /* Process this route node. */
1102 rib_process (rn, same);
1103
1104 /* Free implicit route.*/
1105 if (same)
1106 newrib_free (same);
1107
1108 return 0;
1109}
1110
1111int
1112rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
1113 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1114{
1115 struct route_table *table;
1116 struct route_node *rn;
1117 struct rib *rib;
1118 struct rib *fib = NULL;
1119 struct rib *same = NULL;
1120 struct nexthop *nexthop;
1121 char buf1[BUFSIZ];
1122 char buf2[BUFSIZ];
1123
1124 /* Lookup table. */
1125 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1126 if (! table)
1127 return 0;
1128
1129 /* Apply mask. */
1130 apply_mask_ipv4 (p);
1131
1132 /* Lookup route node. */
1133 rn = route_node_lookup (table, (struct prefix *) p);
1134 if (! rn)
1135 {
1136 if (IS_ZEBRA_DEBUG_KERNEL)
1137 {
1138 if (gate)
1139 zlog_info ("route %s/%d via %s ifindex %d doesn't exist in rib",
1140 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1141 p->prefixlen,
1142 inet_ntop (AF_INET, gate, buf2, BUFSIZ),
1143 ifindex);
1144 else
1145 zlog_info ("route %s/%d ifindex %d doesn't exist in rib",
1146 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1147 p->prefixlen,
1148 ifindex);
1149 }
1150 return ZEBRA_ERR_RTNOEXIST;
1151 }
1152
1153 /* Lookup same type route. */
1154 for (rib = rn->info; rib; rib = rib->next)
1155 {
1156 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1157 fib = rib;
1158
1159 if (rib->type == ZEBRA_ROUTE_CONNECT)
1160 {
1161 nexthop = rib->nexthop;
1162
1163 if (rib->type == type
1164 && nexthop && nexthop->type == NEXTHOP_TYPE_IFINDEX
1165 && nexthop->ifindex == ifindex)
1166 {
1167 if (rib->refcnt)
1168 {
1169 rib->refcnt--;
1170 route_unlock_node (rn);
1171 route_unlock_node (rn);
1172 return 0;
1173 }
1174 same = rib;
1175 break;
1176 }
1177 }
1178 else
1179 {
1180 if (rib->type == type)
1181 {
1182 same = rib;
1183 break;
1184 }
1185 }
1186 }
1187
1188 /* If same type of route can't be found and this message is from
1189 kernel. */
1190 if (! same)
1191 {
1192 if (fib && type == ZEBRA_ROUTE_KERNEL)
1193 {
1194 /* Unset flags. */
1195 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1196 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1197
1198 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1199 }
1200 else
1201 {
1202 if (IS_ZEBRA_DEBUG_KERNEL)
1203 {
1204 if (gate)
1205 zlog_info ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
1206 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1207 p->prefixlen,
1208 inet_ntop (AF_INET, gate, buf2, BUFSIZ),
1209 ifindex,
1210 type);
1211 else
1212 zlog_info ("route %s/%d ifindex %d type %d doesn't exist in rib",
1213 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1214 p->prefixlen,
1215 ifindex,
1216 type);
1217 }
1218 route_unlock_node (rn);
1219 return ZEBRA_ERR_RTNOEXIST;
1220 }
1221 }
1222
1223 if (same)
1224 rib_delnode (rn, same);
1225
1226 /* Process changes. */
1227 rib_process (rn, same);
1228
1229 if (same)
1230 {
1231 newrib_free (same);
1232 route_unlock_node (rn);
1233 }
1234
1235 route_unlock_node (rn);
1236
1237 return 0;
1238}
1239
1240/* Install static route into rib. */
1241void
1242static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
1243{
1244 struct rib *rib;
1245 struct route_node *rn;
1246 struct route_table *table;
1247
1248 /* Lookup table. */
1249 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1250 if (! table)
1251 return;
1252
1253 /* Lookup existing route */
1254 rn = route_node_get (table, p);
1255 for (rib = rn->info; rib; rib = rib->next)
1256 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1257 break;
1258
1259 if (rib)
1260 {
1261 /* Same distance static route is there. Update it with new
1262 nexthop. */
1263 rib_uninstall (rn, rib);
1264 route_unlock_node (rn);
1265
1266 switch (si->type)
1267 {
1268 case STATIC_IPV4_GATEWAY:
1269 nexthop_ipv4_add (rib, &si->gate.ipv4);
1270 break;
1271 case STATIC_IPV4_IFNAME:
1272 nexthop_ifname_add (rib, si->gate.ifname);
1273 break;
1274 case STATIC_IPV4_BLACKHOLE:
1275 nexthop_blackhole_add (rib);
1276 break;
1277 }
1278 rib_process (rn, NULL);
1279 }
1280 else
1281 {
1282 /* This is new static route. */
1283 rib = XMALLOC (MTYPE_RIB, sizeof (struct rib));
1284 memset (rib, 0, sizeof (struct rib));
1285
1286 rib->type = ZEBRA_ROUTE_STATIC;
1287 rib->distance = si->distance;
1288 rib->metric = 0;
1289 rib->nexthop_num = 0;
1290
1291 switch (si->type)
1292 {
1293 case STATIC_IPV4_GATEWAY:
1294 nexthop_ipv4_add (rib, &si->gate.ipv4);
1295 break;
1296 case STATIC_IPV4_IFNAME:
1297 nexthop_ifname_add (rib, si->gate.ifname);
1298 break;
1299 case STATIC_IPV4_BLACKHOLE:
1300 nexthop_blackhole_add (rib);
1301 break;
1302 }
1303
1304 /* Link this rib to the tree. */
1305 rib_addnode (rn, rib);
1306
1307 /* Process this prefix. */
1308 rib_process (rn, NULL);
1309 }
1310}
1311
1312int
1313static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
1314{
1315 if (nexthop->type == NEXTHOP_TYPE_IPV4
1316 && si->type == STATIC_IPV4_GATEWAY
1317 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
1318 return 1;
1319 if (nexthop->type == NEXTHOP_TYPE_IFNAME
1320 && si->type == STATIC_IPV4_IFNAME
1321 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
1322 return 1;
1323 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
1324 && si->type == STATIC_IPV4_BLACKHOLE)
1325 return 1;
1326 return 0;;
1327}
1328
1329/* Uninstall static route from RIB. */
1330void
1331static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
1332{
1333 struct route_node *rn;
1334 struct rib *rib;
1335 struct nexthop *nexthop;
1336 struct route_table *table;
1337
1338 /* Lookup table. */
1339 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1340 if (! table)
1341 return;
1342
1343 /* Lookup existing route with type and distance. */
1344 rn = route_node_lookup (table, p);
1345 if (! rn)
1346 return;
1347
1348 for (rib = rn->info; rib; rib = rib->next)
1349 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1350 break;
1351
1352 if (! rib)
1353 {
1354 route_unlock_node (rn);
1355 return;
1356 }
1357
1358 /* Lookup nexthop. */
1359 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1360 if (static_ipv4_nexthop_same (nexthop, si))
1361 break;
1362
1363 /* Can't find nexthop. */
1364 if (! nexthop)
1365 {
1366 route_unlock_node (rn);
1367 return;
1368 }
1369
1370 /* Check nexthop. */
1371 if (rib->nexthop_num == 1)
1372 {
1373 rib_delnode (rn, rib);
1374 rib_process (rn, rib);
1375 newrib_free (rib);
1376 route_unlock_node (rn);
1377 }
1378 else
1379 {
1380 rib_uninstall (rn, rib);
1381 nexthop_delete (rib, nexthop);
1382 nexthop_free (nexthop);
1383 rib_process (rn, rib);
1384 }
1385
1386 /* Unlock node. */
1387 route_unlock_node (rn);
1388}
1389
1390/* Add static route into static route configuration. */
1391int
1392static_add_ipv4 (struct prefix *p, struct in_addr *gate, char *ifname,
1393 u_char distance, u_int32_t vrf_id)
1394{
1395 u_char type = 0;
1396 struct route_node *rn;
1397 struct static_ipv4 *si;
1398 struct static_ipv4 *pp;
1399 struct static_ipv4 *cp;
1400 struct static_ipv4 *update = NULL;
1401 struct route_table *stable;
1402
1403 /* Lookup table. */
1404 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
1405 if (! stable)
1406 return -1;
1407
1408 /* Lookup static route prefix. */
1409 rn = route_node_get (stable, p);
1410
1411 /* Make flags. */
1412 if (gate)
1413 type = STATIC_IPV4_GATEWAY;
1414 else if (ifname)
1415 type = STATIC_IPV4_IFNAME;
1416 else
1417 type = STATIC_IPV4_BLACKHOLE;
1418
1419 /* Do nothing if there is a same static route. */
1420 for (si = rn->info; si; si = si->next)
1421 {
1422 if (type == si->type
1423 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
1424 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
1425 {
1426 if (distance == si->distance)
1427 {
1428 route_unlock_node (rn);
1429 return 0;
1430 }
1431 else
1432 update = si;
1433 }
1434 }
1435
1436 /* Distance chaged. */
1437 if (update)
1438 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
1439
1440 /* Make new static route structure. */
1441 si = XMALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
1442 memset (si, 0, sizeof (struct static_ipv4));
1443
1444 si->type = type;
1445 si->distance = distance;
1446
1447 if (gate)
1448 si->gate.ipv4 = *gate;
1449 if (ifname)
1450 si->gate.ifname = XSTRDUP (0, ifname);
1451
1452 /* Add new static route information to the tree with sort by
1453 distance value and gateway address. */
1454 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
1455 {
1456 if (si->distance < cp->distance)
1457 break;
1458 if (si->distance > cp->distance)
1459 continue;
1460 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
1461 {
1462 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
1463 break;
1464 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
1465 continue;
1466 }
1467 }
1468
1469 /* Make linked list. */
1470 if (pp)
1471 pp->next = si;
1472 else
1473 rn->info = si;
1474 if (cp)
1475 cp->prev = si;
1476 si->prev = pp;
1477 si->next = cp;
1478
1479 /* Install into rib. */
1480 static_install_ipv4 (p, si);
1481
1482 return 1;
1483}
1484
1485/* Delete static route from static route configuration. */
1486int
1487static_delete_ipv4 (struct prefix *p, struct in_addr *gate, char *ifname,
1488 u_char distance, u_int32_t vrf_id)
1489{
1490 u_char type = 0;
1491 struct route_node *rn;
1492 struct static_ipv4 *si;
1493 struct route_table *stable;
1494
1495 /* Lookup table. */
1496 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
1497 if (! stable)
1498 return -1;
1499
1500 /* Lookup static route prefix. */
1501 rn = route_node_lookup (stable, p);
1502 if (! rn)
1503 return 0;
1504
1505 /* Make flags. */
1506 if (gate)
1507 type = STATIC_IPV4_GATEWAY;
1508 else if (ifname)
1509 type = STATIC_IPV4_IFNAME;
1510 else
1511 type = STATIC_IPV4_BLACKHOLE;
1512
1513 /* Find same static route is the tree */
1514 for (si = rn->info; si; si = si->next)
1515 if (type == si->type
1516 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
1517 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
1518 break;
1519
1520 /* Can't find static route. */
1521 if (! si)
1522 {
1523 route_unlock_node (rn);
1524 return 0;
1525 }
1526
1527 /* Install into rib. */
1528 static_uninstall_ipv4 (p, si);
1529
1530 /* Unlink static route from linked list. */
1531 if (si->prev)
1532 si->prev->next = si->next;
1533 else
1534 rn->info = si->next;
1535 if (si->next)
1536 si->next->prev = si->prev;
1537
1538 /* Free static route configuration. */
1539 XFREE (MTYPE_STATIC_IPV4, si);
1540
1541 return 1;
1542}
1543
1544
1545#ifdef HAVE_IPV6
1546int
1547rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
1548 struct in6_addr *gate, unsigned int ifindex, int table)
1549{
1550 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix))
1551 return 1;
1552 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
1553 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
1554 {
1555 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
1556 return 1;
1557 }
1558 return 0;
1559}
1560
1561int
1562rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
1563 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1564{
1565 struct rib *rib;
1566 struct rib *same = NULL;
1567 struct route_table *table;
1568 struct route_node *rn;
1569 struct nexthop *nexthop;
1570
1571 int distance;
1572 u_int32_t metric = 0;
1573
1574 /* Lookup table. */
1575 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1576 if (! table)
1577 return 0;
1578
1579 /* Make sure mask is applied. */
1580 apply_mask_ipv6 (p);
1581
1582 /* Set default distance by route type. */
1583 distance = route_info[type].distance;
1584
1585 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1586 distance = 200;
1587
1588 /* Filter bogus route. */
1589 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
1590 return 0;
1591
1592 /* Lookup route node.*/
1593 rn = route_node_get (table, (struct prefix *) p);
1594
1595 /* If same type of route are installed, treat it as a implicit
1596 withdraw. */
1597 for (rib = rn->info; rib; rib = rib->next)
1598 {
1599 if (rib->type == ZEBRA_ROUTE_CONNECT)
1600 {
1601 nexthop = rib->nexthop;
1602
1603 if (rib->type == type
1604 && nexthop && nexthop->type == NEXTHOP_TYPE_IFINDEX
1605 && nexthop->ifindex == ifindex)
1606 {
1607 rib->refcnt++;
1608 return 0;
1609 }
1610 }
1611 else if (rib->type == type)
1612 {
1613 same = rib;
1614 rib_delnode (rn, same);
1615 route_unlock_node (rn);
1616 break;
1617 }
1618 }
1619
1620 /* Allocate new rib structure. */
1621 rib = XMALLOC (MTYPE_RIB, sizeof (struct rib));
1622 memset (rib, 0, sizeof (struct rib));
1623 rib->type = type;
1624 rib->distance = distance;
1625 rib->flags = flags;
1626 rib->metric = metric;
1627 rib->nexthop_num = 0;
1628 rib->uptime = time (NULL);
1629
1630 /* Nexthop settings. */
1631 if (gate)
1632 {
1633 if (ifindex)
1634 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
1635 else
1636 nexthop_ipv6_add (rib, gate);
1637 }
1638 else
1639 nexthop_ifindex_add (rib, ifindex);
1640
1641 /* If this route is kernel route, set FIB flag to the route. */
1642 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1643 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1644 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1645
1646 /* Link new rib to node.*/
1647 rib_addnode (rn, rib);
1648
1649 /* Process this route node. */
1650 rib_process (rn, same);
1651
1652 /* Free implicit route.*/
1653 if (same)
1654 newrib_free (same);
1655
1656 return 0;
1657}
1658
1659int
1660rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
1661 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1662{
1663 struct route_table *table;
1664 struct route_node *rn;
1665 struct rib *rib;
1666 struct rib *fib = NULL;
1667 struct rib *same = NULL;
1668 struct nexthop *nexthop;
1669 char buf1[BUFSIZ];
1670 char buf2[BUFSIZ];
1671
1672 /* Apply mask. */
1673 apply_mask_ipv6 (p);
1674
1675 /* Lookup table. */
1676 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1677 if (! table)
1678 return 0;
1679
1680 /* Lookup route node. */
1681 rn = route_node_lookup (table, (struct prefix *) p);
1682 if (! rn)
1683 {
1684 if (IS_ZEBRA_DEBUG_KERNEL)
1685 {
1686 if (gate)
1687 zlog_info ("route %s/%d via %s ifindex %d doesn't exist in rib",
1688 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1689 p->prefixlen,
1690 inet_ntop (AF_INET6, gate, buf2, BUFSIZ),
1691 ifindex);
1692 else
1693 zlog_info ("route %s/%d ifindex %d doesn't exist in rib",
1694 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1695 p->prefixlen,
1696 ifindex);
1697 }
1698 return ZEBRA_ERR_RTNOEXIST;
1699 }
1700
1701 /* Lookup same type route. */
1702 for (rib = rn->info; rib; rib = rib->next)
1703 {
1704 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1705 fib = rib;
1706
1707 if (rib->type == ZEBRA_ROUTE_CONNECT)
1708 {
1709 nexthop = rib->nexthop;
1710
1711 if (rib->type == type
1712 && nexthop && nexthop->type == NEXTHOP_TYPE_IFINDEX
1713 && nexthop->ifindex == ifindex)
1714 {
1715 if (rib->refcnt)
1716 {
1717 rib->refcnt--;
1718 route_unlock_node (rn);
1719 route_unlock_node (rn);
1720 return 0;
1721 }
1722 same = rib;
1723 break;
1724 }
1725 }
1726 else
1727 {
1728 if (rib->type == type)
1729 {
1730 same = rib;
1731 break;
1732 }
1733 }
1734 }
1735
1736 /* If same type of route can't be found and this message is from
1737 kernel. */
1738 if (! same)
1739 {
1740 if (fib && type == ZEBRA_ROUTE_KERNEL)
1741 {
1742 /* Unset flags. */
1743 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1744 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1745
1746 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1747 }
1748 else
1749 {
1750 if (IS_ZEBRA_DEBUG_KERNEL)
1751 {
1752 if (gate)
1753 zlog_info ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
1754 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1755 p->prefixlen,
1756 inet_ntop (AF_INET6, gate, buf2, BUFSIZ),
1757 ifindex,
1758 type);
1759 else
1760 zlog_info ("route %s/%d ifindex %d type %d doesn't exist in rib",
1761 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1762 p->prefixlen,
1763 ifindex,
1764 type);
1765 }
1766 route_unlock_node (rn);
1767 return ZEBRA_ERR_RTNOEXIST;
1768 }
1769 }
1770
1771 if (same)
1772 rib_delnode (rn, same);
1773
1774 /* Process changes. */
1775 rib_process (rn, same);
1776
1777 if (same)
1778 {
1779 newrib_free (same);
1780 route_unlock_node (rn);
1781 }
1782
1783 route_unlock_node (rn);
1784
1785 return 0;
1786}
1787
1788/* Install static route into rib. */
1789void
1790static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
1791{
1792 struct rib *rib;
1793 struct route_table *table;
1794 struct route_node *rn;
1795
1796 /* Lookup table. */
1797 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1798 if (! table)
1799 return;
1800
1801 /* Lookup existing route */
1802 rn = route_node_get (table, p);
1803 for (rib = rn->info; rib; rib = rib->next)
1804 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1805 break;
1806
1807 if (rib)
1808 {
1809 /* Same distance static route is there. Update it with new
1810 nexthop. */
1811 rib_uninstall (rn, rib);
1812 route_unlock_node (rn);
1813
1814 switch (si->type)
1815 {
1816 case STATIC_IPV6_GATEWAY:
1817 nexthop_ipv6_add (rib, &si->ipv6);
1818 break;
1819 case STATIC_IPV6_IFNAME:
1820 nexthop_ifname_add (rib, si->ifname);
1821 break;
1822 case STATIC_IPV6_GATEWAY_IFNAME:
1823 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
1824 break;
1825 }
1826 rib_process (rn, NULL);
1827 }
1828 else
1829 {
1830 /* This is new static route. */
1831 rib = XMALLOC (MTYPE_RIB, sizeof (struct rib));
1832 memset (rib, 0, sizeof (struct rib));
1833
1834 rib->type = ZEBRA_ROUTE_STATIC;
1835 rib->distance = si->distance;
1836 rib->metric = 0;
1837 rib->nexthop_num = 0;
1838
1839 switch (si->type)
1840 {
1841 case STATIC_IPV6_GATEWAY:
1842 nexthop_ipv6_add (rib, &si->ipv6);
1843 break;
1844 case STATIC_IPV6_IFNAME:
1845 nexthop_ifname_add (rib, si->ifname);
1846 break;
1847 case STATIC_IPV6_GATEWAY_IFNAME:
1848 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
1849 break;
1850 }
1851
1852 /* Link this rib to the tree. */
1853 rib_addnode (rn, rib);
1854
1855 /* Process this prefix. */
1856 rib_process (rn, NULL);
1857 }
1858}
1859
1860int
1861static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
1862{
1863 if (nexthop->type == NEXTHOP_TYPE_IPV6
1864 && si->type == STATIC_IPV6_GATEWAY
1865 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
1866 return 1;
1867 if (nexthop->type == NEXTHOP_TYPE_IFNAME
1868 && si->type == STATIC_IPV6_IFNAME
1869 && strcmp (nexthop->ifname, si->ifname) == 0)
1870 return 1;
1871 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
1872 && si->type == STATIC_IPV6_GATEWAY_IFNAME
1873 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
1874 && strcmp (nexthop->ifname, si->ifname) == 0)
1875 return 1;
1876 return 0;;
1877}
1878
1879void
1880static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
1881{
1882 struct route_table *table;
1883 struct route_node *rn;
1884 struct rib *rib;
1885 struct nexthop *nexthop;
1886
1887 /* Lookup table. */
1888 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1889 if (! table)
1890 return;
1891
1892 /* Lookup existing route with type and distance. */
1893 rn = route_node_lookup (table, (struct prefix *) p);
1894 if (! rn)
1895 return;
1896
1897 for (rib = rn->info; rib; rib = rib->next)
1898 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1899 break;
1900 if (! rib)
1901 {
1902 route_unlock_node (rn);
1903 return;
1904 }
1905
1906 /* Lookup nexthop. */
1907 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1908 if (static_ipv6_nexthop_same (nexthop, si))
1909 break;
1910
1911 /* Can't find nexthop. */
1912 if (! nexthop)
1913 {
1914 route_unlock_node (rn);
1915 return;
1916 }
1917
1918 /* Check nexthop. */
1919 if (rib->nexthop_num == 1)
1920 {
1921 rib_delnode (rn, rib);
1922 rib_process (rn, rib);
1923 newrib_free (rib);
1924 route_unlock_node (rn);
1925 }
1926 else
1927 {
1928 rib_uninstall (rn, rib);
1929 nexthop_delete (rib, nexthop);
1930 nexthop_free (nexthop);
1931 rib_process (rn, rib);
1932 }
1933
1934 /* Unlock node. */
1935 route_unlock_node (rn);
1936}
1937
1938/* Add static route into static route configuration. */
1939int
1940static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
1941 char *ifname, u_char distance, u_int32_t vrf_id)
1942{
1943 struct route_node *rn;
1944 struct static_ipv6 *si;
1945 struct static_ipv6 *pp;
1946 struct static_ipv6 *cp;
1947 struct route_table *stable;
1948
1949 /* Lookup table. */
1950 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
1951 if (! stable)
1952 return -1;
1953
1954 /* Lookup static route prefix. */
1955 rn = route_node_get (stable, p);
1956
1957 /* Do nothing if there is a same static route. */
1958 for (si = rn->info; si; si = si->next)
1959 {
1960 if (distance == si->distance
1961 && type == si->type
1962 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
1963 && (! ifname || strcmp (ifname, si->ifname) == 0))
1964 {
1965 route_unlock_node (rn);
1966 return 0;
1967 }
1968 }
1969
1970 /* Make new static route structure. */
1971 si = XMALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
1972 memset (si, 0, sizeof (struct static_ipv6));
1973
1974 si->type = type;
1975 si->distance = distance;
1976
1977 switch (type)
1978 {
1979 case STATIC_IPV6_GATEWAY:
1980 si->ipv6 = *gate;
1981 break;
1982 case STATIC_IPV6_IFNAME:
1983 si->ifname = XSTRDUP (0, ifname);
1984 break;
1985 case STATIC_IPV6_GATEWAY_IFNAME:
1986 si->ipv6 = *gate;
1987 si->ifname = XSTRDUP (0, ifname);
1988 break;
1989 }
1990
1991 /* Add new static route information to the tree with sort by
1992 distance value and gateway address. */
1993 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
1994 {
1995 if (si->distance < cp->distance)
1996 break;
1997 if (si->distance > cp->distance)
1998 continue;
1999 }
2000
2001 /* Make linked list. */
2002 if (pp)
2003 pp->next = si;
2004 else
2005 rn->info = si;
2006 if (cp)
2007 cp->prev = si;
2008 si->prev = pp;
2009 si->next = cp;
2010
2011 /* Install into rib. */
2012 static_install_ipv6 (p, si);
2013
2014 return 1;
2015}
2016
2017/* Delete static route from static route configuration. */
2018int
2019static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
2020 char *ifname, u_char distance, u_int32_t vrf_id)
2021{
2022 struct route_node *rn;
2023 struct static_ipv6 *si;
2024 struct route_table *stable;
2025
2026 /* Lookup table. */
2027 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2028 if (! stable)
2029 return -1;
2030
2031 /* Lookup static route prefix. */
2032 rn = route_node_lookup (stable, p);
2033 if (! rn)
2034 return 0;
2035
2036 /* Find same static route is the tree */
2037 for (si = rn->info; si; si = si->next)
2038 if (distance == si->distance
2039 && type == si->type
2040 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2041 && (! ifname || strcmp (ifname, si->ifname) == 0))
2042 break;
2043
2044 /* Can't find static route. */
2045 if (! si)
2046 {
2047 route_unlock_node (rn);
2048 return 0;
2049 }
2050
2051 /* Install into rib. */
2052 static_uninstall_ipv6 (p, si);
2053
2054 /* Unlink static route from linked list. */
2055 if (si->prev)
2056 si->prev->next = si->next;
2057 else
2058 rn->info = si->next;
2059 if (si->next)
2060 si->next->prev = si->prev;
2061
2062 /* Free static route configuration. */
2063 XFREE (MTYPE_STATIC_IPV6, si);
2064
2065 return 1;
2066}
2067#endif /* HAVE_IPV6 */
2068
2069/* RIB update function. */
2070void
2071rib_update ()
2072{
2073 struct route_node *rn;
2074 struct route_table *table;
2075
2076 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2077 if (table)
2078 for (rn = route_top (table); rn; rn = route_next (rn))
2079 rib_process (rn, NULL);
2080
2081 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2082 if (table)
2083 for (rn = route_top (table); rn; rn = route_next (rn))
2084 rib_process (rn, NULL);
2085}
2086
2087/* Interface goes up. */
2088void
2089rib_if_up (struct interface *ifp)
2090{
2091 rib_update ();
2092}
2093
2094/* Interface goes down. */
2095void
2096rib_if_down (struct interface *ifp)
2097{
2098 rib_update ();
2099}
2100
2101/* Remove all routes which comes from non main table. */
2102void
2103rib_weed_table (struct route_table *table)
2104{
2105 struct route_node *rn;
2106 struct rib *rib;
2107 struct rib *next;
2108
2109 if (table)
2110 for (rn = route_top (table); rn; rn = route_next (rn))
2111 for (rib = rn->info; rib; rib = next)
2112 {
2113 next = rib->next;
2114
2115 if (rib->table != rtm_table_default &&
2116 rib->table != RT_TABLE_MAIN)
2117 {
2118 rib_delnode (rn, rib);
2119 newrib_free (rib);
2120 route_unlock_node (rn);
2121 }
2122 }
2123}
2124
2125/* Delete all routes from non main table. */
2126void
2127rib_weed_tables ()
2128{
2129 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2130 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2131}
2132
2133/* Delete self installed routes after zebra is relaunched. */
2134void
2135rib_sweep_table (struct route_table *table)
2136{
2137 struct route_node *rn;
2138 struct rib *rib;
2139 struct rib *next;
2140 int ret = 0;
2141
2142 if (table)
2143 for (rn = route_top (table); rn; rn = route_next (rn))
2144 for (rib = rn->info; rib; rib = next)
2145 {
2146 next = rib->next;
2147
2148 if (rib->type == ZEBRA_ROUTE_KERNEL &&
2149 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
2150 {
2151 ret = rib_uninstall_kernel (rn, rib);
2152 if (! ret)
2153 {
2154 rib_delnode (rn, rib);
2155 newrib_free (rib);
2156 route_unlock_node (rn);
2157 }
2158 }
2159 }
2160}
2161
2162/* Sweep all RIB tables. */
2163void
2164rib_sweep_route ()
2165{
2166 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2167 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2168}
2169
2170/* Close RIB and clean up kernel routes. */
2171void
2172rib_close_table (struct route_table *table)
2173{
2174 struct route_node *rn;
2175 struct rib *rib;
2176
2177 if (table)
2178 for (rn = route_top (table); rn; rn = route_next (rn))
2179 for (rib = rn->info; rib; rib = rib->next)
2180 if (! RIB_SYSTEM_ROUTE (rib)
2181 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2182 rib_uninstall_kernel (rn, rib);
2183}
2184
2185/* Close all RIB tables. */
2186void
2187rib_close ()
2188{
2189 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2190 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2191}
2192
2193/* Routing information base initialize. */
2194void
2195rib_init ()
2196{
2197 /* VRF initialization. */
2198 vrf_init ();
2199}