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