blob: 6d947c85ab46e58f875547283dc5743253f7931a [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
paul4d38fdb2005-04-28 17:35:14 +0000884rib_process (struct zebra_queue_node_t *qnode)
paul718e3742002-12-13 20:15:29 +0000885{
886 struct rib *rib;
887 struct rib *next;
888 struct rib *fib = NULL;
889 struct rib *select = NULL;
paul4d38fdb2005-04-28 17:35:14 +0000890 struct rib *del = qnode->del;
891 struct route_node *rn = qnode->node;
pauld753e9e2003-01-22 19:45:50 +0000892 int installed = 0;
893 struct nexthop *nexthop = NULL;
paul4d38fdb2005-04-28 17:35:14 +0000894
895 assert (rn);
896
897 /* possibly should lock and unlock rib on each iteration. however, for
898 * now, we assume called functions are synchronous and dont delete RIBs
899 * (as the work-queue deconstructor for this function is supposed to be
900 * the canonical 'delete' path for RIBs). Further if called functions
901 * below were to made asynchronous they should themselves acquire any
902 * locks/refcounts as needed and not depend on this caller to do it for
903 * them
904 */
paul718e3742002-12-13 20:15:29 +0000905 for (rib = rn->info; rib; rib = next)
906 {
907 next = rib->next;
pauld753e9e2003-01-22 19:45:50 +0000908
paul718e3742002-12-13 20:15:29 +0000909 /* Currently installed rib. */
910 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
paul7021c422003-07-15 12:52:22 +0000911 fib = rib;
paul4d38fdb2005-04-28 17:35:14 +0000912
paul718e3742002-12-13 20:15:29 +0000913 /* Skip unreachable nexthop. */
914 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +0000915 continue;
paul718e3742002-12-13 20:15:29 +0000916
917 /* Infinit distance. */
918 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +0000919 continue;
paul718e3742002-12-13 20:15:29 +0000920
921 /* Newly selected rib. */
922 if (! select || rib->distance < select->distance
paul7021c422003-07-15 12:52:22 +0000923 || rib->type == ZEBRA_ROUTE_CONNECT)
924 select = rib;
paul718e3742002-12-13 20:15:29 +0000925 }
paul4d38fdb2005-04-28 17:35:14 +0000926
paul718e3742002-12-13 20:15:29 +0000927 /* Deleted route check. */
928 if (del && CHECK_FLAG (del->flags, ZEBRA_FLAG_SELECTED))
929 fib = del;
paul4d38fdb2005-04-28 17:35:14 +0000930
931 /* We possibly should lock fib and select here However, all functions
932 * below are 'inline' and not asynchronous And if any were to be
933 * converted, they should manage references themselves really.. See
934 * previous comment above.
935 */
936
paul718e3742002-12-13 20:15:29 +0000937 /* Same route is selected. */
938 if (select && select == fib)
939 {
940 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +0000941 {
942 redistribute_delete (&rn->p, select);
943 if (! RIB_SYSTEM_ROUTE (select))
944 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +0000945
paul4d38fdb2005-04-28 17:35:14 +0000946 /* Set real nexthop. */
947 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +0000948
paul4d38fdb2005-04-28 17:35:14 +0000949 if (! RIB_SYSTEM_ROUTE (select))
950 rib_install_kernel (rn, select);
951 redistribute_add (&rn->p, select);
952 }
pauld753e9e2003-01-22 19:45:50 +0000953 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +0000954 {
955 /* Housekeeping code to deal with
956 race conditions in kernel with linux
957 netlink reporting interface up before IPv4 or IPv6 protocol
958 is ready to add routes.
959 This makes sure the routes are IN the kernel.
960 */
pauld753e9e2003-01-22 19:45:50 +0000961
paul4d38fdb2005-04-28 17:35:14 +0000962 for (nexthop = select->nexthop; nexthop; nexthop = nexthop->next)
963 {
964 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
965 installed = 1;
966 }
967 if (! installed)
968 rib_install_kernel (rn, select);
969 }
970 return WQ_SUCCESS;
paul718e3742002-12-13 20:15:29 +0000971 }
972
973 /* Uninstall old rib from forwarding table. */
974 if (fib)
975 {
976 redistribute_delete (&rn->p, fib);
977 if (! RIB_SYSTEM_ROUTE (fib))
978 rib_uninstall_kernel (rn, fib);
979 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
980
981 /* Set real nexthop. */
982 nexthop_active_update (rn, fib, 1);
983 }
984
985 /* Install new rib into forwarding table. */
986 if (select)
987 {
988 /* Set real nexthop. */
989 nexthop_active_update (rn, select, 1);
990
991 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +0000992 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +0000993 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
994 redistribute_add (&rn->p, select);
995 }
paul4d38fdb2005-04-28 17:35:14 +0000996
997 return WQ_SUCCESS;
998
999}
1000
1001/* Add work queue item to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001002static void
paul4d38fdb2005-04-28 17:35:14 +00001003rib_queue_add_qnode (struct zebra_t *zebra, struct zebra_queue_node_t *qnode)
1004{
1005 route_lock_node (qnode->node);
1006
1007 if (IS_ZEBRA_DEBUG_EVENT)
1008 zlog_info ("rib_queue_add_qnode: work queue added");
1009
1010 assert (zebra && qnode && qnode->node);
1011
1012 if (qnode->del)
1013 rib_lock (qnode->del);
1014
1015 if (zebra->ribq == NULL)
1016 {
1017 zlog_err ("rib_queue_add_qnode: ribq work_queue does not exist!");
1018 route_unlock_node (qnode->node);
1019 return;
1020 }
1021
1022 work_queue_add (zebra->ribq, qnode);
1023
1024 return;
1025}
1026
1027/* Add route node and rib to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001028static void
paul4d38fdb2005-04-28 17:35:14 +00001029rib_queue_add (struct zebra_t *zebra, struct route_node *rn, struct rib *del)
1030{
1031 struct zebra_queue_node_t *qnode;
1032
1033 assert (zebra && rn);
1034
1035 qnode = (struct zebra_queue_node_t *)
1036 XCALLOC (MTYPE_RIB_QUEUE, sizeof (struct zebra_queue_node_t));
1037
1038 if (qnode == NULL)
1039 {
1040 zlog_err ("rib_queue_add: failed to allocate queue node memory, %s",
1041 strerror (errno));
1042 return;
1043 }
1044
1045 qnode->node = rn;
1046 qnode->del = del;
1047
1048 rib_queue_add_qnode (zebra, qnode);
1049
1050 return;
1051}
1052
1053/* free zebra_queue_node_t */
paula1ac18c2005-06-28 17:17:12 +00001054static void
paul4d38fdb2005-04-28 17:35:14 +00001055rib_queue_qnode_del (struct zebra_queue_node_t *qnode)
1056{
1057 route_unlock_node (qnode->node);
1058
1059 if (qnode->del)
1060 rib_unlock (qnode->del);
1061
1062 XFREE (MTYPE_RIB_QUEUE, qnode);
1063}
1064
1065/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001066static void
paul4d38fdb2005-04-28 17:35:14 +00001067rib_queue_init (struct zebra_t *zebra)
1068{
1069 assert (zebra);
1070
1071 if (! (zebra->ribq = work_queue_new (zebra->master,
1072 "zebra_rib_work_queue")))
1073 {
1074 zlog_err ("rib_queue_init: could not initialise work queue!");
1075 return;
1076 }
1077
1078 /* fill in the work queue spec */
1079 zebra->ribq->spec.workfunc = (wq_item_status (*) (void *))&rib_process;
1080 zebra->ribq->spec.errorfunc = NULL;
1081 zebra->ribq->spec.del_item_data = (void (*) (void *)) &rib_queue_qnode_del;
1082 /* XXX: TODO: These should be runtime configurable via vty */
1083 zebra->ribq->spec.max_retries = 3;
1084 zebra->ribq->spec.hold = 500;
1085 zebra->ribq->spec.delay = 10;
1086
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 {
1160 if (rib->type == ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001161 {
1162 nexthop = rib->nexthop;
paul718e3742002-12-13 20:15:29 +00001163
paul4d38fdb2005-04-28 17:35:14 +00001164 /* Duplicate connected route comes in. */
1165 if (rib->type == type
1166 && nexthop && nexthop->type == NEXTHOP_TYPE_IFINDEX
1167 && nexthop->ifindex == ifindex)
1168 {
1169 rib->refcnt++;
1170 return 0 ;
1171 }
1172 }
paul718e3742002-12-13 20:15:29 +00001173 else if (rib->type == type)
paul4d38fdb2005-04-28 17:35:14 +00001174 {
1175 same = rib;
1176 break;
1177 }
paul718e3742002-12-13 20:15:29 +00001178 }
1179
1180 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001181 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001182 rib->type = type;
1183 rib->distance = distance;
1184 rib->flags = flags;
1185 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001186 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001187 rib->nexthop_num = 0;
1188 rib->uptime = time (NULL);
1189
1190 /* Nexthop settings. */
1191 if (gate)
1192 {
1193 if (ifindex)
1194 nexthop_ipv4_ifindex_add (rib, gate, ifindex);
1195 else
1196 nexthop_ipv4_add (rib, gate);
1197 }
1198 else
1199 nexthop_ifindex_add (rib, ifindex);
1200
1201 /* If this route is kernel route, set FIB flag to the route. */
1202 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1203 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1204 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1205
1206 /* Link new rib to node.*/
1207 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001208
paul718e3742002-12-13 20:15:29 +00001209 /* Process this route node. */
paul4d38fdb2005-04-28 17:35:14 +00001210 rib_queue_add (&zebrad, rn, same);
1211
paul718e3742002-12-13 20:15:29 +00001212 /* Free implicit route.*/
1213 if (same)
paul4d38fdb2005-04-28 17:35:14 +00001214 rib_delnode (rn, same);
1215
1216 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001217 return 0;
1218}
1219
1220int
1221rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib)
1222{
1223 struct route_table *table;
1224 struct route_node *rn;
1225 struct rib *same;
1226 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00001227
paul718e3742002-12-13 20:15:29 +00001228 /* Lookup table. */
1229 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1230 if (! table)
1231 return 0;
paul718e3742002-12-13 20:15:29 +00001232 /* Make it sure prefixlen is applied to the prefix. */
1233 apply_mask_ipv4 (p);
1234
1235 /* Set default distance by route type. */
1236 if (rib->distance == 0)
1237 {
1238 rib->distance = route_info[rib->type].distance;
1239
1240 /* iBGP distance is 200. */
1241 if (rib->type == ZEBRA_ROUTE_BGP
1242 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1243 rib->distance = 200;
1244 }
1245
1246 /* Lookup route node.*/
1247 rn = route_node_get (table, (struct prefix *) p);
1248
1249 /* If same type of route are installed, treat it as a implicit
1250 withdraw. */
1251 for (same = rn->info; same; same = same->next)
1252 {
1253 if (same->type == rib->type && same->table == rib->table
1254 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001255 break;
paul718e3742002-12-13 20:15:29 +00001256 }
paul4d38fdb2005-04-28 17:35:14 +00001257
paul718e3742002-12-13 20:15:29 +00001258 /* If this route is kernel route, set FIB flag to the route. */
1259 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
1260 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1261 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1262
1263 /* Link new rib to node.*/
1264 rib_addnode (rn, rib);
1265
1266 /* Process this route node. */
paul4d38fdb2005-04-28 17:35:14 +00001267 rib_queue_add (&zebrad, rn, same);
paul718e3742002-12-13 20:15:29 +00001268
1269 /* Free implicit route.*/
1270 if (same)
paul4d38fdb2005-04-28 17:35:14 +00001271 rib_delnode (rn, same);
1272
1273 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001274 return 0;
1275}
1276
1277int
1278rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
1279 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1280{
1281 struct route_table *table;
1282 struct route_node *rn;
1283 struct rib *rib;
1284 struct rib *fib = NULL;
1285 struct rib *same = NULL;
1286 struct nexthop *nexthop;
1287 char buf1[BUFSIZ];
1288 char buf2[BUFSIZ];
1289
1290 /* Lookup table. */
1291 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1292 if (! table)
1293 return 0;
1294
1295 /* Apply mask. */
1296 apply_mask_ipv4 (p);
1297
paul5ec90d22003-06-19 01:41:37 +00001298 if (IS_ZEBRA_DEBUG_KERNEL && gate)
ajsb6178002004-12-07 21:12:56 +00001299 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
paul5ec90d22003-06-19 01:41:37 +00001300 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1301 p->prefixlen,
1302 inet_ntoa (*gate),
1303 ifindex);
1304
paul718e3742002-12-13 20:15:29 +00001305 /* Lookup route node. */
1306 rn = route_node_lookup (table, (struct prefix *) p);
1307 if (! rn)
1308 {
1309 if (IS_ZEBRA_DEBUG_KERNEL)
1310 {
1311 if (gate)
ajsb6178002004-12-07 21:12:56 +00001312 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001313 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1314 p->prefixlen,
1315 inet_ntop (AF_INET, gate, buf2, BUFSIZ),
1316 ifindex);
1317 else
ajsb6178002004-12-07 21:12:56 +00001318 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001319 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1320 p->prefixlen,
1321 ifindex);
1322 }
1323 return ZEBRA_ERR_RTNOEXIST;
1324 }
1325
1326 /* Lookup same type route. */
1327 for (rib = rn->info; rib; rib = rib->next)
1328 {
1329 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1330 fib = rib;
1331
1332 if (rib->type == ZEBRA_ROUTE_CONNECT)
1333 {
1334 nexthop = rib->nexthop;
1335
1336 if (rib->type == type
1337 && nexthop && nexthop->type == NEXTHOP_TYPE_IFINDEX
1338 && nexthop->ifindex == ifindex)
1339 {
1340 if (rib->refcnt)
1341 {
1342 rib->refcnt--;
1343 route_unlock_node (rn);
1344 route_unlock_node (rn);
1345 return 0;
1346 }
1347 same = rib;
1348 break;
1349 }
1350 }
paul5ec90d22003-06-19 01:41:37 +00001351 else if (gate)
1352 {
1353 nexthop = rib->nexthop;
1354
1355 /* Make sure that the route found has the same gateway. */
1356 if (rib->type == type
1357 && nexthop &&
1358 (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
1359 IPV4_ADDR_SAME (&nexthop->rgate.ipv4, gate)) )
1360 {
1361 same = rib;
1362 break;
1363 }
1364 }
paul718e3742002-12-13 20:15:29 +00001365 else
1366 {
1367 if (rib->type == type)
1368 {
1369 same = rib;
1370 break;
1371 }
1372 }
1373 }
1374
1375 /* If same type of route can't be found and this message is from
1376 kernel. */
1377 if (! same)
1378 {
1379 if (fib && type == ZEBRA_ROUTE_KERNEL)
1380 {
1381 /* Unset flags. */
1382 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1383 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1384
1385 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1386 }
1387 else
1388 {
1389 if (IS_ZEBRA_DEBUG_KERNEL)
1390 {
1391 if (gate)
ajsb6178002004-12-07 21:12:56 +00001392 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001393 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1394 p->prefixlen,
1395 inet_ntop (AF_INET, gate, buf2, BUFSIZ),
1396 ifindex,
1397 type);
1398 else
ajsb6178002004-12-07 21:12:56 +00001399 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001400 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1401 p->prefixlen,
1402 ifindex,
1403 type);
1404 }
1405 route_unlock_node (rn);
1406 return ZEBRA_ERR_RTNOEXIST;
1407 }
1408 }
paul4d38fdb2005-04-28 17:35:14 +00001409
1410 /* Process changes. */
1411 rib_queue_add (&zebrad, rn, same);
paul718e3742002-12-13 20:15:29 +00001412
1413 if (same)
1414 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00001415
paul718e3742002-12-13 20:15:29 +00001416 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001417 return 0;
1418}
1419
1420/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00001421static void
paul718e3742002-12-13 20:15:29 +00001422static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
1423{
1424 struct rib *rib;
1425 struct route_node *rn;
1426 struct route_table *table;
1427
1428 /* Lookup table. */
1429 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1430 if (! table)
1431 return;
1432
1433 /* Lookup existing route */
1434 rn = route_node_get (table, p);
1435 for (rib = rn->info; rib; rib = rib->next)
1436 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1437 break;
1438
1439 if (rib)
1440 {
1441 /* Same distance static route is there. Update it with new
1442 nexthop. */
paul718e3742002-12-13 20:15:29 +00001443 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001444 switch (si->type)
paul7021c422003-07-15 12:52:22 +00001445 {
1446 case STATIC_IPV4_GATEWAY:
1447 nexthop_ipv4_add (rib, &si->gate.ipv4);
1448 break;
1449 case STATIC_IPV4_IFNAME:
1450 nexthop_ifname_add (rib, si->gate.ifname);
1451 break;
1452 case STATIC_IPV4_BLACKHOLE:
1453 nexthop_blackhole_add (rib);
1454 break;
paul4d38fdb2005-04-28 17:35:14 +00001455 }
1456 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00001457 }
1458 else
1459 {
1460 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00001461 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
1462
paul718e3742002-12-13 20:15:29 +00001463 rib->type = ZEBRA_ROUTE_STATIC;
1464 rib->distance = si->distance;
1465 rib->metric = 0;
1466 rib->nexthop_num = 0;
1467
1468 switch (si->type)
paul7021c422003-07-15 12:52:22 +00001469 {
1470 case STATIC_IPV4_GATEWAY:
1471 nexthop_ipv4_add (rib, &si->gate.ipv4);
1472 break;
1473 case STATIC_IPV4_IFNAME:
1474 nexthop_ifname_add (rib, si->gate.ifname);
1475 break;
1476 case STATIC_IPV4_BLACKHOLE:
1477 nexthop_blackhole_add (rib);
1478 break;
1479 }
paul718e3742002-12-13 20:15:29 +00001480
hasso81dfcaa2003-05-25 19:21:25 +00001481 /* Save the flags of this static routes (reject, blackhole) */
1482 rib->flags = si->flags;
1483
paul718e3742002-12-13 20:15:29 +00001484 /* Link this rib to the tree. */
1485 rib_addnode (rn, rib);
1486
1487 /* Process this prefix. */
paul4d38fdb2005-04-28 17:35:14 +00001488 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00001489 }
1490}
1491
paula1ac18c2005-06-28 17:17:12 +00001492static int
paul718e3742002-12-13 20:15:29 +00001493static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
1494{
1495 if (nexthop->type == NEXTHOP_TYPE_IPV4
1496 && si->type == STATIC_IPV4_GATEWAY
1497 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
1498 return 1;
1499 if (nexthop->type == NEXTHOP_TYPE_IFNAME
1500 && si->type == STATIC_IPV4_IFNAME
1501 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
1502 return 1;
paul595db7f2003-05-25 21:35:06 +00001503 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
1504 && si->type == STATIC_IPV4_BLACKHOLE)
1505 return 1;
paul718e3742002-12-13 20:15:29 +00001506 return 0;;
1507}
1508
1509/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00001510static void
paul718e3742002-12-13 20:15:29 +00001511static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
1512{
1513 struct route_node *rn;
1514 struct rib *rib;
1515 struct nexthop *nexthop;
1516 struct route_table *table;
1517
1518 /* Lookup table. */
1519 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1520 if (! table)
1521 return;
paul4d38fdb2005-04-28 17:35:14 +00001522
paul718e3742002-12-13 20:15:29 +00001523 /* Lookup existing route with type and distance. */
1524 rn = route_node_lookup (table, p);
1525 if (! rn)
1526 return;
1527
1528 for (rib = rn->info; rib; rib = rib->next)
1529 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1530 break;
1531
1532 if (! rib)
1533 {
1534 route_unlock_node (rn);
1535 return;
1536 }
1537
1538 /* Lookup nexthop. */
1539 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1540 if (static_ipv4_nexthop_same (nexthop, si))
1541 break;
1542
1543 /* Can't find nexthop. */
1544 if (! nexthop)
1545 {
1546 route_unlock_node (rn);
1547 return;
1548 }
1549
1550 /* Check nexthop. */
1551 if (rib->nexthop_num == 1)
1552 {
paul4d38fdb2005-04-28 17:35:14 +00001553 rib_queue_add (&zebrad, rn, rib);
paul718e3742002-12-13 20:15:29 +00001554 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00001555 }
1556 else
1557 {
paul6baeb982003-10-28 03:47:15 +00001558 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1559 rib_uninstall (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001560 rib_queue_add (&zebrad, rn, rib);
paul718e3742002-12-13 20:15:29 +00001561 }
paul718e3742002-12-13 20:15:29 +00001562 /* Unlock node. */
1563 route_unlock_node (rn);
1564}
1565
1566/* Add static route into static route configuration. */
1567int
hasso39db97e2004-10-12 20:50:58 +00001568static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00001569 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001570{
1571 u_char type = 0;
1572 struct route_node *rn;
1573 struct static_ipv4 *si;
1574 struct static_ipv4 *pp;
1575 struct static_ipv4 *cp;
1576 struct static_ipv4 *update = NULL;
1577 struct route_table *stable;
1578
1579 /* Lookup table. */
1580 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
1581 if (! stable)
1582 return -1;
1583
1584 /* Lookup static route prefix. */
1585 rn = route_node_get (stable, p);
1586
1587 /* Make flags. */
1588 if (gate)
1589 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00001590 else if (ifname)
paul718e3742002-12-13 20:15:29 +00001591 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00001592 else
1593 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00001594
1595 /* Do nothing if there is a same static route. */
1596 for (si = rn->info; si; si = si->next)
1597 {
1598 if (type == si->type
1599 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
1600 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
1601 {
1602 if (distance == si->distance)
1603 {
1604 route_unlock_node (rn);
1605 return 0;
1606 }
1607 else
1608 update = si;
1609 }
1610 }
1611
1612 /* Distance chaged. */
1613 if (update)
1614 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
1615
1616 /* Make new static route structure. */
1617 si = XMALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
1618 memset (si, 0, sizeof (struct static_ipv4));
1619
1620 si->type = type;
1621 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00001622 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00001623
1624 if (gate)
1625 si->gate.ipv4 = *gate;
1626 if (ifname)
1627 si->gate.ifname = XSTRDUP (0, ifname);
1628
1629 /* Add new static route information to the tree with sort by
1630 distance value and gateway address. */
1631 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
1632 {
1633 if (si->distance < cp->distance)
1634 break;
1635 if (si->distance > cp->distance)
1636 continue;
1637 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
1638 {
1639 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
1640 break;
1641 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
1642 continue;
1643 }
1644 }
1645
1646 /* Make linked list. */
1647 if (pp)
1648 pp->next = si;
1649 else
1650 rn->info = si;
1651 if (cp)
1652 cp->prev = si;
1653 si->prev = pp;
1654 si->next = cp;
1655
1656 /* Install into rib. */
1657 static_install_ipv4 (p, si);
1658
1659 return 1;
1660}
1661
1662/* Delete static route from static route configuration. */
1663int
hasso39db97e2004-10-12 20:50:58 +00001664static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00001665 u_char distance, u_int32_t vrf_id)
1666{
1667 u_char type = 0;
1668 struct route_node *rn;
1669 struct static_ipv4 *si;
1670 struct route_table *stable;
1671
1672 /* Lookup table. */
1673 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
1674 if (! stable)
1675 return -1;
1676
1677 /* Lookup static route prefix. */
1678 rn = route_node_lookup (stable, p);
1679 if (! rn)
1680 return 0;
1681
1682 /* Make flags. */
1683 if (gate)
1684 type = STATIC_IPV4_GATEWAY;
1685 else if (ifname)
1686 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00001687 else
1688 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00001689
1690 /* Find same static route is the tree */
1691 for (si = rn->info; si; si = si->next)
1692 if (type == si->type
1693 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
1694 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
1695 break;
1696
1697 /* Can't find static route. */
1698 if (! si)
1699 {
1700 route_unlock_node (rn);
1701 return 0;
1702 }
1703
1704 /* Install into rib. */
1705 static_uninstall_ipv4 (p, si);
1706
1707 /* Unlink static route from linked list. */
1708 if (si->prev)
1709 si->prev->next = si->next;
1710 else
1711 rn->info = si->next;
1712 if (si->next)
1713 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00001714 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001715
1716 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00001717 if (ifname)
1718 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00001719 XFREE (MTYPE_STATIC_IPV4, si);
1720
paul143a3852003-09-29 20:06:13 +00001721 route_unlock_node (rn);
1722
paul718e3742002-12-13 20:15:29 +00001723 return 1;
1724}
1725
1726
1727#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00001728static int
paul718e3742002-12-13 20:15:29 +00001729rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
1730 struct in6_addr *gate, unsigned int ifindex, int table)
1731{
hasso726f9b22003-05-25 21:04:54 +00001732 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
1733#if defined (MUSICA) || defined (LINUX)
1734 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
1735 if (p->prefixlen == 96)
1736 return 0;
1737#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00001738 return 1;
hasso726f9b22003-05-25 21:04:54 +00001739 }
paul718e3742002-12-13 20:15:29 +00001740 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
1741 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
1742 {
1743 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
1744 return 1;
1745 }
1746 return 0;
1747}
1748
1749int
1750rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00001751 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
1752 u_int32_t metric, u_char distance)
paul718e3742002-12-13 20:15:29 +00001753{
1754 struct rib *rib;
1755 struct rib *same = NULL;
1756 struct route_table *table;
1757 struct route_node *rn;
1758 struct nexthop *nexthop;
1759
paul718e3742002-12-13 20:15:29 +00001760 /* Lookup table. */
1761 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1762 if (! table)
1763 return 0;
1764
1765 /* Make sure mask is applied. */
1766 apply_mask_ipv6 (p);
1767
1768 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00001769 if (!distance)
1770 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00001771
1772 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1773 distance = 200;
1774
1775 /* Filter bogus route. */
1776 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
1777 return 0;
1778
1779 /* Lookup route node.*/
1780 rn = route_node_get (table, (struct prefix *) p);
1781
1782 /* If same type of route are installed, treat it as a implicit
1783 withdraw. */
1784 for (rib = rn->info; rib; rib = rib->next)
1785 {
1786 if (rib->type == ZEBRA_ROUTE_CONNECT)
1787 {
1788 nexthop = rib->nexthop;
1789
1790 if (rib->type == type
1791 && nexthop && nexthop->type == NEXTHOP_TYPE_IFINDEX
1792 && nexthop->ifindex == ifindex)
1793 {
1794 rib->refcnt++;
1795 return 0;
1796 }
1797 }
1798 else if (rib->type == type)
1799 {
1800 same = rib;
paul718e3742002-12-13 20:15:29 +00001801 break;
1802 }
1803 }
1804
1805 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001806 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
1807
paul718e3742002-12-13 20:15:29 +00001808 rib->type = type;
1809 rib->distance = distance;
1810 rib->flags = flags;
1811 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001812 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001813 rib->nexthop_num = 0;
1814 rib->uptime = time (NULL);
1815
1816 /* Nexthop settings. */
1817 if (gate)
1818 {
1819 if (ifindex)
1820 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
1821 else
1822 nexthop_ipv6_add (rib, gate);
1823 }
1824 else
1825 nexthop_ifindex_add (rib, ifindex);
1826
1827 /* If this route is kernel route, set FIB flag to the route. */
1828 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1829 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1830 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1831
1832 /* Link new rib to node.*/
1833 rib_addnode (rn, rib);
1834
1835 /* Process this route node. */
paul4d38fdb2005-04-28 17:35:14 +00001836 rib_queue_add (&zebrad, rn, same);
1837
paul718e3742002-12-13 20:15:29 +00001838 /* Free implicit route.*/
1839 if (same)
paul4d38fdb2005-04-28 17:35:14 +00001840 rib_delnode (rn, same);
1841
1842 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001843 return 0;
1844}
1845
1846int
1847rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
1848 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1849{
1850 struct route_table *table;
1851 struct route_node *rn;
1852 struct rib *rib;
1853 struct rib *fib = NULL;
1854 struct rib *same = NULL;
1855 struct nexthop *nexthop;
1856 char buf1[BUFSIZ];
1857 char buf2[BUFSIZ];
1858
1859 /* Apply mask. */
1860 apply_mask_ipv6 (p);
1861
1862 /* Lookup table. */
1863 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1864 if (! table)
1865 return 0;
paul4d38fdb2005-04-28 17:35:14 +00001866
paul718e3742002-12-13 20:15:29 +00001867 /* Lookup route node. */
1868 rn = route_node_lookup (table, (struct prefix *) p);
1869 if (! rn)
1870 {
1871 if (IS_ZEBRA_DEBUG_KERNEL)
1872 {
1873 if (gate)
ajsb6178002004-12-07 21:12:56 +00001874 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001875 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1876 p->prefixlen,
1877 inet_ntop (AF_INET6, gate, buf2, BUFSIZ),
1878 ifindex);
1879 else
ajsb6178002004-12-07 21:12:56 +00001880 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001881 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1882 p->prefixlen,
1883 ifindex);
1884 }
1885 return ZEBRA_ERR_RTNOEXIST;
1886 }
1887
1888 /* Lookup same type route. */
1889 for (rib = rn->info; rib; rib = rib->next)
1890 {
1891 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1892 fib = rib;
1893
1894 if (rib->type == ZEBRA_ROUTE_CONNECT)
1895 {
1896 nexthop = rib->nexthop;
1897
1898 if (rib->type == type
1899 && nexthop && nexthop->type == NEXTHOP_TYPE_IFINDEX
1900 && nexthop->ifindex == ifindex)
1901 {
1902 if (rib->refcnt)
1903 {
1904 rib->refcnt--;
1905 route_unlock_node (rn);
1906 route_unlock_node (rn);
1907 return 0;
1908 }
1909 same = rib;
1910 break;
1911 }
1912 }
1913 else
1914 {
1915 if (rib->type == type)
1916 {
1917 same = rib;
1918 break;
1919 }
1920 }
1921 }
1922
1923 /* If same type of route can't be found and this message is from
1924 kernel. */
1925 if (! same)
1926 {
1927 if (fib && type == ZEBRA_ROUTE_KERNEL)
1928 {
1929 /* Unset flags. */
1930 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1931 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1932
1933 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1934 }
1935 else
1936 {
1937 if (IS_ZEBRA_DEBUG_KERNEL)
1938 {
1939 if (gate)
ajsb6178002004-12-07 21:12:56 +00001940 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001941 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1942 p->prefixlen,
1943 inet_ntop (AF_INET6, gate, buf2, BUFSIZ),
1944 ifindex,
1945 type);
1946 else
ajsb6178002004-12-07 21:12:56 +00001947 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001948 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1949 p->prefixlen,
1950 ifindex,
1951 type);
1952 }
1953 route_unlock_node (rn);
1954 return ZEBRA_ERR_RTNOEXIST;
1955 }
1956 }
1957
paul4d38fdb2005-04-28 17:35:14 +00001958 /* Process changes. */
1959 rib_queue_add (&zebrad, rn, same);
1960
paul718e3742002-12-13 20:15:29 +00001961 if (same)
1962 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00001963
paul718e3742002-12-13 20:15:29 +00001964 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001965 return 0;
1966}
1967
1968/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00001969static void
paul718e3742002-12-13 20:15:29 +00001970static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
1971{
1972 struct rib *rib;
1973 struct route_table *table;
1974 struct route_node *rn;
1975
1976 /* Lookup table. */
1977 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1978 if (! table)
1979 return;
1980
1981 /* Lookup existing route */
1982 rn = route_node_get (table, p);
1983 for (rib = rn->info; rib; rib = rib->next)
1984 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1985 break;
1986
1987 if (rib)
1988 {
1989 /* Same distance static route is there. Update it with new
1990 nexthop. */
paul718e3742002-12-13 20:15:29 +00001991 route_unlock_node (rn);
1992
1993 switch (si->type)
1994 {
1995 case STATIC_IPV6_GATEWAY:
1996 nexthop_ipv6_add (rib, &si->ipv6);
1997 break;
1998 case STATIC_IPV6_IFNAME:
1999 nexthop_ifname_add (rib, si->ifname);
2000 break;
2001 case STATIC_IPV6_GATEWAY_IFNAME:
2002 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2003 break;
2004 }
paul4d38fdb2005-04-28 17:35:14 +00002005 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00002006 }
2007 else
2008 {
2009 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002010 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2011
paul718e3742002-12-13 20:15:29 +00002012 rib->type = ZEBRA_ROUTE_STATIC;
2013 rib->distance = si->distance;
2014 rib->metric = 0;
2015 rib->nexthop_num = 0;
2016
2017 switch (si->type)
2018 {
2019 case STATIC_IPV6_GATEWAY:
2020 nexthop_ipv6_add (rib, &si->ipv6);
2021 break;
2022 case STATIC_IPV6_IFNAME:
2023 nexthop_ifname_add (rib, si->ifname);
2024 break;
2025 case STATIC_IPV6_GATEWAY_IFNAME:
2026 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2027 break;
2028 }
2029
hasso81dfcaa2003-05-25 19:21:25 +00002030 /* Save the flags of this static routes (reject, blackhole) */
2031 rib->flags = si->flags;
2032
paul718e3742002-12-13 20:15:29 +00002033 /* Link this rib to the tree. */
2034 rib_addnode (rn, rib);
2035
2036 /* Process this prefix. */
paul4d38fdb2005-04-28 17:35:14 +00002037 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00002038 }
2039}
2040
paula1ac18c2005-06-28 17:17:12 +00002041static int
paul718e3742002-12-13 20:15:29 +00002042static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2043{
2044 if (nexthop->type == NEXTHOP_TYPE_IPV6
2045 && si->type == STATIC_IPV6_GATEWAY
2046 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2047 return 1;
2048 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2049 && si->type == STATIC_IPV6_IFNAME
2050 && strcmp (nexthop->ifname, si->ifname) == 0)
2051 return 1;
2052 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2053 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2054 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2055 && strcmp (nexthop->ifname, si->ifname) == 0)
2056 return 1;
2057 return 0;;
2058}
2059
paula1ac18c2005-06-28 17:17:12 +00002060static void
paul718e3742002-12-13 20:15:29 +00002061static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2062{
2063 struct route_table *table;
2064 struct route_node *rn;
2065 struct rib *rib;
2066 struct nexthop *nexthop;
2067
2068 /* Lookup table. */
2069 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2070 if (! table)
2071 return;
2072
2073 /* Lookup existing route with type and distance. */
2074 rn = route_node_lookup (table, (struct prefix *) p);
2075 if (! rn)
2076 return;
2077
2078 for (rib = rn->info; rib; rib = rib->next)
2079 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2080 break;
2081 if (! rib)
2082 {
2083 route_unlock_node (rn);
2084 return;
2085 }
2086
2087 /* Lookup nexthop. */
2088 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2089 if (static_ipv6_nexthop_same (nexthop, si))
2090 break;
2091
2092 /* Can't find nexthop. */
2093 if (! nexthop)
2094 {
2095 route_unlock_node (rn);
2096 return;
2097 }
2098
2099 /* Check nexthop. */
2100 if (rib->nexthop_num == 1)
2101 {
2102 rib_delnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00002103 rib_queue_add (&zebrad, rn, rib);
paul718e3742002-12-13 20:15:29 +00002104 }
2105 else
2106 {
paul6baeb982003-10-28 03:47:15 +00002107 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2108 rib_uninstall (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00002109 rib_queue_add (&zebrad, rn, rib);
paul718e3742002-12-13 20:15:29 +00002110 }
paul718e3742002-12-13 20:15:29 +00002111 /* Unlock node. */
2112 route_unlock_node (rn);
2113}
2114
2115/* Add static route into static route configuration. */
2116int
2117static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002118 const char *ifname, u_char flags, u_char distance,
2119 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002120{
2121 struct route_node *rn;
2122 struct static_ipv6 *si;
2123 struct static_ipv6 *pp;
2124 struct static_ipv6 *cp;
2125 struct route_table *stable;
2126
2127 /* Lookup table. */
2128 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2129 if (! stable)
2130 return -1;
2131
2132 /* Lookup static route prefix. */
2133 rn = route_node_get (stable, p);
2134
2135 /* Do nothing if there is a same static route. */
2136 for (si = rn->info; si; si = si->next)
2137 {
2138 if (distance == si->distance
2139 && type == si->type
2140 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2141 && (! ifname || strcmp (ifname, si->ifname) == 0))
2142 {
2143 route_unlock_node (rn);
2144 return 0;
2145 }
2146 }
2147
2148 /* Make new static route structure. */
2149 si = XMALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
2150 memset (si, 0, sizeof (struct static_ipv6));
2151
2152 si->type = type;
2153 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002154 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002155
2156 switch (type)
2157 {
2158 case STATIC_IPV6_GATEWAY:
2159 si->ipv6 = *gate;
2160 break;
2161 case STATIC_IPV6_IFNAME:
2162 si->ifname = XSTRDUP (0, ifname);
2163 break;
2164 case STATIC_IPV6_GATEWAY_IFNAME:
2165 si->ipv6 = *gate;
2166 si->ifname = XSTRDUP (0, ifname);
2167 break;
2168 }
2169
2170 /* Add new static route information to the tree with sort by
2171 distance value and gateway address. */
2172 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2173 {
2174 if (si->distance < cp->distance)
2175 break;
2176 if (si->distance > cp->distance)
2177 continue;
2178 }
2179
2180 /* Make linked list. */
2181 if (pp)
2182 pp->next = si;
2183 else
2184 rn->info = si;
2185 if (cp)
2186 cp->prev = si;
2187 si->prev = pp;
2188 si->next = cp;
2189
2190 /* Install into rib. */
2191 static_install_ipv6 (p, si);
2192
2193 return 1;
2194}
2195
2196/* Delete static route from static route configuration. */
2197int
2198static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002199 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002200{
2201 struct route_node *rn;
2202 struct static_ipv6 *si;
2203 struct route_table *stable;
2204
2205 /* Lookup table. */
2206 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2207 if (! stable)
2208 return -1;
2209
2210 /* Lookup static route prefix. */
2211 rn = route_node_lookup (stable, p);
2212 if (! rn)
2213 return 0;
2214
2215 /* Find same static route is the tree */
2216 for (si = rn->info; si; si = si->next)
2217 if (distance == si->distance
2218 && type == si->type
2219 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2220 && (! ifname || strcmp (ifname, si->ifname) == 0))
2221 break;
2222
2223 /* Can't find static route. */
2224 if (! si)
2225 {
2226 route_unlock_node (rn);
2227 return 0;
2228 }
2229
2230 /* Install into rib. */
2231 static_uninstall_ipv6 (p, si);
2232
2233 /* Unlink static route from linked list. */
2234 if (si->prev)
2235 si->prev->next = si->next;
2236 else
2237 rn->info = si->next;
2238 if (si->next)
2239 si->next->prev = si->prev;
2240
2241 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002242 if (ifname)
2243 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00002244 XFREE (MTYPE_STATIC_IPV6, si);
2245
2246 return 1;
2247}
2248#endif /* HAVE_IPV6 */
2249
2250/* RIB update function. */
2251void
paula1ac18c2005-06-28 17:17:12 +00002252rib_update (void)
paul718e3742002-12-13 20:15:29 +00002253{
2254 struct route_node *rn;
2255 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00002256
paul718e3742002-12-13 20:15:29 +00002257 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2258 if (table)
2259 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002260 if (rn->info)
2261 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00002262
2263 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2264 if (table)
2265 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002266 if (rn->info)
2267 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00002268}
2269
2270/* Interface goes up. */
paula1ac18c2005-06-28 17:17:12 +00002271static void
paul718e3742002-12-13 20:15:29 +00002272rib_if_up (struct interface *ifp)
2273{
2274 rib_update ();
2275}
2276
2277/* Interface goes down. */
paula1ac18c2005-06-28 17:17:12 +00002278static void
paul718e3742002-12-13 20:15:29 +00002279rib_if_down (struct interface *ifp)
2280{
2281 rib_update ();
2282}
2283
2284/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00002285static void
paul718e3742002-12-13 20:15:29 +00002286rib_weed_table (struct route_table *table)
2287{
2288 struct route_node *rn;
2289 struct rib *rib;
2290 struct rib *next;
2291
2292 if (table)
2293 for (rn = route_top (table); rn; rn = route_next (rn))
2294 for (rib = rn->info; rib; rib = next)
2295 {
2296 next = rib->next;
2297
paulb21b19c2003-06-15 01:28:29 +00002298 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00002299 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00002300 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002301 }
2302}
2303
2304/* Delete all routes from non main table. */
2305void
paula1ac18c2005-06-28 17:17:12 +00002306rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00002307{
2308 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2309 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2310}
2311
2312/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00002313static void
paul718e3742002-12-13 20:15:29 +00002314rib_sweep_table (struct route_table *table)
2315{
2316 struct route_node *rn;
2317 struct rib *rib;
2318 struct rib *next;
2319 int ret = 0;
2320
2321 if (table)
2322 for (rn = route_top (table); rn; rn = route_next (rn))
2323 for (rib = rn->info; rib; rib = next)
2324 {
2325 next = rib->next;
2326
2327 if (rib->type == ZEBRA_ROUTE_KERNEL &&
2328 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
2329 {
2330 ret = rib_uninstall_kernel (rn, rib);
2331 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00002332 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002333 }
2334 }
2335}
2336
2337/* Sweep all RIB tables. */
2338void
paula1ac18c2005-06-28 17:17:12 +00002339rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00002340{
2341 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2342 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2343}
2344
2345/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00002346static void
paul718e3742002-12-13 20:15:29 +00002347rib_close_table (struct route_table *table)
2348{
2349 struct route_node *rn;
2350 struct rib *rib;
2351
2352 if (table)
2353 for (rn = route_top (table); rn; rn = route_next (rn))
2354 for (rib = rn->info; rib; rib = rib->next)
2355 if (! RIB_SYSTEM_ROUTE (rib)
2356 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2357 rib_uninstall_kernel (rn, rib);
2358}
2359
2360/* Close all RIB tables. */
2361void
paula1ac18c2005-06-28 17:17:12 +00002362rib_close (void)
paul718e3742002-12-13 20:15:29 +00002363{
2364 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2365 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2366}
2367
2368/* Routing information base initialize. */
2369void
paula1ac18c2005-06-28 17:17:12 +00002370rib_init (void)
paul718e3742002-12-13 20:15:29 +00002371{
paul4d38fdb2005-04-28 17:35:14 +00002372 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00002373 /* VRF initialization. */
2374 vrf_init ();
2375}