blob: 6cb686b781184ed0f24d06a9508649df4b655a62 [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);
paul319572c2005-09-21 12:30:08 +00001560 nexthop_delete (rib, nexthop);
1561 nexthop_free (nexthop);
1562 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00001563 }
paul718e3742002-12-13 20:15:29 +00001564 /* Unlock node. */
1565 route_unlock_node (rn);
1566}
1567
1568/* Add static route into static route configuration. */
1569int
hasso39db97e2004-10-12 20:50:58 +00001570static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00001571 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001572{
1573 u_char type = 0;
1574 struct route_node *rn;
1575 struct static_ipv4 *si;
1576 struct static_ipv4 *pp;
1577 struct static_ipv4 *cp;
1578 struct static_ipv4 *update = NULL;
1579 struct route_table *stable;
1580
1581 /* Lookup table. */
1582 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
1583 if (! stable)
1584 return -1;
1585
1586 /* Lookup static route prefix. */
1587 rn = route_node_get (stable, p);
1588
1589 /* Make flags. */
1590 if (gate)
1591 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00001592 else if (ifname)
paul718e3742002-12-13 20:15:29 +00001593 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00001594 else
1595 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00001596
1597 /* Do nothing if there is a same static route. */
1598 for (si = rn->info; si; si = si->next)
1599 {
1600 if (type == si->type
1601 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
1602 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
1603 {
1604 if (distance == si->distance)
1605 {
1606 route_unlock_node (rn);
1607 return 0;
1608 }
1609 else
1610 update = si;
1611 }
1612 }
1613
1614 /* Distance chaged. */
1615 if (update)
1616 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
1617
1618 /* Make new static route structure. */
1619 si = XMALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
1620 memset (si, 0, sizeof (struct static_ipv4));
1621
1622 si->type = type;
1623 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00001624 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00001625
1626 if (gate)
1627 si->gate.ipv4 = *gate;
1628 if (ifname)
1629 si->gate.ifname = XSTRDUP (0, ifname);
1630
1631 /* Add new static route information to the tree with sort by
1632 distance value and gateway address. */
1633 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
1634 {
1635 if (si->distance < cp->distance)
1636 break;
1637 if (si->distance > cp->distance)
1638 continue;
1639 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
1640 {
1641 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
1642 break;
1643 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
1644 continue;
1645 }
1646 }
1647
1648 /* Make linked list. */
1649 if (pp)
1650 pp->next = si;
1651 else
1652 rn->info = si;
1653 if (cp)
1654 cp->prev = si;
1655 si->prev = pp;
1656 si->next = cp;
1657
1658 /* Install into rib. */
1659 static_install_ipv4 (p, si);
1660
1661 return 1;
1662}
1663
1664/* Delete static route from static route configuration. */
1665int
hasso39db97e2004-10-12 20:50:58 +00001666static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00001667 u_char distance, u_int32_t vrf_id)
1668{
1669 u_char type = 0;
1670 struct route_node *rn;
1671 struct static_ipv4 *si;
1672 struct route_table *stable;
1673
1674 /* Lookup table. */
1675 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
1676 if (! stable)
1677 return -1;
1678
1679 /* Lookup static route prefix. */
1680 rn = route_node_lookup (stable, p);
1681 if (! rn)
1682 return 0;
1683
1684 /* Make flags. */
1685 if (gate)
1686 type = STATIC_IPV4_GATEWAY;
1687 else if (ifname)
1688 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00001689 else
1690 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00001691
1692 /* Find same static route is the tree */
1693 for (si = rn->info; si; si = si->next)
1694 if (type == si->type
1695 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
1696 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
1697 break;
1698
1699 /* Can't find static route. */
1700 if (! si)
1701 {
1702 route_unlock_node (rn);
1703 return 0;
1704 }
1705
1706 /* Install into rib. */
1707 static_uninstall_ipv4 (p, si);
1708
1709 /* Unlink static route from linked list. */
1710 if (si->prev)
1711 si->prev->next = si->next;
1712 else
1713 rn->info = si->next;
1714 if (si->next)
1715 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00001716 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001717
1718 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00001719 if (ifname)
1720 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00001721 XFREE (MTYPE_STATIC_IPV4, si);
1722
paul143a3852003-09-29 20:06:13 +00001723 route_unlock_node (rn);
1724
paul718e3742002-12-13 20:15:29 +00001725 return 1;
1726}
1727
1728
1729#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00001730static int
paul718e3742002-12-13 20:15:29 +00001731rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
1732 struct in6_addr *gate, unsigned int ifindex, int table)
1733{
hasso726f9b22003-05-25 21:04:54 +00001734 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
1735#if defined (MUSICA) || defined (LINUX)
1736 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
1737 if (p->prefixlen == 96)
1738 return 0;
1739#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00001740 return 1;
hasso726f9b22003-05-25 21:04:54 +00001741 }
paul718e3742002-12-13 20:15:29 +00001742 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
1743 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
1744 {
1745 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
1746 return 1;
1747 }
1748 return 0;
1749}
1750
1751int
1752rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00001753 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
1754 u_int32_t metric, u_char distance)
paul718e3742002-12-13 20:15:29 +00001755{
1756 struct rib *rib;
1757 struct rib *same = NULL;
1758 struct route_table *table;
1759 struct route_node *rn;
1760 struct nexthop *nexthop;
1761
paul718e3742002-12-13 20:15:29 +00001762 /* Lookup table. */
1763 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1764 if (! table)
1765 return 0;
1766
1767 /* Make sure mask is applied. */
1768 apply_mask_ipv6 (p);
1769
1770 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00001771 if (!distance)
1772 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00001773
1774 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1775 distance = 200;
1776
1777 /* Filter bogus route. */
1778 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
1779 return 0;
1780
1781 /* Lookup route node.*/
1782 rn = route_node_get (table, (struct prefix *) p);
1783
1784 /* If same type of route are installed, treat it as a implicit
1785 withdraw. */
1786 for (rib = rn->info; rib; rib = rib->next)
1787 {
1788 if (rib->type == ZEBRA_ROUTE_CONNECT)
1789 {
1790 nexthop = rib->nexthop;
1791
1792 if (rib->type == type
1793 && nexthop && nexthop->type == NEXTHOP_TYPE_IFINDEX
1794 && nexthop->ifindex == ifindex)
1795 {
1796 rib->refcnt++;
1797 return 0;
1798 }
1799 }
1800 else if (rib->type == type)
1801 {
1802 same = rib;
paul718e3742002-12-13 20:15:29 +00001803 break;
1804 }
1805 }
1806
1807 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001808 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
1809
paul718e3742002-12-13 20:15:29 +00001810 rib->type = type;
1811 rib->distance = distance;
1812 rib->flags = flags;
1813 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001814 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001815 rib->nexthop_num = 0;
1816 rib->uptime = time (NULL);
1817
1818 /* Nexthop settings. */
1819 if (gate)
1820 {
1821 if (ifindex)
1822 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
1823 else
1824 nexthop_ipv6_add (rib, gate);
1825 }
1826 else
1827 nexthop_ifindex_add (rib, ifindex);
1828
1829 /* If this route is kernel route, set FIB flag to the route. */
1830 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1831 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1832 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1833
1834 /* Link new rib to node.*/
1835 rib_addnode (rn, rib);
1836
1837 /* Process this route node. */
paul4d38fdb2005-04-28 17:35:14 +00001838 rib_queue_add (&zebrad, rn, same);
1839
paul718e3742002-12-13 20:15:29 +00001840 /* Free implicit route.*/
1841 if (same)
paul4d38fdb2005-04-28 17:35:14 +00001842 rib_delnode (rn, same);
1843
1844 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001845 return 0;
1846}
1847
1848int
1849rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
1850 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1851{
1852 struct route_table *table;
1853 struct route_node *rn;
1854 struct rib *rib;
1855 struct rib *fib = NULL;
1856 struct rib *same = NULL;
1857 struct nexthop *nexthop;
1858 char buf1[BUFSIZ];
1859 char buf2[BUFSIZ];
1860
1861 /* Apply mask. */
1862 apply_mask_ipv6 (p);
1863
1864 /* Lookup table. */
1865 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1866 if (! table)
1867 return 0;
paul4d38fdb2005-04-28 17:35:14 +00001868
paul718e3742002-12-13 20:15:29 +00001869 /* Lookup route node. */
1870 rn = route_node_lookup (table, (struct prefix *) p);
1871 if (! rn)
1872 {
1873 if (IS_ZEBRA_DEBUG_KERNEL)
1874 {
1875 if (gate)
ajsb6178002004-12-07 21:12:56 +00001876 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001877 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1878 p->prefixlen,
1879 inet_ntop (AF_INET6, gate, buf2, BUFSIZ),
1880 ifindex);
1881 else
ajsb6178002004-12-07 21:12:56 +00001882 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001883 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1884 p->prefixlen,
1885 ifindex);
1886 }
1887 return ZEBRA_ERR_RTNOEXIST;
1888 }
1889
1890 /* Lookup same type route. */
1891 for (rib = rn->info; rib; rib = rib->next)
1892 {
1893 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1894 fib = rib;
1895
1896 if (rib->type == ZEBRA_ROUTE_CONNECT)
1897 {
1898 nexthop = rib->nexthop;
1899
1900 if (rib->type == type
1901 && nexthop && nexthop->type == NEXTHOP_TYPE_IFINDEX
1902 && nexthop->ifindex == ifindex)
1903 {
1904 if (rib->refcnt)
1905 {
1906 rib->refcnt--;
1907 route_unlock_node (rn);
1908 route_unlock_node (rn);
1909 return 0;
1910 }
1911 same = rib;
1912 break;
1913 }
1914 }
1915 else
1916 {
1917 if (rib->type == type)
1918 {
1919 same = rib;
1920 break;
1921 }
1922 }
1923 }
1924
1925 /* If same type of route can't be found and this message is from
1926 kernel. */
1927 if (! same)
1928 {
1929 if (fib && type == ZEBRA_ROUTE_KERNEL)
1930 {
1931 /* Unset flags. */
1932 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1933 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1934
1935 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1936 }
1937 else
1938 {
1939 if (IS_ZEBRA_DEBUG_KERNEL)
1940 {
1941 if (gate)
ajsb6178002004-12-07 21:12:56 +00001942 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001943 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1944 p->prefixlen,
1945 inet_ntop (AF_INET6, gate, buf2, BUFSIZ),
1946 ifindex,
1947 type);
1948 else
ajsb6178002004-12-07 21:12:56 +00001949 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001950 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1951 p->prefixlen,
1952 ifindex,
1953 type);
1954 }
1955 route_unlock_node (rn);
1956 return ZEBRA_ERR_RTNOEXIST;
1957 }
1958 }
1959
paul4d38fdb2005-04-28 17:35:14 +00001960 /* Process changes. */
1961 rib_queue_add (&zebrad, rn, same);
1962
paul718e3742002-12-13 20:15:29 +00001963 if (same)
1964 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00001965
paul718e3742002-12-13 20:15:29 +00001966 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001967 return 0;
1968}
1969
1970/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00001971static void
paul718e3742002-12-13 20:15:29 +00001972static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
1973{
1974 struct rib *rib;
1975 struct route_table *table;
1976 struct route_node *rn;
1977
1978 /* Lookup table. */
1979 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1980 if (! table)
1981 return;
1982
1983 /* Lookup existing route */
1984 rn = route_node_get (table, p);
1985 for (rib = rn->info; rib; rib = rib->next)
1986 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1987 break;
1988
1989 if (rib)
1990 {
1991 /* Same distance static route is there. Update it with new
1992 nexthop. */
paul718e3742002-12-13 20:15:29 +00001993 route_unlock_node (rn);
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 }
paul4d38fdb2005-04-28 17:35:14 +00002007 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00002008 }
2009 else
2010 {
2011 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002012 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2013
paul718e3742002-12-13 20:15:29 +00002014 rib->type = ZEBRA_ROUTE_STATIC;
2015 rib->distance = si->distance;
2016 rib->metric = 0;
2017 rib->nexthop_num = 0;
2018
2019 switch (si->type)
2020 {
2021 case STATIC_IPV6_GATEWAY:
2022 nexthop_ipv6_add (rib, &si->ipv6);
2023 break;
2024 case STATIC_IPV6_IFNAME:
2025 nexthop_ifname_add (rib, si->ifname);
2026 break;
2027 case STATIC_IPV6_GATEWAY_IFNAME:
2028 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2029 break;
2030 }
2031
hasso81dfcaa2003-05-25 19:21:25 +00002032 /* Save the flags of this static routes (reject, blackhole) */
2033 rib->flags = si->flags;
2034
paul718e3742002-12-13 20:15:29 +00002035 /* Link this rib to the tree. */
2036 rib_addnode (rn, rib);
2037
2038 /* Process this prefix. */
paul4d38fdb2005-04-28 17:35:14 +00002039 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00002040 }
2041}
2042
paula1ac18c2005-06-28 17:17:12 +00002043static int
paul718e3742002-12-13 20:15:29 +00002044static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2045{
2046 if (nexthop->type == NEXTHOP_TYPE_IPV6
2047 && si->type == STATIC_IPV6_GATEWAY
2048 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2049 return 1;
2050 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2051 && si->type == STATIC_IPV6_IFNAME
2052 && strcmp (nexthop->ifname, si->ifname) == 0)
2053 return 1;
2054 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2055 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2056 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2057 && strcmp (nexthop->ifname, si->ifname) == 0)
2058 return 1;
2059 return 0;;
2060}
2061
paula1ac18c2005-06-28 17:17:12 +00002062static void
paul718e3742002-12-13 20:15:29 +00002063static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2064{
2065 struct route_table *table;
2066 struct route_node *rn;
2067 struct rib *rib;
2068 struct nexthop *nexthop;
2069
2070 /* Lookup table. */
2071 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2072 if (! table)
2073 return;
2074
2075 /* Lookup existing route with type and distance. */
2076 rn = route_node_lookup (table, (struct prefix *) p);
2077 if (! rn)
2078 return;
2079
2080 for (rib = rn->info; rib; rib = rib->next)
2081 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2082 break;
2083 if (! rib)
2084 {
2085 route_unlock_node (rn);
2086 return;
2087 }
2088
2089 /* Lookup nexthop. */
2090 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2091 if (static_ipv6_nexthop_same (nexthop, si))
2092 break;
2093
2094 /* Can't find nexthop. */
2095 if (! nexthop)
2096 {
2097 route_unlock_node (rn);
2098 return;
2099 }
2100
2101 /* Check nexthop. */
2102 if (rib->nexthop_num == 1)
2103 {
2104 rib_delnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00002105 rib_queue_add (&zebrad, rn, rib);
paul718e3742002-12-13 20:15:29 +00002106 }
2107 else
2108 {
paul6baeb982003-10-28 03:47:15 +00002109 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2110 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002111 nexthop_delete (rib, nexthop);
2112 nexthop_free (nexthop);
2113 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00002114 }
paul718e3742002-12-13 20:15:29 +00002115 /* Unlock node. */
2116 route_unlock_node (rn);
2117}
2118
2119/* Add static route into static route configuration. */
2120int
2121static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002122 const char *ifname, u_char flags, u_char distance,
2123 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002124{
2125 struct route_node *rn;
2126 struct static_ipv6 *si;
2127 struct static_ipv6 *pp;
2128 struct static_ipv6 *cp;
2129 struct route_table *stable;
2130
2131 /* Lookup table. */
2132 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2133 if (! stable)
2134 return -1;
2135
2136 /* Lookup static route prefix. */
2137 rn = route_node_get (stable, p);
2138
2139 /* Do nothing if there is a same static route. */
2140 for (si = rn->info; si; si = si->next)
2141 {
2142 if (distance == si->distance
2143 && type == si->type
2144 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2145 && (! ifname || strcmp (ifname, si->ifname) == 0))
2146 {
2147 route_unlock_node (rn);
2148 return 0;
2149 }
2150 }
2151
2152 /* Make new static route structure. */
2153 si = XMALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
2154 memset (si, 0, sizeof (struct static_ipv6));
2155
2156 si->type = type;
2157 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002158 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002159
2160 switch (type)
2161 {
2162 case STATIC_IPV6_GATEWAY:
2163 si->ipv6 = *gate;
2164 break;
2165 case STATIC_IPV6_IFNAME:
2166 si->ifname = XSTRDUP (0, ifname);
2167 break;
2168 case STATIC_IPV6_GATEWAY_IFNAME:
2169 si->ipv6 = *gate;
2170 si->ifname = XSTRDUP (0, ifname);
2171 break;
2172 }
2173
2174 /* Add new static route information to the tree with sort by
2175 distance value and gateway address. */
2176 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2177 {
2178 if (si->distance < cp->distance)
2179 break;
2180 if (si->distance > cp->distance)
2181 continue;
2182 }
2183
2184 /* Make linked list. */
2185 if (pp)
2186 pp->next = si;
2187 else
2188 rn->info = si;
2189 if (cp)
2190 cp->prev = si;
2191 si->prev = pp;
2192 si->next = cp;
2193
2194 /* Install into rib. */
2195 static_install_ipv6 (p, si);
2196
2197 return 1;
2198}
2199
2200/* Delete static route from static route configuration. */
2201int
2202static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002203 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002204{
2205 struct route_node *rn;
2206 struct static_ipv6 *si;
2207 struct route_table *stable;
2208
2209 /* Lookup table. */
2210 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2211 if (! stable)
2212 return -1;
2213
2214 /* Lookup static route prefix. */
2215 rn = route_node_lookup (stable, p);
2216 if (! rn)
2217 return 0;
2218
2219 /* Find same static route is the tree */
2220 for (si = rn->info; si; si = si->next)
2221 if (distance == si->distance
2222 && type == si->type
2223 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2224 && (! ifname || strcmp (ifname, si->ifname) == 0))
2225 break;
2226
2227 /* Can't find static route. */
2228 if (! si)
2229 {
2230 route_unlock_node (rn);
2231 return 0;
2232 }
2233
2234 /* Install into rib. */
2235 static_uninstall_ipv6 (p, si);
2236
2237 /* Unlink static route from linked list. */
2238 if (si->prev)
2239 si->prev->next = si->next;
2240 else
2241 rn->info = si->next;
2242 if (si->next)
2243 si->next->prev = si->prev;
2244
2245 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002246 if (ifname)
2247 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00002248 XFREE (MTYPE_STATIC_IPV6, si);
2249
2250 return 1;
2251}
2252#endif /* HAVE_IPV6 */
2253
2254/* RIB update function. */
2255void
paula1ac18c2005-06-28 17:17:12 +00002256rib_update (void)
paul718e3742002-12-13 20:15:29 +00002257{
2258 struct route_node *rn;
2259 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00002260
paul718e3742002-12-13 20:15:29 +00002261 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2262 if (table)
2263 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002264 if (rn->info)
2265 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00002266
2267 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2268 if (table)
2269 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002270 if (rn->info)
2271 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00002272}
2273
2274/* Interface goes up. */
paula1ac18c2005-06-28 17:17:12 +00002275static void
paul718e3742002-12-13 20:15:29 +00002276rib_if_up (struct interface *ifp)
2277{
2278 rib_update ();
2279}
2280
2281/* Interface goes down. */
paula1ac18c2005-06-28 17:17:12 +00002282static void
paul718e3742002-12-13 20:15:29 +00002283rib_if_down (struct interface *ifp)
2284{
2285 rib_update ();
2286}
2287
2288/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00002289static void
paul718e3742002-12-13 20:15:29 +00002290rib_weed_table (struct route_table *table)
2291{
2292 struct route_node *rn;
2293 struct rib *rib;
2294 struct rib *next;
2295
2296 if (table)
2297 for (rn = route_top (table); rn; rn = route_next (rn))
2298 for (rib = rn->info; rib; rib = next)
2299 {
2300 next = rib->next;
2301
paulb21b19c2003-06-15 01:28:29 +00002302 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00002303 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00002304 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002305 }
2306}
2307
2308/* Delete all routes from non main table. */
2309void
paula1ac18c2005-06-28 17:17:12 +00002310rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00002311{
2312 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2313 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2314}
2315
2316/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00002317static void
paul718e3742002-12-13 20:15:29 +00002318rib_sweep_table (struct route_table *table)
2319{
2320 struct route_node *rn;
2321 struct rib *rib;
2322 struct rib *next;
2323 int ret = 0;
2324
2325 if (table)
2326 for (rn = route_top (table); rn; rn = route_next (rn))
2327 for (rib = rn->info; rib; rib = next)
2328 {
2329 next = rib->next;
2330
2331 if (rib->type == ZEBRA_ROUTE_KERNEL &&
2332 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
2333 {
2334 ret = rib_uninstall_kernel (rn, rib);
2335 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00002336 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002337 }
2338 }
2339}
2340
2341/* Sweep all RIB tables. */
2342void
paula1ac18c2005-06-28 17:17:12 +00002343rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00002344{
2345 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2346 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2347}
2348
2349/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00002350static void
paul718e3742002-12-13 20:15:29 +00002351rib_close_table (struct route_table *table)
2352{
2353 struct route_node *rn;
2354 struct rib *rib;
2355
2356 if (table)
2357 for (rn = route_top (table); rn; rn = route_next (rn))
2358 for (rib = rn->info; rib; rib = rib->next)
2359 if (! RIB_SYSTEM_ROUTE (rib)
2360 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2361 rib_uninstall_kernel (rn, rib);
2362}
2363
2364/* Close all RIB tables. */
2365void
paula1ac18c2005-06-28 17:17:12 +00002366rib_close (void)
paul718e3742002-12-13 20:15:29 +00002367{
2368 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2369 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2370}
2371
2372/* Routing information base initialize. */
2373void
paula1ac18c2005-06-28 17:17:12 +00002374rib_init (void)
paul718e3742002-12-13 20:15:29 +00002375{
paul4d38fdb2005-04-28 17:35:14 +00002376 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00002377 /* VRF initialization. */
2378 vrf_init ();
2379}