blob: fb983bdb1b4b4b18f7d3c24a1bc5c844daf73f68 [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"
paul4d38fdb2005-04-28 17:35:14 +000032#include "linklist.h"
33#include "thread.h"
34#include "workqueue.h"
paul718e3742002-12-13 20:15:29 +000035
36#include "zebra/rib.h"
37#include "zebra/rt.h"
38#include "zebra/zserv.h"
39#include "zebra/redistribute.h"
40#include "zebra/debug.h"
41
42/* Default rtm_table for all clients */
paulb21b19c2003-06-15 01:28:29 +000043extern struct zebra_t zebrad;
paul718e3742002-12-13 20:15:29 +000044
45/* Each route type's string and default distance value. */
46struct
47{
48 int key;
49 int distance;
50} route_info[] =
51{
52 {ZEBRA_ROUTE_SYSTEM, 0},
53 {ZEBRA_ROUTE_KERNEL, 0},
54 {ZEBRA_ROUTE_CONNECT, 0},
55 {ZEBRA_ROUTE_STATIC, 1},
56 {ZEBRA_ROUTE_RIP, 120},
57 {ZEBRA_ROUTE_RIPNG, 120},
58 {ZEBRA_ROUTE_OSPF, 110},
59 {ZEBRA_ROUTE_OSPF6, 110},
jardin9e867fe2003-12-23 08:56:18 +000060 {ZEBRA_ROUTE_ISIS, 115},
paul718e3742002-12-13 20:15:29 +000061 {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */}
62};
paul4d38fdb2005-04-28 17:35:14 +000063
64struct zebra_queue_node_t
65{
66 struct route_node *node;
67 struct rib *del;
68};
paul718e3742002-12-13 20:15:29 +000069
70/* Vector for routing table. */
71vector vrf_vector;
72
73/* Allocate new VRF. */
paula1ac18c2005-06-28 17:17:12 +000074static struct vrf *
hassofce954f2004-10-07 20:29:24 +000075vrf_alloc (const char *name)
paul718e3742002-12-13 20:15:29 +000076{
77 struct vrf *vrf;
78
79 vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
80
81 /* Put name. */
82 if (name)
83 vrf->name = XSTRDUP (MTYPE_VRF_NAME, name);
84
85 /* Allocate routing table and static table. */
86 vrf->table[AFI_IP][SAFI_UNICAST] = route_table_init ();
87 vrf->table[AFI_IP6][SAFI_UNICAST] = route_table_init ();
88 vrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
89 vrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
90
91 return vrf;
92}
93
94/* Free VRF. */
paula1ac18c2005-06-28 17:17:12 +000095static void
paul718e3742002-12-13 20:15:29 +000096vrf_free (struct vrf *vrf)
97{
98 if (vrf->name)
99 XFREE (MTYPE_VRF_NAME, vrf->name);
100 XFREE (MTYPE_VRF, vrf);
101}
102
103/* Lookup VRF by identifier. */
104struct vrf *
105vrf_lookup (u_int32_t id)
106{
107 return vector_lookup (vrf_vector, id);
108}
109
110/* Lookup VRF by name. */
paula1ac18c2005-06-28 17:17:12 +0000111static struct vrf *
paul718e3742002-12-13 20:15:29 +0000112vrf_lookup_by_name (char *name)
113{
hassofce954f2004-10-07 20:29:24 +0000114 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000115 struct vrf *vrf;
116
paul55468c82005-03-14 20:19:01 +0000117 for (i = 0; i < vector_active (vrf_vector); i++)
paul718e3742002-12-13 20:15:29 +0000118 if ((vrf = vector_slot (vrf_vector, i)) != NULL)
119 if (vrf->name && name && strcmp (vrf->name, name) == 0)
120 return vrf;
121 return NULL;
122}
123
124/* Initialize VRF. */
paula1ac18c2005-06-28 17:17:12 +0000125static void
126vrf_init (void)
paul718e3742002-12-13 20:15:29 +0000127{
128 struct vrf *default_table;
129
130 /* Allocate VRF vector. */
131 vrf_vector = vector_init (1);
132
133 /* Allocate default main table. */
134 default_table = vrf_alloc ("Default-IP-Routing-Table");
135
136 /* Default table index must be 0. */
137 vector_set_index (vrf_vector, 0, default_table);
138}
139
140/* Lookup route table. */
141struct route_table *
142vrf_table (afi_t afi, safi_t safi, u_int32_t id)
143{
144 struct vrf *vrf;
145
146 vrf = vrf_lookup (id);
147 if (! vrf)
148 return NULL;
149
150 return vrf->table[afi][safi];
151}
152
153/* Lookup static route table. */
154struct route_table *
155vrf_static_table (afi_t afi, safi_t safi, u_int32_t id)
156{
157 struct vrf *vrf;
158
159 vrf = vrf_lookup (id);
160 if (! vrf)
161 return NULL;
162
163 return vrf->stable[afi][safi];
164}
165
166/* Add nexthop to the end of the list. */
paula1ac18c2005-06-28 17:17:12 +0000167static void
paul718e3742002-12-13 20:15:29 +0000168nexthop_add (struct rib *rib, struct nexthop *nexthop)
169{
170 struct nexthop *last;
171
172 for (last = rib->nexthop; last && last->next; last = last->next)
173 ;
174 if (last)
175 last->next = nexthop;
176 else
177 rib->nexthop = nexthop;
178 nexthop->prev = last;
179
180 rib->nexthop_num++;
181}
182
183/* Delete specified nexthop from the list. */
paula1ac18c2005-06-28 17:17:12 +0000184static void
paul718e3742002-12-13 20:15:29 +0000185nexthop_delete (struct rib *rib, struct nexthop *nexthop)
186{
187 if (nexthop->next)
188 nexthop->next->prev = nexthop->prev;
189 if (nexthop->prev)
190 nexthop->prev->next = nexthop->next;
191 else
192 rib->nexthop = nexthop->next;
193 rib->nexthop_num--;
194}
195
196/* Free nexthop. */
paula1ac18c2005-06-28 17:17:12 +0000197static void
paul718e3742002-12-13 20:15:29 +0000198nexthop_free (struct nexthop *nexthop)
199{
paula4b70762003-05-16 17:19:48 +0000200 if (nexthop->ifname)
201 XFREE (0, nexthop->ifname);
paul718e3742002-12-13 20:15:29 +0000202 XFREE (MTYPE_NEXTHOP, nexthop);
203}
204
205struct nexthop *
206nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
207{
208 struct nexthop *nexthop;
209
210 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
211 memset (nexthop, 0, sizeof (struct nexthop));
212 nexthop->type = NEXTHOP_TYPE_IFINDEX;
213 nexthop->ifindex = ifindex;
214
215 nexthop_add (rib, nexthop);
216
217 return nexthop;
218}
219
220struct nexthop *
221nexthop_ifname_add (struct rib *rib, char *ifname)
222{
223 struct nexthop *nexthop;
224
225 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
226 memset (nexthop, 0, sizeof (struct nexthop));
227 nexthop->type = NEXTHOP_TYPE_IFNAME;
paula4b70762003-05-16 17:19:48 +0000228 nexthop->ifname = XSTRDUP (0, ifname);
paul718e3742002-12-13 20:15:29 +0000229
230 nexthop_add (rib, nexthop);
231
232 return nexthop;
233}
234
235struct nexthop *
236nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4)
237{
238 struct nexthop *nexthop;
239
240 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
241 memset (nexthop, 0, sizeof (struct nexthop));
242 nexthop->type = NEXTHOP_TYPE_IPV4;
243 nexthop->gate.ipv4 = *ipv4;
244
245 nexthop_add (rib, nexthop);
246
247 return nexthop;
248}
249
paula1ac18c2005-06-28 17:17:12 +0000250static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000251nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
252 unsigned int ifindex)
253{
254 struct nexthop *nexthop;
255
256 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
257 memset (nexthop, 0, sizeof (struct nexthop));
258 nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
259 nexthop->gate.ipv4 = *ipv4;
260 nexthop->ifindex = ifindex;
261
262 nexthop_add (rib, nexthop);
263
264 return nexthop;
265}
266
267#ifdef HAVE_IPV6
268struct nexthop *
269nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
270{
271 struct nexthop *nexthop;
272
273 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
274 memset (nexthop, 0, sizeof (struct nexthop));
275 nexthop->type = NEXTHOP_TYPE_IPV6;
276 nexthop->gate.ipv6 = *ipv6;
277
278 nexthop_add (rib, nexthop);
279
280 return nexthop;
281}
282
paula1ac18c2005-06-28 17:17:12 +0000283static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000284nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
285 char *ifname)
286{
287 struct nexthop *nexthop;
288
289 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
290 memset (nexthop, 0, sizeof (struct nexthop));
291 nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
292 nexthop->gate.ipv6 = *ipv6;
293 nexthop->ifname = XSTRDUP (0, ifname);
294
295 nexthop_add (rib, nexthop);
296
297 return nexthop;
298}
299
paula1ac18c2005-06-28 17:17:12 +0000300static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000301nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
302 unsigned int ifindex)
303{
304 struct nexthop *nexthop;
305
306 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
307 memset (nexthop, 0, sizeof (struct nexthop));
308 nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
309 nexthop->gate.ipv6 = *ipv6;
310 nexthop->ifindex = ifindex;
311
312 nexthop_add (rib, nexthop);
313
314 return nexthop;
315}
316#endif /* HAVE_IPV6 */
317
paul595db7f2003-05-25 21:35:06 +0000318struct nexthop *
319nexthop_blackhole_add (struct rib *rib)
320{
321 struct nexthop *nexthop;
322
323 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
324 memset (nexthop, 0, sizeof (struct nexthop));
325 nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
326 SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
327
328 nexthop_add (rib, nexthop);
329
330 return nexthop;
331}
332
paul718e3742002-12-13 20:15:29 +0000333/* If force flag is not set, do not modify falgs at all for uninstall
334 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000335static int
paul718e3742002-12-13 20:15:29 +0000336nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
337 struct route_node *top)
338{
339 struct prefix_ipv4 p;
340 struct route_table *table;
341 struct route_node *rn;
342 struct rib *match;
343 struct nexthop *newhop;
344
345 if (nexthop->type == NEXTHOP_TYPE_IPV4)
346 nexthop->ifindex = 0;
347
348 if (set)
349 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
350
351 /* Make lookup prefix. */
352 memset (&p, 0, sizeof (struct prefix_ipv4));
353 p.family = AF_INET;
354 p.prefixlen = IPV4_MAX_PREFIXLEN;
355 p.prefix = nexthop->gate.ipv4;
356
357 /* Lookup table. */
358 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
359 if (! table)
360 return 0;
361
362 rn = route_node_match (table, (struct prefix *) &p);
363 while (rn)
364 {
365 route_unlock_node (rn);
366
367 /* If lookup self prefix return immidiately. */
368 if (rn == top)
369 return 0;
370
371 /* Pick up selected route. */
372 for (match = rn->info; match; match = match->next)
373 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
374 break;
375
376 /* If there is no selected route or matched route is EGP, go up
377 tree. */
378 if (! match
379 || match->type == ZEBRA_ROUTE_BGP)
380 {
381 do {
382 rn = rn->parent;
383 } while (rn && rn->info == NULL);
384 if (rn)
385 route_lock_node (rn);
386 }
387 else
388 {
389 if (match->type == ZEBRA_ROUTE_CONNECT)
390 {
391 /* Directly point connected route. */
392 newhop = match->nexthop;
393 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
394 nexthop->ifindex = newhop->ifindex;
395
396 return 1;
397 }
398 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
399 {
400 for (newhop = match->nexthop; newhop; newhop = newhop->next)
401 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
402 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
403 {
404 if (set)
405 {
406 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
407 nexthop->rtype = newhop->type;
408 if (newhop->type == NEXTHOP_TYPE_IPV4 ||
409 newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
410 nexthop->rgate.ipv4 = newhop->gate.ipv4;
411 if (newhop->type == NEXTHOP_TYPE_IFINDEX
412 || newhop->type == NEXTHOP_TYPE_IFNAME
413 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
414 nexthop->rifindex = newhop->ifindex;
415 }
416 return 1;
417 }
418 return 0;
419 }
420 else
421 {
422 return 0;
423 }
424 }
425 }
426 return 0;
427}
428
429#ifdef HAVE_IPV6
430/* If force flag is not set, do not modify falgs at all for uninstall
431 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000432static int
paul718e3742002-12-13 20:15:29 +0000433nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
434 struct route_node *top)
435{
436 struct prefix_ipv6 p;
437 struct route_table *table;
438 struct route_node *rn;
439 struct rib *match;
440 struct nexthop *newhop;
441
442 if (nexthop->type == NEXTHOP_TYPE_IPV6)
443 nexthop->ifindex = 0;
444
445 if (set)
446 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
447
448 /* Make lookup prefix. */
449 memset (&p, 0, sizeof (struct prefix_ipv6));
450 p.family = AF_INET6;
451 p.prefixlen = IPV6_MAX_PREFIXLEN;
452 p.prefix = nexthop->gate.ipv6;
453
454 /* Lookup table. */
455 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
456 if (! table)
457 return 0;
458
459 rn = route_node_match (table, (struct prefix *) &p);
460 while (rn)
461 {
462 route_unlock_node (rn);
463
464 /* If lookup self prefix return immidiately. */
465 if (rn == top)
466 return 0;
467
468 /* Pick up selected route. */
469 for (match = rn->info; match; match = match->next)
470 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
471 break;
472
473 /* If there is no selected route or matched route is EGP, go up
474 tree. */
475 if (! match
476 || match->type == ZEBRA_ROUTE_BGP)
477 {
478 do {
479 rn = rn->parent;
480 } while (rn && rn->info == NULL);
481 if (rn)
482 route_lock_node (rn);
483 }
484 else
485 {
486 if (match->type == ZEBRA_ROUTE_CONNECT)
487 {
488 /* Directly point connected route. */
489 newhop = match->nexthop;
490
491 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
492 nexthop->ifindex = newhop->ifindex;
493
494 return 1;
495 }
496 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
497 {
498 for (newhop = match->nexthop; newhop; newhop = newhop->next)
499 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
500 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
501 {
502 if (set)
503 {
504 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
505 nexthop->rtype = newhop->type;
506 if (newhop->type == NEXTHOP_TYPE_IPV6
507 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
508 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
509 nexthop->rgate.ipv6 = newhop->gate.ipv6;
510 if (newhop->type == NEXTHOP_TYPE_IFINDEX
511 || newhop->type == NEXTHOP_TYPE_IFNAME
512 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
513 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
514 nexthop->rifindex = newhop->ifindex;
515 }
516 return 1;
517 }
518 return 0;
519 }
520 else
521 {
522 return 0;
523 }
524 }
525 }
526 return 0;
527}
528#endif /* HAVE_IPV6 */
529
530struct rib *
531rib_match_ipv4 (struct in_addr addr)
532{
533 struct prefix_ipv4 p;
534 struct route_table *table;
535 struct route_node *rn;
536 struct rib *match;
537 struct nexthop *newhop;
538
539 /* Lookup table. */
540 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
541 if (! table)
542 return 0;
543
544 memset (&p, 0, sizeof (struct prefix_ipv4));
545 p.family = AF_INET;
546 p.prefixlen = IPV4_MAX_PREFIXLEN;
547 p.prefix = addr;
548
549 rn = route_node_match (table, (struct prefix *) &p);
550
551 while (rn)
552 {
553 route_unlock_node (rn);
554
555 /* Pick up selected route. */
556 for (match = rn->info; match; match = match->next)
557 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
558 break;
559
560 /* If there is no selected route or matched route is EGP, go up
561 tree. */
562 if (! match
563 || match->type == ZEBRA_ROUTE_BGP)
564 {
565 do {
566 rn = rn->parent;
567 } while (rn && rn->info == NULL);
568 if (rn)
569 route_lock_node (rn);
570 }
571 else
572 {
573 if (match->type == ZEBRA_ROUTE_CONNECT)
574 /* Directly point connected route. */
575 return match;
576 else
577 {
578 for (newhop = match->nexthop; newhop; newhop = newhop->next)
579 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
580 return match;
581 return NULL;
582 }
583 }
584 }
585 return NULL;
586}
587
588struct rib *
589rib_lookup_ipv4 (struct prefix_ipv4 *p)
590{
591 struct route_table *table;
592 struct route_node *rn;
593 struct rib *match;
594 struct nexthop *nexthop;
595
596 /* Lookup table. */
597 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
598 if (! table)
599 return 0;
600
601 rn = route_node_lookup (table, (struct prefix *) p);
602
603 /* No route for this prefix. */
604 if (! rn)
605 return NULL;
606
607 /* Unlock node. */
608 route_unlock_node (rn);
609
610 /* Pick up selected route. */
611 for (match = rn->info; match; match = match->next)
612 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
613 break;
614
615 if (! match || match->type == ZEBRA_ROUTE_BGP)
616 return NULL;
617
618 if (match->type == ZEBRA_ROUTE_CONNECT)
619 return match;
620
621 for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
622 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
623 return match;
624
625 return NULL;
626}
627
628#ifdef HAVE_IPV6
629struct rib *
630rib_match_ipv6 (struct in6_addr *addr)
631{
632 struct prefix_ipv6 p;
633 struct route_table *table;
634 struct route_node *rn;
635 struct rib *match;
636 struct nexthop *newhop;
637
638 /* Lookup table. */
639 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
640 if (! table)
641 return 0;
642
643 memset (&p, 0, sizeof (struct prefix_ipv6));
644 p.family = AF_INET6;
645 p.prefixlen = IPV6_MAX_PREFIXLEN;
646 IPV6_ADDR_COPY (&p.prefix, addr);
647
648 rn = route_node_match (table, (struct prefix *) &p);
649
650 while (rn)
651 {
652 route_unlock_node (rn);
653
654 /* Pick up selected route. */
655 for (match = rn->info; match; match = match->next)
656 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
657 break;
658
659 /* If there is no selected route or matched route is EGP, go up
660 tree. */
661 if (! match
662 || match->type == ZEBRA_ROUTE_BGP)
663 {
664 do {
665 rn = rn->parent;
666 } while (rn && rn->info == NULL);
667 if (rn)
668 route_lock_node (rn);
669 }
670 else
671 {
672 if (match->type == ZEBRA_ROUTE_CONNECT)
673 /* Directly point connected route. */
674 return match;
675 else
676 {
677 for (newhop = match->nexthop; newhop; newhop = newhop->next)
678 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
679 return match;
680 return NULL;
681 }
682 }
683 }
684 return NULL;
685}
686#endif /* HAVE_IPV6 */
687
paula1ac18c2005-06-28 17:17:12 +0000688static int
paul718e3742002-12-13 20:15:29 +0000689nexthop_active_check (struct route_node *rn, struct rib *rib,
690 struct nexthop *nexthop, int set)
691{
692 struct interface *ifp;
693
694 switch (nexthop->type)
695 {
696 case NEXTHOP_TYPE_IFINDEX:
697 ifp = if_lookup_by_index (nexthop->ifindex);
698 if (ifp && if_is_up (ifp))
699 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
700 else
701 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
702 break;
703 case NEXTHOP_TYPE_IFNAME:
704 case NEXTHOP_TYPE_IPV6_IFNAME:
705 ifp = if_lookup_by_name (nexthop->ifname);
706 if (ifp && if_is_up (ifp))
707 {
708 if (set)
709 nexthop->ifindex = ifp->ifindex;
710 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
711 }
712 else
713 {
714 if (set)
715 nexthop->ifindex = 0;
716 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
717 }
718 break;
719 case NEXTHOP_TYPE_IPV4:
720 case NEXTHOP_TYPE_IPV4_IFINDEX:
721 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
722 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
723 else
724 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
725 break;
726#ifdef HAVE_IPV6
727 case NEXTHOP_TYPE_IPV6:
728 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
729 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
730 else
731 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
732 break;
733 case NEXTHOP_TYPE_IPV6_IFINDEX:
734 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
735 {
736 ifp = if_lookup_by_index (nexthop->ifindex);
737 if (ifp && if_is_up (ifp))
738 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
739 else
740 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
741 }
742 else
743 {
744 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
745 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
746 else
747 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
748 }
749 break;
750#endif /* HAVE_IPV6 */
paul595db7f2003-05-25 21:35:06 +0000751 case NEXTHOP_TYPE_BLACKHOLE:
752 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
753 break;
paul718e3742002-12-13 20:15:29 +0000754 default:
755 break;
756 }
757 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
758}
759
paula1ac18c2005-06-28 17:17:12 +0000760static int
paul718e3742002-12-13 20:15:29 +0000761nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
762{
763 struct nexthop *nexthop;
764 int active;
765
766 rib->nexthop_active_num = 0;
767 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
768
769 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
770 {
771 active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
paul6baeb982003-10-28 03:47:15 +0000772
773 nexthop_active_check (rn, rib, nexthop, set);
774 if ((MULTIPATH_NUM == 0 || rib->nexthop_active_num < MULTIPATH_NUM)
775 && active != CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
776 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
777
778 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
779 rib->nexthop_active_num++;
paul718e3742002-12-13 20:15:29 +0000780 }
781 return rib->nexthop_active_num;
782}
paul6baeb982003-10-28 03:47:15 +0000783
paul718e3742002-12-13 20:15:29 +0000784
785#define RIB_SYSTEM_ROUTE(R) \
786 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
787
paul4d38fdb2005-04-28 17:35:14 +0000788static struct rib *
789rib_lock (struct rib *rib)
790{
791 assert (rib->lock >= 0);
792
793 rib->lock++;
794 return rib;
795}
796
797static struct rib *
798rib_unlock (struct rib *rib)
paul718e3742002-12-13 20:15:29 +0000799{
800 struct nexthop *nexthop;
801 struct nexthop *next;
paul4d38fdb2005-04-28 17:35:14 +0000802
803 assert (rib->lock > 0);
804 rib->lock--;
paul718e3742002-12-13 20:15:29 +0000805
paul4d38fdb2005-04-28 17:35:14 +0000806 if (rib->lock == 0)
paul718e3742002-12-13 20:15:29 +0000807 {
paul4d38fdb2005-04-28 17:35:14 +0000808 for (nexthop = rib->nexthop; nexthop; nexthop = next)
809 {
810 next = nexthop->next;
811 nexthop_free (nexthop);
812 }
813 XFREE (MTYPE_RIB, rib);
814 return NULL;
paul718e3742002-12-13 20:15:29 +0000815 }
paul4d38fdb2005-04-28 17:35:14 +0000816 return rib;
paul718e3742002-12-13 20:15:29 +0000817}
818
paula1ac18c2005-06-28 17:17:12 +0000819static void
paul718e3742002-12-13 20:15:29 +0000820rib_install_kernel (struct route_node *rn, struct rib *rib)
821{
822 int ret = 0;
823 struct nexthop *nexthop;
824
825 switch (PREFIX_FAMILY (&rn->p))
826 {
827 case AF_INET:
828 ret = kernel_add_ipv4 (&rn->p, rib);
829 break;
830#ifdef HAVE_IPV6
831 case AF_INET6:
832 ret = kernel_add_ipv6 (&rn->p, rib);
833 break;
834#endif /* HAVE_IPV6 */
835 }
836
837 if (ret < 0)
838 {
839 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
840 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
841 }
842}
843
844/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +0000845static int
paul718e3742002-12-13 20:15:29 +0000846rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
847{
848 int ret = 0;
849 struct nexthop *nexthop;
850
851 switch (PREFIX_FAMILY (&rn->p))
852 {
853 case AF_INET:
854 ret = kernel_delete_ipv4 (&rn->p, rib);
855 break;
856#ifdef HAVE_IPV6
857 case AF_INET6:
858 ret = kernel_delete_ipv6 (&rn->p, rib);
859 break;
860#endif /* HAVE_IPV6 */
861 }
862
863 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
864 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
865
866 return ret;
867}
868
869/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +0000870static void
paul718e3742002-12-13 20:15:29 +0000871rib_uninstall (struct route_node *rn, struct rib *rib)
872{
873 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
874 {
875 redistribute_delete (&rn->p, rib);
876 if (! RIB_SYSTEM_ROUTE (rib))
877 rib_uninstall_kernel (rn, rib);
878 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
879 }
880}
881
882/* Core function for processing routing information base. */
paula1ac18c2005-06-28 17:17:12 +0000883static wq_item_status
paul0fb58d52005-11-14 14:31:49 +0000884rib_process (struct work_queue *wq, void *data)
paul718e3742002-12-13 20:15:29 +0000885{
paul0fb58d52005-11-14 14:31:49 +0000886 struct zebra_queue_node_t *qnode = data;
paul718e3742002-12-13 20:15:29 +0000887 struct rib *rib;
888 struct rib *next;
889 struct rib *fib = NULL;
890 struct rib *select = NULL;
paul4d38fdb2005-04-28 17:35:14 +0000891 struct rib *del = qnode->del;
892 struct route_node *rn = qnode->node;
pauld753e9e2003-01-22 19:45:50 +0000893 int installed = 0;
894 struct nexthop *nexthop = NULL;
paul4d38fdb2005-04-28 17:35:14 +0000895
896 assert (rn);
897
898 /* possibly should lock and unlock rib on each iteration. however, for
899 * now, we assume called functions are synchronous and dont delete RIBs
900 * (as the work-queue deconstructor for this function is supposed to be
901 * the canonical 'delete' path for RIBs). Further if called functions
902 * below were to made asynchronous they should themselves acquire any
903 * locks/refcounts as needed and not depend on this caller to do it for
904 * them
905 */
paul718e3742002-12-13 20:15:29 +0000906 for (rib = rn->info; rib; rib = next)
907 {
908 next = rib->next;
pauld753e9e2003-01-22 19:45:50 +0000909
paul718e3742002-12-13 20:15:29 +0000910 /* Currently installed rib. */
911 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
paul7021c422003-07-15 12:52:22 +0000912 fib = rib;
paul4d38fdb2005-04-28 17:35:14 +0000913
paul718e3742002-12-13 20:15:29 +0000914 /* Skip unreachable nexthop. */
915 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +0000916 continue;
paul718e3742002-12-13 20:15:29 +0000917
918 /* Infinit distance. */
919 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +0000920 continue;
paul718e3742002-12-13 20:15:29 +0000921
922 /* Newly selected rib. */
923 if (! select || rib->distance < select->distance
paul7021c422003-07-15 12:52:22 +0000924 || rib->type == ZEBRA_ROUTE_CONNECT)
925 select = rib;
paul718e3742002-12-13 20:15:29 +0000926 }
paul4d38fdb2005-04-28 17:35:14 +0000927
paul718e3742002-12-13 20:15:29 +0000928 /* Deleted route check. */
929 if (del && CHECK_FLAG (del->flags, ZEBRA_FLAG_SELECTED))
930 fib = del;
paul4d38fdb2005-04-28 17:35:14 +0000931
932 /* We possibly should lock fib and select here However, all functions
933 * below are 'inline' and not asynchronous And if any were to be
934 * converted, they should manage references themselves really.. See
935 * previous comment above.
936 */
937
paul718e3742002-12-13 20:15:29 +0000938 /* Same route is selected. */
939 if (select && select == fib)
940 {
941 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +0000942 {
943 redistribute_delete (&rn->p, select);
944 if (! RIB_SYSTEM_ROUTE (select))
945 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +0000946
paul4d38fdb2005-04-28 17:35:14 +0000947 /* Set real nexthop. */
948 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +0000949
paul4d38fdb2005-04-28 17:35:14 +0000950 if (! RIB_SYSTEM_ROUTE (select))
951 rib_install_kernel (rn, select);
952 redistribute_add (&rn->p, select);
953 }
pauld753e9e2003-01-22 19:45:50 +0000954 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +0000955 {
956 /* Housekeeping code to deal with
957 race conditions in kernel with linux
958 netlink reporting interface up before IPv4 or IPv6 protocol
959 is ready to add routes.
960 This makes sure the routes are IN the kernel.
961 */
pauld753e9e2003-01-22 19:45:50 +0000962
paul4d38fdb2005-04-28 17:35:14 +0000963 for (nexthop = select->nexthop; nexthop; nexthop = nexthop->next)
964 {
965 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
966 installed = 1;
967 }
968 if (! installed)
969 rib_install_kernel (rn, select);
970 }
971 return WQ_SUCCESS;
paul718e3742002-12-13 20:15:29 +0000972 }
973
974 /* Uninstall old rib from forwarding table. */
975 if (fib)
976 {
977 redistribute_delete (&rn->p, fib);
978 if (! RIB_SYSTEM_ROUTE (fib))
979 rib_uninstall_kernel (rn, fib);
980 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
981
982 /* Set real nexthop. */
983 nexthop_active_update (rn, fib, 1);
984 }
985
986 /* Install new rib into forwarding table. */
987 if (select)
988 {
989 /* Set real nexthop. */
990 nexthop_active_update (rn, select, 1);
991
992 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +0000993 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +0000994 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
995 redistribute_add (&rn->p, select);
996 }
paul4d38fdb2005-04-28 17:35:14 +0000997
998 return WQ_SUCCESS;
999
1000}
1001
1002/* Add work queue item to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001003static void
paul4d38fdb2005-04-28 17:35:14 +00001004rib_queue_add_qnode (struct zebra_t *zebra, struct zebra_queue_node_t *qnode)
1005{
1006 route_lock_node (qnode->node);
1007
1008 if (IS_ZEBRA_DEBUG_EVENT)
1009 zlog_info ("rib_queue_add_qnode: work queue added");
1010
1011 assert (zebra && qnode && qnode->node);
1012
1013 if (qnode->del)
1014 rib_lock (qnode->del);
1015
1016 if (zebra->ribq == NULL)
1017 {
1018 zlog_err ("rib_queue_add_qnode: ribq work_queue does not exist!");
1019 route_unlock_node (qnode->node);
1020 return;
1021 }
1022
1023 work_queue_add (zebra->ribq, qnode);
1024
1025 return;
1026}
1027
1028/* Add route node and rib to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001029static void
paul4d38fdb2005-04-28 17:35:14 +00001030rib_queue_add (struct zebra_t *zebra, struct route_node *rn, struct rib *del)
1031{
1032 struct zebra_queue_node_t *qnode;
1033
1034 assert (zebra && rn);
1035
1036 qnode = (struct zebra_queue_node_t *)
1037 XCALLOC (MTYPE_RIB_QUEUE, sizeof (struct zebra_queue_node_t));
1038
1039 if (qnode == NULL)
1040 {
1041 zlog_err ("rib_queue_add: failed to allocate queue node memory, %s",
1042 strerror (errno));
1043 return;
1044 }
1045
1046 qnode->node = rn;
1047 qnode->del = del;
1048
1049 rib_queue_add_qnode (zebra, qnode);
1050
1051 return;
1052}
1053
1054/* free zebra_queue_node_t */
paula1ac18c2005-06-28 17:17:12 +00001055static void
paul0fb58d52005-11-14 14:31:49 +00001056rib_queue_qnode_del (struct work_queue *wq, void *data)
paul4d38fdb2005-04-28 17:35:14 +00001057{
paul0fb58d52005-11-14 14:31:49 +00001058 struct zebra_queue_node_t *qnode = data;
paul4d38fdb2005-04-28 17:35:14 +00001059 route_unlock_node (qnode->node);
1060
1061 if (qnode->del)
1062 rib_unlock (qnode->del);
1063
1064 XFREE (MTYPE_RIB_QUEUE, qnode);
1065}
1066
1067/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001068static void
paul4d38fdb2005-04-28 17:35:14 +00001069rib_queue_init (struct zebra_t *zebra)
1070{
1071 assert (zebra);
1072
1073 if (! (zebra->ribq = work_queue_new (zebra->master,
1074 "zebra_rib_work_queue")))
1075 {
1076 zlog_err ("rib_queue_init: could not initialise work queue!");
1077 return;
1078 }
1079
1080 /* fill in the work queue spec */
paul0fb58d52005-11-14 14:31:49 +00001081 zebra->ribq->spec.workfunc = &rib_process;
paul4d38fdb2005-04-28 17:35:14 +00001082 zebra->ribq->spec.errorfunc = NULL;
paul0fb58d52005-11-14 14:31:49 +00001083 zebra->ribq->spec.del_item_data = &rib_queue_qnode_del;
paul4d38fdb2005-04-28 17:35:14 +00001084 /* XXX: TODO: These should be runtime configurable via vty */
1085 zebra->ribq->spec.max_retries = 3;
paul4d38fdb2005-04-28 17:35:14 +00001086
1087 return;
paul718e3742002-12-13 20:15:29 +00001088}
1089
1090/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001091static void
paul718e3742002-12-13 20:15:29 +00001092rib_addnode (struct route_node *rn, struct rib *rib)
1093{
1094 struct rib *head;
paul4d38fdb2005-04-28 17:35:14 +00001095
1096 assert (rib && rn);
1097
1098 rib_lock (rib);
1099 route_lock_node (rn);
1100
paul718e3742002-12-13 20:15:29 +00001101 head = rn->info;
1102 if (head)
1103 head->prev = rib;
1104 rib->next = head;
1105 rn->info = rib;
1106}
1107
paula1ac18c2005-06-28 17:17:12 +00001108static void
paul718e3742002-12-13 20:15:29 +00001109rib_delnode (struct route_node *rn, struct rib *rib)
1110{
paul4d38fdb2005-04-28 17:35:14 +00001111 assert (rn && rib);
1112
paul718e3742002-12-13 20:15:29 +00001113 if (rib->next)
1114 rib->next->prev = rib->prev;
1115 if (rib->prev)
1116 rib->prev->next = rib->next;
1117 else
1118 rn->info = rib->next;
paul4d38fdb2005-04-28 17:35:14 +00001119
1120 rib_unlock (rib);
1121 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001122}
1123
1124int
1125rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
1126 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
1127 u_int32_t metric, u_char distance)
1128{
1129 struct rib *rib;
1130 struct rib *same = NULL;
1131 struct route_table *table;
1132 struct route_node *rn;
1133 struct nexthop *nexthop;
1134
1135 /* Lookup table. */
1136 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1137 if (! table)
1138 return 0;
1139
1140 /* Make it sure prefixlen is applied to the prefix. */
1141 apply_mask_ipv4 (p);
1142
1143 /* Set default distance by route type. */
1144 if (distance == 0)
1145 {
1146 distance = route_info[type].distance;
1147
1148 /* iBGP distance is 200. */
1149 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1150 distance = 200;
1151 }
1152
1153 /* Lookup route node.*/
1154 rn = route_node_get (table, (struct prefix *) p);
1155
1156 /* If same type of route are installed, treat it as a implicit
1157 withdraw. */
1158 for (rib = rn->info; rib; rib = rib->next)
1159 {
hassoebf1ead2005-09-21 14:58:20 +00001160 if (rib->type != type)
1161 continue;
1162 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001163 {
1164 same = rib;
1165 break;
1166 }
hassoebf1ead2005-09-21 14:58:20 +00001167 /* Duplicate connected route comes in. */
1168 else if ((nexthop = rib->nexthop) &&
1169 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
1170 nexthop->ifindex == ifindex)
1171 {
1172 rib->refcnt++;
1173 return 0 ;
1174 }
paul718e3742002-12-13 20:15:29 +00001175 }
1176
1177 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001178 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001179 rib->type = type;
1180 rib->distance = distance;
1181 rib->flags = flags;
1182 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001183 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001184 rib->nexthop_num = 0;
1185 rib->uptime = time (NULL);
1186
1187 /* Nexthop settings. */
1188 if (gate)
1189 {
1190 if (ifindex)
1191 nexthop_ipv4_ifindex_add (rib, gate, ifindex);
1192 else
1193 nexthop_ipv4_add (rib, gate);
1194 }
1195 else
1196 nexthop_ifindex_add (rib, ifindex);
1197
1198 /* If this route is kernel route, set FIB flag to the route. */
1199 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1200 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1201 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1202
1203 /* Link new rib to node.*/
1204 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001205
paul718e3742002-12-13 20:15:29 +00001206 /* Process this route node. */
paul4d38fdb2005-04-28 17:35:14 +00001207 rib_queue_add (&zebrad, rn, same);
1208
paul718e3742002-12-13 20:15:29 +00001209 /* Free implicit route.*/
1210 if (same)
paul4d38fdb2005-04-28 17:35:14 +00001211 rib_delnode (rn, same);
1212
1213 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001214 return 0;
1215}
1216
1217int
1218rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib)
1219{
1220 struct route_table *table;
1221 struct route_node *rn;
1222 struct rib *same;
1223 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00001224
paul718e3742002-12-13 20:15:29 +00001225 /* Lookup table. */
1226 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1227 if (! table)
1228 return 0;
paul718e3742002-12-13 20:15:29 +00001229 /* Make it sure prefixlen is applied to the prefix. */
1230 apply_mask_ipv4 (p);
1231
1232 /* Set default distance by route type. */
1233 if (rib->distance == 0)
1234 {
1235 rib->distance = route_info[rib->type].distance;
1236
1237 /* iBGP distance is 200. */
1238 if (rib->type == ZEBRA_ROUTE_BGP
1239 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1240 rib->distance = 200;
1241 }
1242
1243 /* Lookup route node.*/
1244 rn = route_node_get (table, (struct prefix *) p);
1245
1246 /* If same type of route are installed, treat it as a implicit
1247 withdraw. */
1248 for (same = rn->info; same; same = same->next)
1249 {
1250 if (same->type == rib->type && same->table == rib->table
1251 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001252 break;
paul718e3742002-12-13 20:15:29 +00001253 }
paul4d38fdb2005-04-28 17:35:14 +00001254
paul718e3742002-12-13 20:15:29 +00001255 /* If this route is kernel route, set FIB flag to the route. */
1256 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
1257 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1258 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1259
1260 /* Link new rib to node.*/
1261 rib_addnode (rn, rib);
1262
1263 /* Process this route node. */
paul4d38fdb2005-04-28 17:35:14 +00001264 rib_queue_add (&zebrad, rn, same);
paul718e3742002-12-13 20:15:29 +00001265
1266 /* Free implicit route.*/
1267 if (same)
paul4d38fdb2005-04-28 17:35:14 +00001268 rib_delnode (rn, same);
1269
1270 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001271 return 0;
1272}
1273
hassoebf1ead2005-09-21 14:58:20 +00001274/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00001275int
1276rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
1277 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1278{
1279 struct route_table *table;
1280 struct route_node *rn;
1281 struct rib *rib;
1282 struct rib *fib = NULL;
1283 struct rib *same = NULL;
1284 struct nexthop *nexthop;
1285 char buf1[BUFSIZ];
1286 char buf2[BUFSIZ];
1287
1288 /* Lookup table. */
1289 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1290 if (! table)
1291 return 0;
1292
1293 /* Apply mask. */
1294 apply_mask_ipv4 (p);
1295
paul5ec90d22003-06-19 01:41:37 +00001296 if (IS_ZEBRA_DEBUG_KERNEL && gate)
ajsb6178002004-12-07 21:12:56 +00001297 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
paul5ec90d22003-06-19 01:41:37 +00001298 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1299 p->prefixlen,
1300 inet_ntoa (*gate),
1301 ifindex);
1302
paul718e3742002-12-13 20:15:29 +00001303 /* Lookup route node. */
1304 rn = route_node_lookup (table, (struct prefix *) p);
1305 if (! rn)
1306 {
1307 if (IS_ZEBRA_DEBUG_KERNEL)
1308 {
1309 if (gate)
ajsb6178002004-12-07 21:12:56 +00001310 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001311 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1312 p->prefixlen,
1313 inet_ntop (AF_INET, gate, buf2, BUFSIZ),
1314 ifindex);
1315 else
ajsb6178002004-12-07 21:12:56 +00001316 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001317 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1318 p->prefixlen,
1319 ifindex);
1320 }
1321 return ZEBRA_ERR_RTNOEXIST;
1322 }
1323
1324 /* Lookup same type route. */
1325 for (rib = rn->info; rib; rib = rib->next)
1326 {
1327 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1328 fib = rib;
1329
hassoebf1ead2005-09-21 14:58:20 +00001330 if (rib->type != type)
1331 continue;
1332 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
1333 nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex)
paul718e3742002-12-13 20:15:29 +00001334 {
hassoebf1ead2005-09-21 14:58:20 +00001335 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00001336 {
hassoebf1ead2005-09-21 14:58:20 +00001337 rib->refcnt--;
1338 route_unlock_node (rn);
1339 route_unlock_node (rn);
1340 return 0;
paul718e3742002-12-13 20:15:29 +00001341 }
hassoebf1ead2005-09-21 14:58:20 +00001342 same = rib;
1343 break;
paul718e3742002-12-13 20:15:29 +00001344 }
hassoebf1ead2005-09-21 14:58:20 +00001345 /* Make sure that the route found has the same gateway. */
1346 else if (gate == NULL ||
1347 ((nexthop = rib->nexthop) &&
1348 (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
1349 IPV4_ADDR_SAME (&nexthop->rgate.ipv4, gate))))
paul5ec90d22003-06-19 01:41:37 +00001350 {
hassoebf1ead2005-09-21 14:58:20 +00001351 same = rib;
1352 break;
paul718e3742002-12-13 20:15:29 +00001353 }
1354 }
1355
1356 /* If same type of route can't be found and this message is from
1357 kernel. */
1358 if (! same)
1359 {
1360 if (fib && type == ZEBRA_ROUTE_KERNEL)
1361 {
1362 /* Unset flags. */
1363 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1364 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1365
1366 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1367 }
1368 else
1369 {
1370 if (IS_ZEBRA_DEBUG_KERNEL)
1371 {
1372 if (gate)
ajsb6178002004-12-07 21:12:56 +00001373 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001374 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1375 p->prefixlen,
1376 inet_ntop (AF_INET, gate, buf2, BUFSIZ),
1377 ifindex,
1378 type);
1379 else
ajsb6178002004-12-07 21:12:56 +00001380 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001381 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1382 p->prefixlen,
1383 ifindex,
1384 type);
1385 }
1386 route_unlock_node (rn);
1387 return ZEBRA_ERR_RTNOEXIST;
1388 }
1389 }
paul4d38fdb2005-04-28 17:35:14 +00001390
1391 /* Process changes. */
1392 rib_queue_add (&zebrad, rn, same);
paul718e3742002-12-13 20:15:29 +00001393
1394 if (same)
1395 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00001396
paul718e3742002-12-13 20:15:29 +00001397 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001398 return 0;
1399}
1400
1401/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00001402static void
paul718e3742002-12-13 20:15:29 +00001403static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
1404{
1405 struct rib *rib;
1406 struct route_node *rn;
1407 struct route_table *table;
1408
1409 /* Lookup table. */
1410 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1411 if (! table)
1412 return;
1413
1414 /* Lookup existing route */
1415 rn = route_node_get (table, p);
1416 for (rib = rn->info; rib; rib = rib->next)
1417 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1418 break;
1419
1420 if (rib)
1421 {
1422 /* Same distance static route is there. Update it with new
1423 nexthop. */
paul718e3742002-12-13 20:15:29 +00001424 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001425 switch (si->type)
paul7021c422003-07-15 12:52:22 +00001426 {
1427 case STATIC_IPV4_GATEWAY:
1428 nexthop_ipv4_add (rib, &si->gate.ipv4);
1429 break;
1430 case STATIC_IPV4_IFNAME:
1431 nexthop_ifname_add (rib, si->gate.ifname);
1432 break;
1433 case STATIC_IPV4_BLACKHOLE:
1434 nexthop_blackhole_add (rib);
1435 break;
paul4d38fdb2005-04-28 17:35:14 +00001436 }
1437 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00001438 }
1439 else
1440 {
1441 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00001442 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
1443
paul718e3742002-12-13 20:15:29 +00001444 rib->type = ZEBRA_ROUTE_STATIC;
1445 rib->distance = si->distance;
1446 rib->metric = 0;
1447 rib->nexthop_num = 0;
1448
1449 switch (si->type)
paul7021c422003-07-15 12:52:22 +00001450 {
1451 case STATIC_IPV4_GATEWAY:
1452 nexthop_ipv4_add (rib, &si->gate.ipv4);
1453 break;
1454 case STATIC_IPV4_IFNAME:
1455 nexthop_ifname_add (rib, si->gate.ifname);
1456 break;
1457 case STATIC_IPV4_BLACKHOLE:
1458 nexthop_blackhole_add (rib);
1459 break;
1460 }
paul718e3742002-12-13 20:15:29 +00001461
hasso81dfcaa2003-05-25 19:21:25 +00001462 /* Save the flags of this static routes (reject, blackhole) */
1463 rib->flags = si->flags;
1464
paul718e3742002-12-13 20:15:29 +00001465 /* Link this rib to the tree. */
1466 rib_addnode (rn, rib);
1467
1468 /* Process this prefix. */
paul4d38fdb2005-04-28 17:35:14 +00001469 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00001470 }
1471}
1472
paula1ac18c2005-06-28 17:17:12 +00001473static int
paul718e3742002-12-13 20:15:29 +00001474static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
1475{
1476 if (nexthop->type == NEXTHOP_TYPE_IPV4
1477 && si->type == STATIC_IPV4_GATEWAY
1478 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
1479 return 1;
1480 if (nexthop->type == NEXTHOP_TYPE_IFNAME
1481 && si->type == STATIC_IPV4_IFNAME
1482 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
1483 return 1;
paul595db7f2003-05-25 21:35:06 +00001484 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
1485 && si->type == STATIC_IPV4_BLACKHOLE)
1486 return 1;
paul718e3742002-12-13 20:15:29 +00001487 return 0;;
1488}
1489
1490/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00001491static void
paul718e3742002-12-13 20:15:29 +00001492static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
1493{
1494 struct route_node *rn;
1495 struct rib *rib;
1496 struct nexthop *nexthop;
1497 struct route_table *table;
1498
1499 /* Lookup table. */
1500 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1501 if (! table)
1502 return;
paul4d38fdb2005-04-28 17:35:14 +00001503
paul718e3742002-12-13 20:15:29 +00001504 /* Lookup existing route with type and distance. */
1505 rn = route_node_lookup (table, p);
1506 if (! rn)
1507 return;
1508
1509 for (rib = rn->info; rib; rib = rib->next)
1510 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1511 break;
1512
1513 if (! rib)
1514 {
1515 route_unlock_node (rn);
1516 return;
1517 }
1518
1519 /* Lookup nexthop. */
1520 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1521 if (static_ipv4_nexthop_same (nexthop, si))
1522 break;
1523
1524 /* Can't find nexthop. */
1525 if (! nexthop)
1526 {
1527 route_unlock_node (rn);
1528 return;
1529 }
1530
1531 /* Check nexthop. */
1532 if (rib->nexthop_num == 1)
1533 {
paul4d38fdb2005-04-28 17:35:14 +00001534 rib_queue_add (&zebrad, rn, rib);
paul718e3742002-12-13 20:15:29 +00001535 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00001536 }
1537 else
1538 {
paul6baeb982003-10-28 03:47:15 +00001539 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1540 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00001541 nexthop_delete (rib, nexthop);
1542 nexthop_free (nexthop);
1543 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00001544 }
paul718e3742002-12-13 20:15:29 +00001545 /* Unlock node. */
1546 route_unlock_node (rn);
1547}
1548
1549/* Add static route into static route configuration. */
1550int
hasso39db97e2004-10-12 20:50:58 +00001551static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00001552 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001553{
1554 u_char type = 0;
1555 struct route_node *rn;
1556 struct static_ipv4 *si;
1557 struct static_ipv4 *pp;
1558 struct static_ipv4 *cp;
1559 struct static_ipv4 *update = NULL;
1560 struct route_table *stable;
1561
1562 /* Lookup table. */
1563 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
1564 if (! stable)
1565 return -1;
1566
1567 /* Lookup static route prefix. */
1568 rn = route_node_get (stable, p);
1569
1570 /* Make flags. */
1571 if (gate)
1572 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00001573 else if (ifname)
paul718e3742002-12-13 20:15:29 +00001574 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00001575 else
1576 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00001577
1578 /* Do nothing if there is a same static route. */
1579 for (si = rn->info; si; si = si->next)
1580 {
1581 if (type == si->type
1582 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
1583 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
1584 {
1585 if (distance == si->distance)
1586 {
1587 route_unlock_node (rn);
1588 return 0;
1589 }
1590 else
1591 update = si;
1592 }
1593 }
1594
1595 /* Distance chaged. */
1596 if (update)
1597 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
1598
1599 /* Make new static route structure. */
1600 si = XMALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
1601 memset (si, 0, sizeof (struct static_ipv4));
1602
1603 si->type = type;
1604 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00001605 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00001606
1607 if (gate)
1608 si->gate.ipv4 = *gate;
1609 if (ifname)
1610 si->gate.ifname = XSTRDUP (0, ifname);
1611
1612 /* Add new static route information to the tree with sort by
1613 distance value and gateway address. */
1614 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
1615 {
1616 if (si->distance < cp->distance)
1617 break;
1618 if (si->distance > cp->distance)
1619 continue;
1620 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
1621 {
1622 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
1623 break;
1624 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
1625 continue;
1626 }
1627 }
1628
1629 /* Make linked list. */
1630 if (pp)
1631 pp->next = si;
1632 else
1633 rn->info = si;
1634 if (cp)
1635 cp->prev = si;
1636 si->prev = pp;
1637 si->next = cp;
1638
1639 /* Install into rib. */
1640 static_install_ipv4 (p, si);
1641
1642 return 1;
1643}
1644
1645/* Delete static route from static route configuration. */
1646int
hasso39db97e2004-10-12 20:50:58 +00001647static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00001648 u_char distance, u_int32_t vrf_id)
1649{
1650 u_char type = 0;
1651 struct route_node *rn;
1652 struct static_ipv4 *si;
1653 struct route_table *stable;
1654
1655 /* Lookup table. */
1656 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
1657 if (! stable)
1658 return -1;
1659
1660 /* Lookup static route prefix. */
1661 rn = route_node_lookup (stable, p);
1662 if (! rn)
1663 return 0;
1664
1665 /* Make flags. */
1666 if (gate)
1667 type = STATIC_IPV4_GATEWAY;
1668 else if (ifname)
1669 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00001670 else
1671 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00001672
1673 /* Find same static route is the tree */
1674 for (si = rn->info; si; si = si->next)
1675 if (type == si->type
1676 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
1677 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
1678 break;
1679
1680 /* Can't find static route. */
1681 if (! si)
1682 {
1683 route_unlock_node (rn);
1684 return 0;
1685 }
1686
1687 /* Install into rib. */
1688 static_uninstall_ipv4 (p, si);
1689
1690 /* Unlink static route from linked list. */
1691 if (si->prev)
1692 si->prev->next = si->next;
1693 else
1694 rn->info = si->next;
1695 if (si->next)
1696 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00001697 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001698
1699 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00001700 if (ifname)
1701 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00001702 XFREE (MTYPE_STATIC_IPV4, si);
1703
paul143a3852003-09-29 20:06:13 +00001704 route_unlock_node (rn);
1705
paul718e3742002-12-13 20:15:29 +00001706 return 1;
1707}
1708
1709
1710#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00001711static int
paul718e3742002-12-13 20:15:29 +00001712rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
1713 struct in6_addr *gate, unsigned int ifindex, int table)
1714{
hasso726f9b22003-05-25 21:04:54 +00001715 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
1716#if defined (MUSICA) || defined (LINUX)
1717 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
1718 if (p->prefixlen == 96)
1719 return 0;
1720#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00001721 return 1;
hasso726f9b22003-05-25 21:04:54 +00001722 }
paul718e3742002-12-13 20:15:29 +00001723 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
1724 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
1725 {
1726 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
1727 return 1;
1728 }
1729 return 0;
1730}
1731
1732int
1733rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00001734 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
1735 u_int32_t metric, u_char distance)
paul718e3742002-12-13 20:15:29 +00001736{
1737 struct rib *rib;
1738 struct rib *same = NULL;
1739 struct route_table *table;
1740 struct route_node *rn;
1741 struct nexthop *nexthop;
1742
paul718e3742002-12-13 20:15:29 +00001743 /* Lookup table. */
1744 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1745 if (! table)
1746 return 0;
1747
1748 /* Make sure mask is applied. */
1749 apply_mask_ipv6 (p);
1750
1751 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00001752 if (!distance)
1753 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00001754
1755 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1756 distance = 200;
1757
1758 /* Filter bogus route. */
1759 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
1760 return 0;
1761
1762 /* Lookup route node.*/
1763 rn = route_node_get (table, (struct prefix *) p);
1764
1765 /* If same type of route are installed, treat it as a implicit
1766 withdraw. */
1767 for (rib = rn->info; rib; rib = rib->next)
1768 {
hassoebf1ead2005-09-21 14:58:20 +00001769 if (rib->type != type)
1770 continue;
1771 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00001772 {
1773 same = rib;
paul718e3742002-12-13 20:15:29 +00001774 break;
1775 }
hassoebf1ead2005-09-21 14:58:20 +00001776 else if ((nexthop = rib->nexthop) &&
1777 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
1778 nexthop->ifindex == ifindex)
1779 {
1780 rib->refcnt++;
1781 return 0;
1782 }
paul718e3742002-12-13 20:15:29 +00001783 }
1784
1785 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001786 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
1787
paul718e3742002-12-13 20:15:29 +00001788 rib->type = type;
1789 rib->distance = distance;
1790 rib->flags = flags;
1791 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001792 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001793 rib->nexthop_num = 0;
1794 rib->uptime = time (NULL);
1795
1796 /* Nexthop settings. */
1797 if (gate)
1798 {
1799 if (ifindex)
1800 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
1801 else
1802 nexthop_ipv6_add (rib, gate);
1803 }
1804 else
1805 nexthop_ifindex_add (rib, ifindex);
1806
1807 /* If this route is kernel route, set FIB flag to the route. */
1808 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1809 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1810 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1811
1812 /* Link new rib to node.*/
1813 rib_addnode (rn, rib);
1814
1815 /* Process this route node. */
paul4d38fdb2005-04-28 17:35:14 +00001816 rib_queue_add (&zebrad, rn, same);
1817
paul718e3742002-12-13 20:15:29 +00001818 /* Free implicit route.*/
1819 if (same)
paul4d38fdb2005-04-28 17:35:14 +00001820 rib_delnode (rn, same);
1821
1822 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001823 return 0;
1824}
1825
hassoebf1ead2005-09-21 14:58:20 +00001826/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00001827int
1828rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
1829 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1830{
1831 struct route_table *table;
1832 struct route_node *rn;
1833 struct rib *rib;
1834 struct rib *fib = NULL;
1835 struct rib *same = NULL;
1836 struct nexthop *nexthop;
1837 char buf1[BUFSIZ];
1838 char buf2[BUFSIZ];
1839
1840 /* Apply mask. */
1841 apply_mask_ipv6 (p);
1842
1843 /* Lookup table. */
1844 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1845 if (! table)
1846 return 0;
paul4d38fdb2005-04-28 17:35:14 +00001847
paul718e3742002-12-13 20:15:29 +00001848 /* Lookup route node. */
1849 rn = route_node_lookup (table, (struct prefix *) p);
1850 if (! rn)
1851 {
1852 if (IS_ZEBRA_DEBUG_KERNEL)
1853 {
1854 if (gate)
ajsb6178002004-12-07 21:12:56 +00001855 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001856 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1857 p->prefixlen,
1858 inet_ntop (AF_INET6, gate, buf2, BUFSIZ),
1859 ifindex);
1860 else
ajsb6178002004-12-07 21:12:56 +00001861 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001862 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1863 p->prefixlen,
1864 ifindex);
1865 }
1866 return ZEBRA_ERR_RTNOEXIST;
1867 }
1868
1869 /* Lookup same type route. */
1870 for (rib = rn->info; rib; rib = rib->next)
1871 {
1872 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1873 fib = rib;
1874
hassoebf1ead2005-09-21 14:58:20 +00001875 if (rib->type != type)
1876 continue;
1877 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
1878 nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex)
paul718e3742002-12-13 20:15:29 +00001879 {
hassoebf1ead2005-09-21 14:58:20 +00001880 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00001881 {
hassoebf1ead2005-09-21 14:58:20 +00001882 rib->refcnt--;
1883 route_unlock_node (rn);
1884 route_unlock_node (rn);
1885 return 0;
paul718e3742002-12-13 20:15:29 +00001886 }
hassoebf1ead2005-09-21 14:58:20 +00001887 same = rib;
1888 break;
paul718e3742002-12-13 20:15:29 +00001889 }
hassoebf1ead2005-09-21 14:58:20 +00001890 /* Make sure that the route found has the same gateway. */
1891 else if (gate == NULL ||
1892 ((nexthop = rib->nexthop) &&
1893 (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate) ||
1894 IPV6_ADDR_SAME (&nexthop->rgate.ipv6, gate))))
paul718e3742002-12-13 20:15:29 +00001895 {
hassoebf1ead2005-09-21 14:58:20 +00001896 same = rib;
1897 break;
paul718e3742002-12-13 20:15:29 +00001898 }
1899 }
1900
1901 /* If same type of route can't be found and this message is from
1902 kernel. */
1903 if (! same)
1904 {
1905 if (fib && type == ZEBRA_ROUTE_KERNEL)
1906 {
1907 /* Unset flags. */
1908 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1909 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1910
1911 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1912 }
1913 else
1914 {
1915 if (IS_ZEBRA_DEBUG_KERNEL)
1916 {
1917 if (gate)
ajsb6178002004-12-07 21:12:56 +00001918 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001919 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1920 p->prefixlen,
1921 inet_ntop (AF_INET6, gate, buf2, BUFSIZ),
1922 ifindex,
1923 type);
1924 else
ajsb6178002004-12-07 21:12:56 +00001925 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001926 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1927 p->prefixlen,
1928 ifindex,
1929 type);
1930 }
1931 route_unlock_node (rn);
1932 return ZEBRA_ERR_RTNOEXIST;
1933 }
1934 }
1935
paul4d38fdb2005-04-28 17:35:14 +00001936 /* Process changes. */
1937 rib_queue_add (&zebrad, rn, same);
1938
paul718e3742002-12-13 20:15:29 +00001939 if (same)
1940 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00001941
paul718e3742002-12-13 20:15:29 +00001942 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001943 return 0;
1944}
1945
1946/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00001947static void
paul718e3742002-12-13 20:15:29 +00001948static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
1949{
1950 struct rib *rib;
1951 struct route_table *table;
1952 struct route_node *rn;
1953
1954 /* Lookup table. */
1955 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1956 if (! table)
1957 return;
1958
1959 /* Lookup existing route */
1960 rn = route_node_get (table, p);
1961 for (rib = rn->info; rib; rib = rib->next)
1962 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1963 break;
1964
1965 if (rib)
1966 {
1967 /* Same distance static route is there. Update it with new
1968 nexthop. */
paul718e3742002-12-13 20:15:29 +00001969 route_unlock_node (rn);
1970
1971 switch (si->type)
1972 {
1973 case STATIC_IPV6_GATEWAY:
1974 nexthop_ipv6_add (rib, &si->ipv6);
1975 break;
1976 case STATIC_IPV6_IFNAME:
1977 nexthop_ifname_add (rib, si->ifname);
1978 break;
1979 case STATIC_IPV6_GATEWAY_IFNAME:
1980 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
1981 break;
1982 }
paul4d38fdb2005-04-28 17:35:14 +00001983 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00001984 }
1985 else
1986 {
1987 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00001988 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
1989
paul718e3742002-12-13 20:15:29 +00001990 rib->type = ZEBRA_ROUTE_STATIC;
1991 rib->distance = si->distance;
1992 rib->metric = 0;
1993 rib->nexthop_num = 0;
1994
1995 switch (si->type)
1996 {
1997 case STATIC_IPV6_GATEWAY:
1998 nexthop_ipv6_add (rib, &si->ipv6);
1999 break;
2000 case STATIC_IPV6_IFNAME:
2001 nexthop_ifname_add (rib, si->ifname);
2002 break;
2003 case STATIC_IPV6_GATEWAY_IFNAME:
2004 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2005 break;
2006 }
2007
hasso81dfcaa2003-05-25 19:21:25 +00002008 /* Save the flags of this static routes (reject, blackhole) */
2009 rib->flags = si->flags;
2010
paul718e3742002-12-13 20:15:29 +00002011 /* Link this rib to the tree. */
2012 rib_addnode (rn, rib);
2013
2014 /* Process this prefix. */
paul4d38fdb2005-04-28 17:35:14 +00002015 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00002016 }
2017}
2018
paula1ac18c2005-06-28 17:17:12 +00002019static int
paul718e3742002-12-13 20:15:29 +00002020static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2021{
2022 if (nexthop->type == NEXTHOP_TYPE_IPV6
2023 && si->type == STATIC_IPV6_GATEWAY
2024 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2025 return 1;
2026 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2027 && si->type == STATIC_IPV6_IFNAME
2028 && strcmp (nexthop->ifname, si->ifname) == 0)
2029 return 1;
2030 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2031 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2032 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2033 && strcmp (nexthop->ifname, si->ifname) == 0)
2034 return 1;
2035 return 0;;
2036}
2037
paula1ac18c2005-06-28 17:17:12 +00002038static void
paul718e3742002-12-13 20:15:29 +00002039static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2040{
2041 struct route_table *table;
2042 struct route_node *rn;
2043 struct rib *rib;
2044 struct nexthop *nexthop;
2045
2046 /* Lookup table. */
2047 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2048 if (! table)
2049 return;
2050
2051 /* Lookup existing route with type and distance. */
2052 rn = route_node_lookup (table, (struct prefix *) p);
2053 if (! rn)
2054 return;
2055
2056 for (rib = rn->info; rib; rib = rib->next)
2057 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2058 break;
2059 if (! rib)
2060 {
2061 route_unlock_node (rn);
2062 return;
2063 }
2064
2065 /* Lookup nexthop. */
2066 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2067 if (static_ipv6_nexthop_same (nexthop, si))
2068 break;
2069
2070 /* Can't find nexthop. */
2071 if (! nexthop)
2072 {
2073 route_unlock_node (rn);
2074 return;
2075 }
2076
2077 /* Check nexthop. */
2078 if (rib->nexthop_num == 1)
2079 {
2080 rib_delnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00002081 rib_queue_add (&zebrad, rn, rib);
paul718e3742002-12-13 20:15:29 +00002082 }
2083 else
2084 {
paul6baeb982003-10-28 03:47:15 +00002085 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2086 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002087 nexthop_delete (rib, nexthop);
2088 nexthop_free (nexthop);
2089 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00002090 }
paul718e3742002-12-13 20:15:29 +00002091 /* Unlock node. */
2092 route_unlock_node (rn);
2093}
2094
2095/* Add static route into static route configuration. */
2096int
2097static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002098 const char *ifname, u_char flags, u_char distance,
2099 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002100{
2101 struct route_node *rn;
2102 struct static_ipv6 *si;
2103 struct static_ipv6 *pp;
2104 struct static_ipv6 *cp;
2105 struct route_table *stable;
2106
2107 /* Lookup table. */
2108 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2109 if (! stable)
2110 return -1;
2111
2112 /* Lookup static route prefix. */
2113 rn = route_node_get (stable, p);
2114
2115 /* Do nothing if there is a same static route. */
2116 for (si = rn->info; si; si = si->next)
2117 {
2118 if (distance == si->distance
2119 && type == si->type
2120 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2121 && (! ifname || strcmp (ifname, si->ifname) == 0))
2122 {
2123 route_unlock_node (rn);
2124 return 0;
2125 }
2126 }
2127
2128 /* Make new static route structure. */
2129 si = XMALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
2130 memset (si, 0, sizeof (struct static_ipv6));
2131
2132 si->type = type;
2133 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002134 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002135
2136 switch (type)
2137 {
2138 case STATIC_IPV6_GATEWAY:
2139 si->ipv6 = *gate;
2140 break;
2141 case STATIC_IPV6_IFNAME:
2142 si->ifname = XSTRDUP (0, ifname);
2143 break;
2144 case STATIC_IPV6_GATEWAY_IFNAME:
2145 si->ipv6 = *gate;
2146 si->ifname = XSTRDUP (0, ifname);
2147 break;
2148 }
2149
2150 /* Add new static route information to the tree with sort by
2151 distance value and gateway address. */
2152 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2153 {
2154 if (si->distance < cp->distance)
2155 break;
2156 if (si->distance > cp->distance)
2157 continue;
2158 }
2159
2160 /* Make linked list. */
2161 if (pp)
2162 pp->next = si;
2163 else
2164 rn->info = si;
2165 if (cp)
2166 cp->prev = si;
2167 si->prev = pp;
2168 si->next = cp;
2169
2170 /* Install into rib. */
2171 static_install_ipv6 (p, si);
2172
2173 return 1;
2174}
2175
2176/* Delete static route from static route configuration. */
2177int
2178static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002179 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002180{
2181 struct route_node *rn;
2182 struct static_ipv6 *si;
2183 struct route_table *stable;
2184
2185 /* Lookup table. */
2186 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2187 if (! stable)
2188 return -1;
2189
2190 /* Lookup static route prefix. */
2191 rn = route_node_lookup (stable, p);
2192 if (! rn)
2193 return 0;
2194
2195 /* Find same static route is the tree */
2196 for (si = rn->info; si; si = si->next)
2197 if (distance == si->distance
2198 && type == si->type
2199 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2200 && (! ifname || strcmp (ifname, si->ifname) == 0))
2201 break;
2202
2203 /* Can't find static route. */
2204 if (! si)
2205 {
2206 route_unlock_node (rn);
2207 return 0;
2208 }
2209
2210 /* Install into rib. */
2211 static_uninstall_ipv6 (p, si);
2212
2213 /* Unlink static route from linked list. */
2214 if (si->prev)
2215 si->prev->next = si->next;
2216 else
2217 rn->info = si->next;
2218 if (si->next)
2219 si->next->prev = si->prev;
2220
2221 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002222 if (ifname)
2223 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00002224 XFREE (MTYPE_STATIC_IPV6, si);
2225
2226 return 1;
2227}
2228#endif /* HAVE_IPV6 */
2229
2230/* RIB update function. */
2231void
paula1ac18c2005-06-28 17:17:12 +00002232rib_update (void)
paul718e3742002-12-13 20:15:29 +00002233{
2234 struct route_node *rn;
2235 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00002236
paul718e3742002-12-13 20:15:29 +00002237 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2238 if (table)
2239 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002240 if (rn->info)
2241 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00002242
2243 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2244 if (table)
2245 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002246 if (rn->info)
2247 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00002248}
2249
2250/* Interface goes up. */
paula1ac18c2005-06-28 17:17:12 +00002251static void
paul718e3742002-12-13 20:15:29 +00002252rib_if_up (struct interface *ifp)
2253{
2254 rib_update ();
2255}
2256
2257/* Interface goes down. */
paula1ac18c2005-06-28 17:17:12 +00002258static void
paul718e3742002-12-13 20:15:29 +00002259rib_if_down (struct interface *ifp)
2260{
2261 rib_update ();
2262}
2263
2264/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00002265static void
paul718e3742002-12-13 20:15:29 +00002266rib_weed_table (struct route_table *table)
2267{
2268 struct route_node *rn;
2269 struct rib *rib;
2270 struct rib *next;
2271
2272 if (table)
2273 for (rn = route_top (table); rn; rn = route_next (rn))
2274 for (rib = rn->info; rib; rib = next)
2275 {
2276 next = rib->next;
2277
paulb21b19c2003-06-15 01:28:29 +00002278 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00002279 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00002280 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002281 }
2282}
2283
2284/* Delete all routes from non main table. */
2285void
paula1ac18c2005-06-28 17:17:12 +00002286rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00002287{
2288 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2289 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2290}
2291
2292/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00002293static void
paul718e3742002-12-13 20:15:29 +00002294rib_sweep_table (struct route_table *table)
2295{
2296 struct route_node *rn;
2297 struct rib *rib;
2298 struct rib *next;
2299 int ret = 0;
2300
2301 if (table)
2302 for (rn = route_top (table); rn; rn = route_next (rn))
2303 for (rib = rn->info; rib; rib = next)
2304 {
2305 next = rib->next;
2306
2307 if (rib->type == ZEBRA_ROUTE_KERNEL &&
2308 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
2309 {
2310 ret = rib_uninstall_kernel (rn, rib);
2311 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00002312 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002313 }
2314 }
2315}
2316
2317/* Sweep all RIB tables. */
2318void
paula1ac18c2005-06-28 17:17:12 +00002319rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00002320{
2321 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2322 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2323}
2324
2325/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00002326static void
paul718e3742002-12-13 20:15:29 +00002327rib_close_table (struct route_table *table)
2328{
2329 struct route_node *rn;
2330 struct rib *rib;
2331
2332 if (table)
2333 for (rn = route_top (table); rn; rn = route_next (rn))
2334 for (rib = rn->info; rib; rib = rib->next)
2335 if (! RIB_SYSTEM_ROUTE (rib)
2336 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2337 rib_uninstall_kernel (rn, rib);
2338}
2339
2340/* Close all RIB tables. */
2341void
paula1ac18c2005-06-28 17:17:12 +00002342rib_close (void)
paul718e3742002-12-13 20:15:29 +00002343{
2344 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2345 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2346}
2347
2348/* Routing information base initialize. */
2349void
paula1ac18c2005-06-28 17:17:12 +00002350rib_init (void)
paul718e3742002-12-13 20:15:29 +00002351{
paul4d38fdb2005-04-28 17:35:14 +00002352 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00002353 /* VRF initialization. */
2354 vrf_init ();
2355}