blob: 5d9cb2f68cb842231c70c859d789bfb502e91e89 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* Routing Information Base.
2 * Copyright (C) 1997, 98, 99, 2001 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "prefix.h"
25#include "table.h"
26#include "memory.h"
27#include "str.h"
28#include "command.h"
29#include "if.h"
30#include "log.h"
31#include "sockunion.h"
paul4d38fdb2005-04-28 17:35:14 +000032#include "linklist.h"
33#include "thread.h"
34#include "workqueue.h"
paul718e3742002-12-13 20:15:29 +000035
36#include "zebra/rib.h"
37#include "zebra/rt.h"
38#include "zebra/zserv.h"
39#include "zebra/redistribute.h"
40#include "zebra/debug.h"
41
42/* Default rtm_table for all clients */
paulb21b19c2003-06-15 01:28:29 +000043extern struct zebra_t zebrad;
paul718e3742002-12-13 20:15:29 +000044
45/* Each route type's string and default distance value. */
46struct
47{
48 int key;
49 int distance;
50} route_info[] =
51{
52 {ZEBRA_ROUTE_SYSTEM, 0},
53 {ZEBRA_ROUTE_KERNEL, 0},
54 {ZEBRA_ROUTE_CONNECT, 0},
55 {ZEBRA_ROUTE_STATIC, 1},
56 {ZEBRA_ROUTE_RIP, 120},
57 {ZEBRA_ROUTE_RIPNG, 120},
58 {ZEBRA_ROUTE_OSPF, 110},
59 {ZEBRA_ROUTE_OSPF6, 110},
jardin9e867fe2003-12-23 08:56:18 +000060 {ZEBRA_ROUTE_ISIS, 115},
paul718e3742002-12-13 20:15:29 +000061 {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */}
62};
paul4d38fdb2005-04-28 17:35:14 +000063
64struct zebra_queue_node_t
65{
66 struct route_node *node;
67 struct rib *del;
68};
paul718e3742002-12-13 20:15:29 +000069
70/* Vector for routing table. */
71vector vrf_vector;
72
73/* Allocate new VRF. */
paula1ac18c2005-06-28 17:17:12 +000074static struct vrf *
hassofce954f2004-10-07 20:29:24 +000075vrf_alloc (const char *name)
paul718e3742002-12-13 20:15:29 +000076{
77 struct vrf *vrf;
78
79 vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
80
81 /* Put name. */
82 if (name)
83 vrf->name = XSTRDUP (MTYPE_VRF_NAME, name);
84
85 /* Allocate routing table and static table. */
86 vrf->table[AFI_IP][SAFI_UNICAST] = route_table_init ();
87 vrf->table[AFI_IP6][SAFI_UNICAST] = route_table_init ();
88 vrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
89 vrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
90
91 return vrf;
92}
93
94/* Free VRF. */
paula1ac18c2005-06-28 17:17:12 +000095static void
paul718e3742002-12-13 20:15:29 +000096vrf_free (struct vrf *vrf)
97{
98 if (vrf->name)
99 XFREE (MTYPE_VRF_NAME, vrf->name);
100 XFREE (MTYPE_VRF, vrf);
101}
102
103/* Lookup VRF by identifier. */
104struct vrf *
105vrf_lookup (u_int32_t id)
106{
107 return vector_lookup (vrf_vector, id);
108}
109
110/* Lookup VRF by name. */
paula1ac18c2005-06-28 17:17:12 +0000111static struct vrf *
paul718e3742002-12-13 20:15:29 +0000112vrf_lookup_by_name (char *name)
113{
hassofce954f2004-10-07 20:29:24 +0000114 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000115 struct vrf *vrf;
116
paul55468c82005-03-14 20:19:01 +0000117 for (i = 0; i < vector_active (vrf_vector); i++)
paul718e3742002-12-13 20:15:29 +0000118 if ((vrf = vector_slot (vrf_vector, i)) != NULL)
119 if (vrf->name && name && strcmp (vrf->name, name) == 0)
120 return vrf;
121 return NULL;
122}
123
124/* Initialize VRF. */
paula1ac18c2005-06-28 17:17:12 +0000125static void
126vrf_init (void)
paul718e3742002-12-13 20:15:29 +0000127{
128 struct vrf *default_table;
129
130 /* Allocate VRF vector. */
131 vrf_vector = vector_init (1);
132
133 /* Allocate default main table. */
134 default_table = vrf_alloc ("Default-IP-Routing-Table");
135
136 /* Default table index must be 0. */
137 vector_set_index (vrf_vector, 0, default_table);
138}
139
140/* Lookup route table. */
141struct route_table *
142vrf_table (afi_t afi, safi_t safi, u_int32_t id)
143{
144 struct vrf *vrf;
145
146 vrf = vrf_lookup (id);
147 if (! vrf)
148 return NULL;
149
150 return vrf->table[afi][safi];
151}
152
153/* Lookup static route table. */
154struct route_table *
155vrf_static_table (afi_t afi, safi_t safi, u_int32_t id)
156{
157 struct vrf *vrf;
158
159 vrf = vrf_lookup (id);
160 if (! vrf)
161 return NULL;
162
163 return vrf->stable[afi][safi];
164}
165
166/* Add nexthop to the end of the list. */
paula1ac18c2005-06-28 17:17:12 +0000167static void
paul718e3742002-12-13 20:15:29 +0000168nexthop_add (struct rib *rib, struct nexthop *nexthop)
169{
170 struct nexthop *last;
171
172 for (last = rib->nexthop; last && last->next; last = last->next)
173 ;
174 if (last)
175 last->next = nexthop;
176 else
177 rib->nexthop = nexthop;
178 nexthop->prev = last;
179
180 rib->nexthop_num++;
181}
182
183/* Delete specified nexthop from the list. */
paula1ac18c2005-06-28 17:17:12 +0000184static void
paul718e3742002-12-13 20:15:29 +0000185nexthop_delete (struct rib *rib, struct nexthop *nexthop)
186{
187 if (nexthop->next)
188 nexthop->next->prev = nexthop->prev;
189 if (nexthop->prev)
190 nexthop->prev->next = nexthop->next;
191 else
192 rib->nexthop = nexthop->next;
193 rib->nexthop_num--;
194}
195
196/* Free nexthop. */
paula1ac18c2005-06-28 17:17:12 +0000197static void
paul718e3742002-12-13 20:15:29 +0000198nexthop_free (struct nexthop *nexthop)
199{
paula4b70762003-05-16 17:19:48 +0000200 if (nexthop->ifname)
201 XFREE (0, nexthop->ifname);
paul718e3742002-12-13 20:15:29 +0000202 XFREE (MTYPE_NEXTHOP, nexthop);
203}
204
205struct nexthop *
206nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
207{
208 struct nexthop *nexthop;
209
210 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
211 memset (nexthop, 0, sizeof (struct nexthop));
212 nexthop->type = NEXTHOP_TYPE_IFINDEX;
213 nexthop->ifindex = ifindex;
214
215 nexthop_add (rib, nexthop);
216
217 return nexthop;
218}
219
220struct nexthop *
221nexthop_ifname_add (struct rib *rib, char *ifname)
222{
223 struct nexthop *nexthop;
224
225 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
226 memset (nexthop, 0, sizeof (struct nexthop));
227 nexthop->type = NEXTHOP_TYPE_IFNAME;
paula4b70762003-05-16 17:19:48 +0000228 nexthop->ifname = XSTRDUP (0, ifname);
paul718e3742002-12-13 20:15:29 +0000229
230 nexthop_add (rib, nexthop);
231
232 return nexthop;
233}
234
235struct nexthop *
236nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4)
237{
238 struct nexthop *nexthop;
239
240 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
241 memset (nexthop, 0, sizeof (struct nexthop));
242 nexthop->type = NEXTHOP_TYPE_IPV4;
243 nexthop->gate.ipv4 = *ipv4;
244
245 nexthop_add (rib, nexthop);
246
247 return nexthop;
248}
249
paula1ac18c2005-06-28 17:17:12 +0000250static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000251nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
252 unsigned int ifindex)
253{
254 struct nexthop *nexthop;
255
256 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
257 memset (nexthop, 0, sizeof (struct nexthop));
258 nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
259 nexthop->gate.ipv4 = *ipv4;
260 nexthop->ifindex = ifindex;
261
262 nexthop_add (rib, nexthop);
263
264 return nexthop;
265}
266
267#ifdef HAVE_IPV6
268struct nexthop *
269nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
270{
271 struct nexthop *nexthop;
272
273 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
274 memset (nexthop, 0, sizeof (struct nexthop));
275 nexthop->type = NEXTHOP_TYPE_IPV6;
276 nexthop->gate.ipv6 = *ipv6;
277
278 nexthop_add (rib, nexthop);
279
280 return nexthop;
281}
282
paula1ac18c2005-06-28 17:17:12 +0000283static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000284nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
285 char *ifname)
286{
287 struct nexthop *nexthop;
288
289 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
290 memset (nexthop, 0, sizeof (struct nexthop));
291 nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
292 nexthop->gate.ipv6 = *ipv6;
293 nexthop->ifname = XSTRDUP (0, ifname);
294
295 nexthop_add (rib, nexthop);
296
297 return nexthop;
298}
299
paula1ac18c2005-06-28 17:17:12 +0000300static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000301nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
302 unsigned int ifindex)
303{
304 struct nexthop *nexthop;
305
306 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
307 memset (nexthop, 0, sizeof (struct nexthop));
308 nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
309 nexthop->gate.ipv6 = *ipv6;
310 nexthop->ifindex = ifindex;
311
312 nexthop_add (rib, nexthop);
313
314 return nexthop;
315}
316#endif /* HAVE_IPV6 */
317
paul595db7f2003-05-25 21:35:06 +0000318struct nexthop *
319nexthop_blackhole_add (struct rib *rib)
320{
321 struct nexthop *nexthop;
322
323 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
324 memset (nexthop, 0, sizeof (struct nexthop));
325 nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
326 SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
327
328 nexthop_add (rib, nexthop);
329
330 return nexthop;
331}
332
paul718e3742002-12-13 20:15:29 +0000333/* If force flag is not set, do not modify falgs at all for uninstall
334 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000335static int
paul718e3742002-12-13 20:15:29 +0000336nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
337 struct route_node *top)
338{
339 struct prefix_ipv4 p;
340 struct route_table *table;
341 struct route_node *rn;
342 struct rib *match;
343 struct nexthop *newhop;
344
345 if (nexthop->type == NEXTHOP_TYPE_IPV4)
346 nexthop->ifindex = 0;
347
348 if (set)
349 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
350
351 /* Make lookup prefix. */
352 memset (&p, 0, sizeof (struct prefix_ipv4));
353 p.family = AF_INET;
354 p.prefixlen = IPV4_MAX_PREFIXLEN;
355 p.prefix = nexthop->gate.ipv4;
356
357 /* Lookup table. */
358 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
359 if (! table)
360 return 0;
361
362 rn = route_node_match (table, (struct prefix *) &p);
363 while (rn)
364 {
365 route_unlock_node (rn);
366
367 /* If lookup self prefix return immidiately. */
368 if (rn == top)
369 return 0;
370
371 /* Pick up selected route. */
372 for (match = rn->info; match; match = match->next)
373 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
374 break;
375
376 /* If there is no selected route or matched route is EGP, go up
377 tree. */
378 if (! match
379 || match->type == ZEBRA_ROUTE_BGP)
380 {
381 do {
382 rn = rn->parent;
383 } while (rn && rn->info == NULL);
384 if (rn)
385 route_lock_node (rn);
386 }
387 else
388 {
389 if (match->type == ZEBRA_ROUTE_CONNECT)
390 {
391 /* Directly point connected route. */
392 newhop = match->nexthop;
393 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
394 nexthop->ifindex = newhop->ifindex;
395
396 return 1;
397 }
398 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
399 {
400 for (newhop = match->nexthop; newhop; newhop = newhop->next)
401 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
402 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
403 {
404 if (set)
405 {
406 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
407 nexthop->rtype = newhop->type;
408 if (newhop->type == NEXTHOP_TYPE_IPV4 ||
409 newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
410 nexthop->rgate.ipv4 = newhop->gate.ipv4;
411 if (newhop->type == NEXTHOP_TYPE_IFINDEX
412 || newhop->type == NEXTHOP_TYPE_IFNAME
413 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
414 nexthop->rifindex = newhop->ifindex;
415 }
416 return 1;
417 }
418 return 0;
419 }
420 else
421 {
422 return 0;
423 }
424 }
425 }
426 return 0;
427}
428
429#ifdef HAVE_IPV6
430/* If force flag is not set, do not modify falgs at all for uninstall
431 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000432static int
paul718e3742002-12-13 20:15:29 +0000433nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
434 struct route_node *top)
435{
436 struct prefix_ipv6 p;
437 struct route_table *table;
438 struct route_node *rn;
439 struct rib *match;
440 struct nexthop *newhop;
441
442 if (nexthop->type == NEXTHOP_TYPE_IPV6)
443 nexthop->ifindex = 0;
444
445 if (set)
446 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
447
448 /* Make lookup prefix. */
449 memset (&p, 0, sizeof (struct prefix_ipv6));
450 p.family = AF_INET6;
451 p.prefixlen = IPV6_MAX_PREFIXLEN;
452 p.prefix = nexthop->gate.ipv6;
453
454 /* Lookup table. */
455 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
456 if (! table)
457 return 0;
458
459 rn = route_node_match (table, (struct prefix *) &p);
460 while (rn)
461 {
462 route_unlock_node (rn);
463
464 /* If lookup self prefix return immidiately. */
465 if (rn == top)
466 return 0;
467
468 /* Pick up selected route. */
469 for (match = rn->info; match; match = match->next)
470 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
471 break;
472
473 /* If there is no selected route or matched route is EGP, go up
474 tree. */
475 if (! match
476 || match->type == ZEBRA_ROUTE_BGP)
477 {
478 do {
479 rn = rn->parent;
480 } while (rn && rn->info == NULL);
481 if (rn)
482 route_lock_node (rn);
483 }
484 else
485 {
486 if (match->type == ZEBRA_ROUTE_CONNECT)
487 {
488 /* Directly point connected route. */
489 newhop = match->nexthop;
490
491 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
492 nexthop->ifindex = newhop->ifindex;
493
494 return 1;
495 }
496 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
497 {
498 for (newhop = match->nexthop; newhop; newhop = newhop->next)
499 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
500 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
501 {
502 if (set)
503 {
504 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
505 nexthop->rtype = newhop->type;
506 if (newhop->type == NEXTHOP_TYPE_IPV6
507 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
508 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
509 nexthop->rgate.ipv6 = newhop->gate.ipv6;
510 if (newhop->type == NEXTHOP_TYPE_IFINDEX
511 || newhop->type == NEXTHOP_TYPE_IFNAME
512 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
513 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
514 nexthop->rifindex = newhop->ifindex;
515 }
516 return 1;
517 }
518 return 0;
519 }
520 else
521 {
522 return 0;
523 }
524 }
525 }
526 return 0;
527}
528#endif /* HAVE_IPV6 */
529
530struct rib *
531rib_match_ipv4 (struct in_addr addr)
532{
533 struct prefix_ipv4 p;
534 struct route_table *table;
535 struct route_node *rn;
536 struct rib *match;
537 struct nexthop *newhop;
538
539 /* Lookup table. */
540 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
541 if (! table)
542 return 0;
543
544 memset (&p, 0, sizeof (struct prefix_ipv4));
545 p.family = AF_INET;
546 p.prefixlen = IPV4_MAX_PREFIXLEN;
547 p.prefix = addr;
548
549 rn = route_node_match (table, (struct prefix *) &p);
550
551 while (rn)
552 {
553 route_unlock_node (rn);
554
555 /* Pick up selected route. */
556 for (match = rn->info; match; match = match->next)
557 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
558 break;
559
560 /* If there is no selected route or matched route is EGP, go up
561 tree. */
562 if (! match
563 || match->type == ZEBRA_ROUTE_BGP)
564 {
565 do {
566 rn = rn->parent;
567 } while (rn && rn->info == NULL);
568 if (rn)
569 route_lock_node (rn);
570 }
571 else
572 {
573 if (match->type == ZEBRA_ROUTE_CONNECT)
574 /* Directly point connected route. */
575 return match;
576 else
577 {
578 for (newhop = match->nexthop; newhop; newhop = newhop->next)
579 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
580 return match;
581 return NULL;
582 }
583 }
584 }
585 return NULL;
586}
587
588struct rib *
589rib_lookup_ipv4 (struct prefix_ipv4 *p)
590{
591 struct route_table *table;
592 struct route_node *rn;
593 struct rib *match;
594 struct nexthop *nexthop;
595
596 /* Lookup table. */
597 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
598 if (! table)
599 return 0;
600
601 rn = route_node_lookup (table, (struct prefix *) p);
602
603 /* No route for this prefix. */
604 if (! rn)
605 return NULL;
606
607 /* Unlock node. */
608 route_unlock_node (rn);
609
610 /* Pick up selected route. */
611 for (match = rn->info; match; match = match->next)
612 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
613 break;
614
615 if (! match || match->type == ZEBRA_ROUTE_BGP)
616 return NULL;
617
618 if (match->type == ZEBRA_ROUTE_CONNECT)
619 return match;
620
621 for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
622 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
623 return match;
624
625 return NULL;
626}
627
628#ifdef HAVE_IPV6
629struct rib *
630rib_match_ipv6 (struct in6_addr *addr)
631{
632 struct prefix_ipv6 p;
633 struct route_table *table;
634 struct route_node *rn;
635 struct rib *match;
636 struct nexthop *newhop;
637
638 /* Lookup table. */
639 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
640 if (! table)
641 return 0;
642
643 memset (&p, 0, sizeof (struct prefix_ipv6));
644 p.family = AF_INET6;
645 p.prefixlen = IPV6_MAX_PREFIXLEN;
646 IPV6_ADDR_COPY (&p.prefix, addr);
647
648 rn = route_node_match (table, (struct prefix *) &p);
649
650 while (rn)
651 {
652 route_unlock_node (rn);
653
654 /* Pick up selected route. */
655 for (match = rn->info; match; match = match->next)
656 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
657 break;
658
659 /* If there is no selected route or matched route is EGP, go up
660 tree. */
661 if (! match
662 || match->type == ZEBRA_ROUTE_BGP)
663 {
664 do {
665 rn = rn->parent;
666 } while (rn && rn->info == NULL);
667 if (rn)
668 route_lock_node (rn);
669 }
670 else
671 {
672 if (match->type == ZEBRA_ROUTE_CONNECT)
673 /* Directly point connected route. */
674 return match;
675 else
676 {
677 for (newhop = match->nexthop; newhop; newhop = newhop->next)
678 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
679 return match;
680 return NULL;
681 }
682 }
683 }
684 return NULL;
685}
686#endif /* HAVE_IPV6 */
687
paula1ac18c2005-06-28 17:17:12 +0000688static int
paul718e3742002-12-13 20:15:29 +0000689nexthop_active_check (struct route_node *rn, struct rib *rib,
690 struct nexthop *nexthop, int set)
691{
692 struct interface *ifp;
693
694 switch (nexthop->type)
695 {
696 case NEXTHOP_TYPE_IFINDEX:
697 ifp = if_lookup_by_index (nexthop->ifindex);
698 if (ifp && if_is_up (ifp))
699 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
700 else
701 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
702 break;
703 case NEXTHOP_TYPE_IFNAME:
704 case NEXTHOP_TYPE_IPV6_IFNAME:
705 ifp = if_lookup_by_name (nexthop->ifname);
706 if (ifp && if_is_up (ifp))
707 {
708 if (set)
709 nexthop->ifindex = ifp->ifindex;
710 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
711 }
712 else
713 {
714 if (set)
715 nexthop->ifindex = 0;
716 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
717 }
718 break;
719 case NEXTHOP_TYPE_IPV4:
720 case NEXTHOP_TYPE_IPV4_IFINDEX:
721 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
722 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
723 else
724 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
725 break;
726#ifdef HAVE_IPV6
727 case NEXTHOP_TYPE_IPV6:
728 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
729 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
730 else
731 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
732 break;
733 case NEXTHOP_TYPE_IPV6_IFINDEX:
734 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
735 {
736 ifp = if_lookup_by_index (nexthop->ifindex);
737 if (ifp && if_is_up (ifp))
738 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
739 else
740 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
741 }
742 else
743 {
744 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
745 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
746 else
747 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
748 }
749 break;
750#endif /* HAVE_IPV6 */
paul595db7f2003-05-25 21:35:06 +0000751 case NEXTHOP_TYPE_BLACKHOLE:
752 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
753 break;
paul718e3742002-12-13 20:15:29 +0000754 default:
755 break;
756 }
757 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
758}
759
paula1ac18c2005-06-28 17:17:12 +0000760static int
paul718e3742002-12-13 20:15:29 +0000761nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
762{
763 struct nexthop *nexthop;
764 int active;
765
766 rib->nexthop_active_num = 0;
767 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
768
769 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
770 {
771 active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
paul6baeb982003-10-28 03:47:15 +0000772
773 nexthop_active_check (rn, rib, nexthop, set);
774 if ((MULTIPATH_NUM == 0 || rib->nexthop_active_num < MULTIPATH_NUM)
775 && active != CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
776 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
777
778 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
779 rib->nexthop_active_num++;
paul718e3742002-12-13 20:15:29 +0000780 }
781 return rib->nexthop_active_num;
782}
paul6baeb982003-10-28 03:47:15 +0000783
paul718e3742002-12-13 20:15:29 +0000784
785#define RIB_SYSTEM_ROUTE(R) \
786 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
787
paul4d38fdb2005-04-28 17:35:14 +0000788static struct rib *
789rib_lock (struct rib *rib)
790{
791 assert (rib->lock >= 0);
792
793 rib->lock++;
794 return rib;
795}
796
797static struct rib *
798rib_unlock (struct rib *rib)
paul718e3742002-12-13 20:15:29 +0000799{
800 struct nexthop *nexthop;
801 struct nexthop *next;
paul4d38fdb2005-04-28 17:35:14 +0000802
803 assert (rib->lock > 0);
804 rib->lock--;
paul718e3742002-12-13 20:15:29 +0000805
paul4d38fdb2005-04-28 17:35:14 +0000806 if (rib->lock == 0)
paul718e3742002-12-13 20:15:29 +0000807 {
paul4d38fdb2005-04-28 17:35:14 +0000808 for (nexthop = rib->nexthop; nexthop; nexthop = next)
809 {
810 next = nexthop->next;
811 nexthop_free (nexthop);
812 }
813 XFREE (MTYPE_RIB, rib);
814 return NULL;
paul718e3742002-12-13 20:15:29 +0000815 }
paul4d38fdb2005-04-28 17:35:14 +0000816 return rib;
paul718e3742002-12-13 20:15:29 +0000817}
818
paula1ac18c2005-06-28 17:17:12 +0000819static void
paul718e3742002-12-13 20:15:29 +0000820rib_install_kernel (struct route_node *rn, struct rib *rib)
821{
822 int ret = 0;
823 struct nexthop *nexthop;
824
825 switch (PREFIX_FAMILY (&rn->p))
826 {
827 case AF_INET:
828 ret = kernel_add_ipv4 (&rn->p, rib);
829 break;
830#ifdef HAVE_IPV6
831 case AF_INET6:
832 ret = kernel_add_ipv6 (&rn->p, rib);
833 break;
834#endif /* HAVE_IPV6 */
835 }
836
837 if (ret < 0)
838 {
839 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
840 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
841 }
842}
843
844/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +0000845static int
paul718e3742002-12-13 20:15:29 +0000846rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
847{
848 int ret = 0;
849 struct nexthop *nexthop;
850
851 switch (PREFIX_FAMILY (&rn->p))
852 {
853 case AF_INET:
854 ret = kernel_delete_ipv4 (&rn->p, rib);
855 break;
856#ifdef HAVE_IPV6
857 case AF_INET6:
858 ret = kernel_delete_ipv6 (&rn->p, rib);
859 break;
860#endif /* HAVE_IPV6 */
861 }
862
863 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
864 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
865
866 return ret;
867}
868
869/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +0000870static void
paul718e3742002-12-13 20:15:29 +0000871rib_uninstall (struct route_node *rn, struct rib *rib)
872{
873 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
874 {
875 redistribute_delete (&rn->p, rib);
876 if (! RIB_SYSTEM_ROUTE (rib))
877 rib_uninstall_kernel (rn, rib);
878 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
879 }
880}
881
882/* Core function for processing routing information base. */
paula1ac18c2005-06-28 17:17:12 +0000883static wq_item_status
paul0fb58d52005-11-14 14:31:49 +0000884rib_process (struct work_queue *wq, void *data)
paul718e3742002-12-13 20:15:29 +0000885{
paul0fb58d52005-11-14 14:31:49 +0000886 struct zebra_queue_node_t *qnode = data;
paul718e3742002-12-13 20:15:29 +0000887 struct rib *rib;
888 struct rib *next;
889 struct rib *fib = NULL;
890 struct rib *select = NULL;
paul4d38fdb2005-04-28 17:35:14 +0000891 struct rib *del = qnode->del;
892 struct route_node *rn = qnode->node;
pauld753e9e2003-01-22 19:45:50 +0000893 int installed = 0;
894 struct nexthop *nexthop = NULL;
paul4d38fdb2005-04-28 17:35:14 +0000895
896 assert (rn);
897
898 /* possibly should lock and unlock rib on each iteration. however, for
899 * now, we assume called functions are synchronous and dont delete RIBs
900 * (as the work-queue deconstructor for this function is supposed to be
901 * the canonical 'delete' path for RIBs). Further if called functions
902 * below were to made asynchronous they should themselves acquire any
903 * locks/refcounts as needed and not depend on this caller to do it for
904 * them
905 */
paul718e3742002-12-13 20:15:29 +0000906 for (rib = rn->info; rib; rib = next)
907 {
908 next = rib->next;
pauld753e9e2003-01-22 19:45:50 +0000909
paul718e3742002-12-13 20:15:29 +0000910 /* Currently installed rib. */
911 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
paul7021c422003-07-15 12:52:22 +0000912 fib = rib;
paul4d38fdb2005-04-28 17:35:14 +0000913
paul718e3742002-12-13 20:15:29 +0000914 /* Skip unreachable nexthop. */
915 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +0000916 continue;
paul718e3742002-12-13 20:15:29 +0000917
918 /* Infinit distance. */
919 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +0000920 continue;
paul718e3742002-12-13 20:15:29 +0000921
paulaf887b52006-01-18 14:52:52 +0000922 /* Newly selected rib, the common case. */
923 if (!select)
924 {
925 select = rib;
926 continue;
927 }
928
929 /* filter route selection in following order:
930 * - lower distance beats higher
931 * - connected beats other types
932 * - lower metric beats higher for equal distance
933 * - last, hence oldest, route wins tie break.
934 */
935 if ((rib->type == ZEBRA_ROUTE_CONNECT)
936 || (rib->distance <= select->distance))
937 if (rib->metric <= select->metric)
938 select = rib;
paul718e3742002-12-13 20:15:29 +0000939 }
paul4d38fdb2005-04-28 17:35:14 +0000940
paul718e3742002-12-13 20:15:29 +0000941 /* Deleted route check. */
942 if (del && CHECK_FLAG (del->flags, ZEBRA_FLAG_SELECTED))
943 fib = del;
paul4d38fdb2005-04-28 17:35:14 +0000944
945 /* We possibly should lock fib and select here However, all functions
946 * below are 'inline' and not asynchronous And if any were to be
947 * converted, they should manage references themselves really.. See
948 * previous comment above.
949 */
950
paul718e3742002-12-13 20:15:29 +0000951 /* Same route is selected. */
952 if (select && select == fib)
953 {
954 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +0000955 {
956 redistribute_delete (&rn->p, select);
957 if (! RIB_SYSTEM_ROUTE (select))
958 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +0000959
paul4d38fdb2005-04-28 17:35:14 +0000960 /* Set real nexthop. */
961 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +0000962
paul4d38fdb2005-04-28 17:35:14 +0000963 if (! RIB_SYSTEM_ROUTE (select))
964 rib_install_kernel (rn, select);
965 redistribute_add (&rn->p, select);
966 }
pauld753e9e2003-01-22 19:45:50 +0000967 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +0000968 {
969 /* Housekeeping code to deal with
970 race conditions in kernel with linux
971 netlink reporting interface up before IPv4 or IPv6 protocol
972 is ready to add routes.
973 This makes sure the routes are IN the kernel.
974 */
pauld753e9e2003-01-22 19:45:50 +0000975
paul4d38fdb2005-04-28 17:35:14 +0000976 for (nexthop = select->nexthop; nexthop; nexthop = nexthop->next)
977 {
978 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
979 installed = 1;
980 }
981 if (! installed)
982 rib_install_kernel (rn, select);
983 }
984 return WQ_SUCCESS;
paul718e3742002-12-13 20:15:29 +0000985 }
986
987 /* Uninstall old rib from forwarding table. */
988 if (fib)
989 {
990 redistribute_delete (&rn->p, fib);
991 if (! RIB_SYSTEM_ROUTE (fib))
992 rib_uninstall_kernel (rn, fib);
993 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
994
995 /* Set real nexthop. */
996 nexthop_active_update (rn, fib, 1);
997 }
998
999 /* Install new rib into forwarding table. */
1000 if (select)
1001 {
1002 /* Set real nexthop. */
1003 nexthop_active_update (rn, select, 1);
1004
1005 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001006 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001007 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1008 redistribute_add (&rn->p, select);
1009 }
paul4d38fdb2005-04-28 17:35:14 +00001010
1011 return WQ_SUCCESS;
1012
1013}
1014
1015/* Add work queue item to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001016static void
paul4d38fdb2005-04-28 17:35:14 +00001017rib_queue_add_qnode (struct zebra_t *zebra, struct zebra_queue_node_t *qnode)
1018{
1019 route_lock_node (qnode->node);
1020
1021 if (IS_ZEBRA_DEBUG_EVENT)
1022 zlog_info ("rib_queue_add_qnode: work queue added");
1023
1024 assert (zebra && qnode && qnode->node);
1025
1026 if (qnode->del)
1027 rib_lock (qnode->del);
1028
1029 if (zebra->ribq == NULL)
1030 {
1031 zlog_err ("rib_queue_add_qnode: ribq work_queue does not exist!");
1032 route_unlock_node (qnode->node);
1033 return;
1034 }
1035
1036 work_queue_add (zebra->ribq, qnode);
1037
1038 return;
1039}
1040
1041/* Add route node and rib to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001042static void
paul4d38fdb2005-04-28 17:35:14 +00001043rib_queue_add (struct zebra_t *zebra, struct route_node *rn, struct rib *del)
1044{
1045 struct zebra_queue_node_t *qnode;
1046
1047 assert (zebra && rn);
1048
1049 qnode = (struct zebra_queue_node_t *)
1050 XCALLOC (MTYPE_RIB_QUEUE, sizeof (struct zebra_queue_node_t));
1051
1052 if (qnode == NULL)
1053 {
1054 zlog_err ("rib_queue_add: failed to allocate queue node memory, %s",
1055 strerror (errno));
1056 return;
1057 }
1058
1059 qnode->node = rn;
1060 qnode->del = del;
1061
1062 rib_queue_add_qnode (zebra, qnode);
1063
1064 return;
1065}
1066
1067/* free zebra_queue_node_t */
paula1ac18c2005-06-28 17:17:12 +00001068static void
paul0fb58d52005-11-14 14:31:49 +00001069rib_queue_qnode_del (struct work_queue *wq, void *data)
paul4d38fdb2005-04-28 17:35:14 +00001070{
paul0fb58d52005-11-14 14:31:49 +00001071 struct zebra_queue_node_t *qnode = data;
paul4d38fdb2005-04-28 17:35:14 +00001072 route_unlock_node (qnode->node);
1073
1074 if (qnode->del)
1075 rib_unlock (qnode->del);
1076
1077 XFREE (MTYPE_RIB_QUEUE, qnode);
1078}
1079
1080/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001081static void
paul4d38fdb2005-04-28 17:35:14 +00001082rib_queue_init (struct zebra_t *zebra)
1083{
1084 assert (zebra);
1085
1086 if (! (zebra->ribq = work_queue_new (zebra->master,
1087 "zebra_rib_work_queue")))
1088 {
1089 zlog_err ("rib_queue_init: could not initialise work queue!");
1090 return;
1091 }
1092
1093 /* fill in the work queue spec */
paul0fb58d52005-11-14 14:31:49 +00001094 zebra->ribq->spec.workfunc = &rib_process;
paul4d38fdb2005-04-28 17:35:14 +00001095 zebra->ribq->spec.errorfunc = NULL;
paul0fb58d52005-11-14 14:31:49 +00001096 zebra->ribq->spec.del_item_data = &rib_queue_qnode_del;
paul4d38fdb2005-04-28 17:35:14 +00001097 /* XXX: TODO: These should be runtime configurable via vty */
1098 zebra->ribq->spec.max_retries = 3;
paul4d38fdb2005-04-28 17:35:14 +00001099
1100 return;
paul718e3742002-12-13 20:15:29 +00001101}
1102
1103/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001104static void
paul718e3742002-12-13 20:15:29 +00001105rib_addnode (struct route_node *rn, struct rib *rib)
1106{
1107 struct rib *head;
paul4d38fdb2005-04-28 17:35:14 +00001108
1109 assert (rib && rn);
1110
1111 rib_lock (rib);
1112 route_lock_node (rn);
1113
paul718e3742002-12-13 20:15:29 +00001114 head = rn->info;
1115 if (head)
1116 head->prev = rib;
1117 rib->next = head;
1118 rn->info = rib;
1119}
1120
paula1ac18c2005-06-28 17:17:12 +00001121static void
paul718e3742002-12-13 20:15:29 +00001122rib_delnode (struct route_node *rn, struct rib *rib)
1123{
paul4d38fdb2005-04-28 17:35:14 +00001124 assert (rn && rib);
1125
paul718e3742002-12-13 20:15:29 +00001126 if (rib->next)
1127 rib->next->prev = rib->prev;
1128 if (rib->prev)
1129 rib->prev->next = rib->next;
1130 else
1131 rn->info = rib->next;
paul4d38fdb2005-04-28 17:35:14 +00001132
1133 rib_unlock (rib);
1134 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001135}
1136
1137int
1138rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
1139 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
1140 u_int32_t metric, u_char distance)
1141{
1142 struct rib *rib;
1143 struct rib *same = NULL;
1144 struct route_table *table;
1145 struct route_node *rn;
1146 struct nexthop *nexthop;
1147
1148 /* Lookup table. */
1149 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1150 if (! table)
1151 return 0;
1152
1153 /* Make it sure prefixlen is applied to the prefix. */
1154 apply_mask_ipv4 (p);
1155
1156 /* Set default distance by route type. */
1157 if (distance == 0)
1158 {
1159 distance = route_info[type].distance;
1160
1161 /* iBGP distance is 200. */
1162 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1163 distance = 200;
1164 }
1165
1166 /* Lookup route node.*/
1167 rn = route_node_get (table, (struct prefix *) p);
1168
1169 /* If same type of route are installed, treat it as a implicit
1170 withdraw. */
1171 for (rib = rn->info; rib; rib = rib->next)
1172 {
hassoebf1ead2005-09-21 14:58:20 +00001173 if (rib->type != type)
1174 continue;
1175 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001176 {
1177 same = rib;
1178 break;
1179 }
hassoebf1ead2005-09-21 14:58:20 +00001180 /* Duplicate connected route comes in. */
1181 else if ((nexthop = rib->nexthop) &&
1182 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
1183 nexthop->ifindex == ifindex)
1184 {
1185 rib->refcnt++;
1186 return 0 ;
1187 }
paul718e3742002-12-13 20:15:29 +00001188 }
1189
1190 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001191 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001192 rib->type = type;
1193 rib->distance = distance;
1194 rib->flags = flags;
1195 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001196 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001197 rib->nexthop_num = 0;
1198 rib->uptime = time (NULL);
1199
1200 /* Nexthop settings. */
1201 if (gate)
1202 {
1203 if (ifindex)
1204 nexthop_ipv4_ifindex_add (rib, gate, ifindex);
1205 else
1206 nexthop_ipv4_add (rib, gate);
1207 }
1208 else
1209 nexthop_ifindex_add (rib, ifindex);
1210
1211 /* If this route is kernel route, set FIB flag to the route. */
1212 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1213 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1214 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1215
1216 /* Link new rib to node.*/
1217 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001218
paul718e3742002-12-13 20:15:29 +00001219 /* Process this route node. */
paul4d38fdb2005-04-28 17:35:14 +00001220 rib_queue_add (&zebrad, rn, same);
1221
paul718e3742002-12-13 20:15:29 +00001222 /* Free implicit route.*/
1223 if (same)
paul4d38fdb2005-04-28 17:35:14 +00001224 rib_delnode (rn, same);
1225
1226 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001227 return 0;
1228}
1229
1230int
1231rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib)
1232{
1233 struct route_table *table;
1234 struct route_node *rn;
1235 struct rib *same;
1236 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00001237
paul718e3742002-12-13 20:15:29 +00001238 /* Lookup table. */
1239 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1240 if (! table)
1241 return 0;
paul718e3742002-12-13 20:15:29 +00001242 /* Make it sure prefixlen is applied to the prefix. */
1243 apply_mask_ipv4 (p);
1244
1245 /* Set default distance by route type. */
1246 if (rib->distance == 0)
1247 {
1248 rib->distance = route_info[rib->type].distance;
1249
1250 /* iBGP distance is 200. */
1251 if (rib->type == ZEBRA_ROUTE_BGP
1252 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1253 rib->distance = 200;
1254 }
1255
1256 /* Lookup route node.*/
1257 rn = route_node_get (table, (struct prefix *) p);
1258
1259 /* If same type of route are installed, treat it as a implicit
1260 withdraw. */
1261 for (same = rn->info; same; same = same->next)
1262 {
1263 if (same->type == rib->type && same->table == rib->table
1264 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001265 break;
paul718e3742002-12-13 20:15:29 +00001266 }
paul4d38fdb2005-04-28 17:35:14 +00001267
paul718e3742002-12-13 20:15:29 +00001268 /* If this route is kernel route, set FIB flag to the route. */
1269 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
1270 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1271 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1272
1273 /* Link new rib to node.*/
1274 rib_addnode (rn, rib);
1275
1276 /* Process this route node. */
paul4d38fdb2005-04-28 17:35:14 +00001277 rib_queue_add (&zebrad, rn, same);
paul718e3742002-12-13 20:15:29 +00001278
1279 /* Free implicit route.*/
1280 if (same)
paul4d38fdb2005-04-28 17:35:14 +00001281 rib_delnode (rn, same);
1282
1283 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001284 return 0;
1285}
1286
hassoebf1ead2005-09-21 14:58:20 +00001287/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00001288int
1289rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
1290 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1291{
1292 struct route_table *table;
1293 struct route_node *rn;
1294 struct rib *rib;
1295 struct rib *fib = NULL;
1296 struct rib *same = NULL;
1297 struct nexthop *nexthop;
1298 char buf1[BUFSIZ];
1299 char buf2[BUFSIZ];
1300
1301 /* Lookup table. */
1302 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1303 if (! table)
1304 return 0;
1305
1306 /* Apply mask. */
1307 apply_mask_ipv4 (p);
1308
paul5ec90d22003-06-19 01:41:37 +00001309 if (IS_ZEBRA_DEBUG_KERNEL && gate)
ajsb6178002004-12-07 21:12:56 +00001310 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
paul5ec90d22003-06-19 01:41:37 +00001311 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1312 p->prefixlen,
1313 inet_ntoa (*gate),
1314 ifindex);
1315
paul718e3742002-12-13 20:15:29 +00001316 /* Lookup route node. */
1317 rn = route_node_lookup (table, (struct prefix *) p);
1318 if (! rn)
1319 {
1320 if (IS_ZEBRA_DEBUG_KERNEL)
1321 {
1322 if (gate)
ajsb6178002004-12-07 21:12:56 +00001323 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001324 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1325 p->prefixlen,
1326 inet_ntop (AF_INET, gate, buf2, BUFSIZ),
1327 ifindex);
1328 else
ajsb6178002004-12-07 21:12:56 +00001329 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001330 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1331 p->prefixlen,
1332 ifindex);
1333 }
1334 return ZEBRA_ERR_RTNOEXIST;
1335 }
1336
1337 /* Lookup same type route. */
1338 for (rib = rn->info; rib; rib = rib->next)
1339 {
1340 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1341 fib = rib;
1342
hassoebf1ead2005-09-21 14:58:20 +00001343 if (rib->type != type)
1344 continue;
1345 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
1346 nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex)
paul718e3742002-12-13 20:15:29 +00001347 {
hassoebf1ead2005-09-21 14:58:20 +00001348 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00001349 {
hassoebf1ead2005-09-21 14:58:20 +00001350 rib->refcnt--;
1351 route_unlock_node (rn);
1352 route_unlock_node (rn);
1353 return 0;
paul718e3742002-12-13 20:15:29 +00001354 }
hassoebf1ead2005-09-21 14:58:20 +00001355 same = rib;
1356 break;
paul718e3742002-12-13 20:15:29 +00001357 }
hassoebf1ead2005-09-21 14:58:20 +00001358 /* Make sure that the route found has the same gateway. */
1359 else if (gate == NULL ||
1360 ((nexthop = rib->nexthop) &&
1361 (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
1362 IPV4_ADDR_SAME (&nexthop->rgate.ipv4, gate))))
paul5ec90d22003-06-19 01:41:37 +00001363 {
hassoebf1ead2005-09-21 14:58:20 +00001364 same = rib;
1365 break;
paul718e3742002-12-13 20:15:29 +00001366 }
1367 }
1368
1369 /* If same type of route can't be found and this message is from
1370 kernel. */
1371 if (! same)
1372 {
1373 if (fib && type == ZEBRA_ROUTE_KERNEL)
1374 {
1375 /* Unset flags. */
1376 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1377 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1378
1379 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1380 }
1381 else
1382 {
1383 if (IS_ZEBRA_DEBUG_KERNEL)
1384 {
1385 if (gate)
ajsb6178002004-12-07 21:12:56 +00001386 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001387 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1388 p->prefixlen,
1389 inet_ntop (AF_INET, gate, buf2, BUFSIZ),
1390 ifindex,
1391 type);
1392 else
ajsb6178002004-12-07 21:12:56 +00001393 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001394 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1395 p->prefixlen,
1396 ifindex,
1397 type);
1398 }
1399 route_unlock_node (rn);
1400 return ZEBRA_ERR_RTNOEXIST;
1401 }
1402 }
paul4d38fdb2005-04-28 17:35:14 +00001403
1404 /* Process changes. */
1405 rib_queue_add (&zebrad, rn, same);
paul718e3742002-12-13 20:15:29 +00001406
1407 if (same)
1408 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00001409
paul718e3742002-12-13 20:15:29 +00001410 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001411 return 0;
1412}
1413
1414/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00001415static void
paul718e3742002-12-13 20:15:29 +00001416static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
1417{
1418 struct rib *rib;
1419 struct route_node *rn;
1420 struct route_table *table;
1421
1422 /* Lookup table. */
1423 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1424 if (! table)
1425 return;
1426
1427 /* Lookup existing route */
1428 rn = route_node_get (table, p);
1429 for (rib = rn->info; rib; rib = rib->next)
1430 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1431 break;
1432
1433 if (rib)
1434 {
1435 /* Same distance static route is there. Update it with new
1436 nexthop. */
paul718e3742002-12-13 20:15:29 +00001437 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001438 switch (si->type)
paul7021c422003-07-15 12:52:22 +00001439 {
1440 case STATIC_IPV4_GATEWAY:
1441 nexthop_ipv4_add (rib, &si->gate.ipv4);
1442 break;
1443 case STATIC_IPV4_IFNAME:
1444 nexthop_ifname_add (rib, si->gate.ifname);
1445 break;
1446 case STATIC_IPV4_BLACKHOLE:
1447 nexthop_blackhole_add (rib);
1448 break;
paul4d38fdb2005-04-28 17:35:14 +00001449 }
1450 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00001451 }
1452 else
1453 {
1454 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00001455 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
1456
paul718e3742002-12-13 20:15:29 +00001457 rib->type = ZEBRA_ROUTE_STATIC;
1458 rib->distance = si->distance;
1459 rib->metric = 0;
1460 rib->nexthop_num = 0;
1461
1462 switch (si->type)
paul7021c422003-07-15 12:52:22 +00001463 {
1464 case STATIC_IPV4_GATEWAY:
1465 nexthop_ipv4_add (rib, &si->gate.ipv4);
1466 break;
1467 case STATIC_IPV4_IFNAME:
1468 nexthop_ifname_add (rib, si->gate.ifname);
1469 break;
1470 case STATIC_IPV4_BLACKHOLE:
1471 nexthop_blackhole_add (rib);
1472 break;
1473 }
paul718e3742002-12-13 20:15:29 +00001474
hasso81dfcaa2003-05-25 19:21:25 +00001475 /* Save the flags of this static routes (reject, blackhole) */
1476 rib->flags = si->flags;
1477
paul718e3742002-12-13 20:15:29 +00001478 /* Link this rib to the tree. */
1479 rib_addnode (rn, rib);
1480
1481 /* Process this prefix. */
paul4d38fdb2005-04-28 17:35:14 +00001482 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00001483 }
1484}
1485
paula1ac18c2005-06-28 17:17:12 +00001486static int
paul718e3742002-12-13 20:15:29 +00001487static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
1488{
1489 if (nexthop->type == NEXTHOP_TYPE_IPV4
1490 && si->type == STATIC_IPV4_GATEWAY
1491 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
1492 return 1;
1493 if (nexthop->type == NEXTHOP_TYPE_IFNAME
1494 && si->type == STATIC_IPV4_IFNAME
1495 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
1496 return 1;
paul595db7f2003-05-25 21:35:06 +00001497 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
1498 && si->type == STATIC_IPV4_BLACKHOLE)
1499 return 1;
paul718e3742002-12-13 20:15:29 +00001500 return 0;;
1501}
1502
1503/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00001504static void
paul718e3742002-12-13 20:15:29 +00001505static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
1506{
1507 struct route_node *rn;
1508 struct rib *rib;
1509 struct nexthop *nexthop;
1510 struct route_table *table;
1511
1512 /* Lookup table. */
1513 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1514 if (! table)
1515 return;
paul4d38fdb2005-04-28 17:35:14 +00001516
paul718e3742002-12-13 20:15:29 +00001517 /* Lookup existing route with type and distance. */
1518 rn = route_node_lookup (table, p);
1519 if (! rn)
1520 return;
1521
1522 for (rib = rn->info; rib; rib = rib->next)
1523 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1524 break;
1525
1526 if (! rib)
1527 {
1528 route_unlock_node (rn);
1529 return;
1530 }
1531
1532 /* Lookup nexthop. */
1533 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1534 if (static_ipv4_nexthop_same (nexthop, si))
1535 break;
1536
1537 /* Can't find nexthop. */
1538 if (! nexthop)
1539 {
1540 route_unlock_node (rn);
1541 return;
1542 }
1543
1544 /* Check nexthop. */
1545 if (rib->nexthop_num == 1)
1546 {
paul4d38fdb2005-04-28 17:35:14 +00001547 rib_queue_add (&zebrad, rn, rib);
paul718e3742002-12-13 20:15:29 +00001548 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00001549 }
1550 else
1551 {
paul6baeb982003-10-28 03:47:15 +00001552 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1553 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00001554 nexthop_delete (rib, nexthop);
1555 nexthop_free (nexthop);
1556 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00001557 }
paul718e3742002-12-13 20:15:29 +00001558 /* Unlock node. */
1559 route_unlock_node (rn);
1560}
1561
1562/* Add static route into static route configuration. */
1563int
hasso39db97e2004-10-12 20:50:58 +00001564static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00001565 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001566{
1567 u_char type = 0;
1568 struct route_node *rn;
1569 struct static_ipv4 *si;
1570 struct static_ipv4 *pp;
1571 struct static_ipv4 *cp;
1572 struct static_ipv4 *update = NULL;
1573 struct route_table *stable;
1574
1575 /* Lookup table. */
1576 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
1577 if (! stable)
1578 return -1;
1579
1580 /* Lookup static route prefix. */
1581 rn = route_node_get (stable, p);
1582
1583 /* Make flags. */
1584 if (gate)
1585 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00001586 else if (ifname)
paul718e3742002-12-13 20:15:29 +00001587 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00001588 else
1589 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00001590
1591 /* Do nothing if there is a same static route. */
1592 for (si = rn->info; si; si = si->next)
1593 {
1594 if (type == si->type
1595 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
1596 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
1597 {
1598 if (distance == si->distance)
1599 {
1600 route_unlock_node (rn);
1601 return 0;
1602 }
1603 else
1604 update = si;
1605 }
1606 }
1607
1608 /* Distance chaged. */
1609 if (update)
1610 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
1611
1612 /* Make new static route structure. */
1613 si = XMALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
1614 memset (si, 0, sizeof (struct static_ipv4));
1615
1616 si->type = type;
1617 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00001618 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00001619
1620 if (gate)
1621 si->gate.ipv4 = *gate;
1622 if (ifname)
1623 si->gate.ifname = XSTRDUP (0, ifname);
1624
1625 /* Add new static route information to the tree with sort by
1626 distance value and gateway address. */
1627 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
1628 {
1629 if (si->distance < cp->distance)
1630 break;
1631 if (si->distance > cp->distance)
1632 continue;
1633 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
1634 {
1635 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
1636 break;
1637 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
1638 continue;
1639 }
1640 }
1641
1642 /* Make linked list. */
1643 if (pp)
1644 pp->next = si;
1645 else
1646 rn->info = si;
1647 if (cp)
1648 cp->prev = si;
1649 si->prev = pp;
1650 si->next = cp;
1651
1652 /* Install into rib. */
1653 static_install_ipv4 (p, si);
1654
1655 return 1;
1656}
1657
1658/* Delete static route from static route configuration. */
1659int
hasso39db97e2004-10-12 20:50:58 +00001660static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00001661 u_char distance, u_int32_t vrf_id)
1662{
1663 u_char type = 0;
1664 struct route_node *rn;
1665 struct static_ipv4 *si;
1666 struct route_table *stable;
1667
1668 /* Lookup table. */
1669 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
1670 if (! stable)
1671 return -1;
1672
1673 /* Lookup static route prefix. */
1674 rn = route_node_lookup (stable, p);
1675 if (! rn)
1676 return 0;
1677
1678 /* Make flags. */
1679 if (gate)
1680 type = STATIC_IPV4_GATEWAY;
1681 else if (ifname)
1682 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00001683 else
1684 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00001685
1686 /* Find same static route is the tree */
1687 for (si = rn->info; si; si = si->next)
1688 if (type == si->type
1689 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
1690 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
1691 break;
1692
1693 /* Can't find static route. */
1694 if (! si)
1695 {
1696 route_unlock_node (rn);
1697 return 0;
1698 }
1699
1700 /* Install into rib. */
1701 static_uninstall_ipv4 (p, si);
1702
1703 /* Unlink static route from linked list. */
1704 if (si->prev)
1705 si->prev->next = si->next;
1706 else
1707 rn->info = si->next;
1708 if (si->next)
1709 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00001710 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001711
1712 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00001713 if (ifname)
1714 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00001715 XFREE (MTYPE_STATIC_IPV4, si);
1716
paul143a3852003-09-29 20:06:13 +00001717 route_unlock_node (rn);
1718
paul718e3742002-12-13 20:15:29 +00001719 return 1;
1720}
1721
1722
1723#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00001724static int
paul718e3742002-12-13 20:15:29 +00001725rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
1726 struct in6_addr *gate, unsigned int ifindex, int table)
1727{
hasso726f9b22003-05-25 21:04:54 +00001728 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
1729#if defined (MUSICA) || defined (LINUX)
1730 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
1731 if (p->prefixlen == 96)
1732 return 0;
1733#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00001734 return 1;
hasso726f9b22003-05-25 21:04:54 +00001735 }
paul718e3742002-12-13 20:15:29 +00001736 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
1737 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
1738 {
1739 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
1740 return 1;
1741 }
1742 return 0;
1743}
1744
1745int
1746rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00001747 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
1748 u_int32_t metric, u_char distance)
paul718e3742002-12-13 20:15:29 +00001749{
1750 struct rib *rib;
1751 struct rib *same = NULL;
1752 struct route_table *table;
1753 struct route_node *rn;
1754 struct nexthop *nexthop;
1755
paul718e3742002-12-13 20:15:29 +00001756 /* Lookup table. */
1757 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1758 if (! table)
1759 return 0;
1760
1761 /* Make sure mask is applied. */
1762 apply_mask_ipv6 (p);
1763
1764 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00001765 if (!distance)
1766 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00001767
1768 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1769 distance = 200;
1770
1771 /* Filter bogus route. */
1772 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
1773 return 0;
1774
1775 /* Lookup route node.*/
1776 rn = route_node_get (table, (struct prefix *) p);
1777
1778 /* If same type of route are installed, treat it as a implicit
1779 withdraw. */
1780 for (rib = rn->info; rib; rib = rib->next)
1781 {
hassoebf1ead2005-09-21 14:58:20 +00001782 if (rib->type != type)
1783 continue;
1784 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00001785 {
1786 same = rib;
paul718e3742002-12-13 20:15:29 +00001787 break;
1788 }
hassoebf1ead2005-09-21 14:58:20 +00001789 else if ((nexthop = rib->nexthop) &&
1790 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
1791 nexthop->ifindex == ifindex)
1792 {
1793 rib->refcnt++;
1794 return 0;
1795 }
paul718e3742002-12-13 20:15:29 +00001796 }
1797
1798 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001799 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
1800
paul718e3742002-12-13 20:15:29 +00001801 rib->type = type;
1802 rib->distance = distance;
1803 rib->flags = flags;
1804 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001805 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001806 rib->nexthop_num = 0;
1807 rib->uptime = time (NULL);
1808
1809 /* Nexthop settings. */
1810 if (gate)
1811 {
1812 if (ifindex)
1813 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
1814 else
1815 nexthop_ipv6_add (rib, gate);
1816 }
1817 else
1818 nexthop_ifindex_add (rib, ifindex);
1819
1820 /* If this route is kernel route, set FIB flag to the route. */
1821 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1822 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1823 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1824
1825 /* Link new rib to node.*/
1826 rib_addnode (rn, rib);
1827
1828 /* Process this route node. */
paul4d38fdb2005-04-28 17:35:14 +00001829 rib_queue_add (&zebrad, rn, same);
1830
paul718e3742002-12-13 20:15:29 +00001831 /* Free implicit route.*/
1832 if (same)
paul4d38fdb2005-04-28 17:35:14 +00001833 rib_delnode (rn, same);
1834
1835 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001836 return 0;
1837}
1838
hassoebf1ead2005-09-21 14:58:20 +00001839/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00001840int
1841rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
1842 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1843{
1844 struct route_table *table;
1845 struct route_node *rn;
1846 struct rib *rib;
1847 struct rib *fib = NULL;
1848 struct rib *same = NULL;
1849 struct nexthop *nexthop;
1850 char buf1[BUFSIZ];
1851 char buf2[BUFSIZ];
1852
1853 /* Apply mask. */
1854 apply_mask_ipv6 (p);
1855
1856 /* Lookup table. */
1857 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1858 if (! table)
1859 return 0;
paul4d38fdb2005-04-28 17:35:14 +00001860
paul718e3742002-12-13 20:15:29 +00001861 /* Lookup route node. */
1862 rn = route_node_lookup (table, (struct prefix *) p);
1863 if (! rn)
1864 {
1865 if (IS_ZEBRA_DEBUG_KERNEL)
1866 {
1867 if (gate)
ajsb6178002004-12-07 21:12:56 +00001868 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001869 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1870 p->prefixlen,
1871 inet_ntop (AF_INET6, gate, buf2, BUFSIZ),
1872 ifindex);
1873 else
ajsb6178002004-12-07 21:12:56 +00001874 zlog_debug ("route %s/%d 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 ifindex);
1878 }
1879 return ZEBRA_ERR_RTNOEXIST;
1880 }
1881
1882 /* Lookup same type route. */
1883 for (rib = rn->info; rib; rib = rib->next)
1884 {
1885 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1886 fib = rib;
1887
hassoebf1ead2005-09-21 14:58:20 +00001888 if (rib->type != type)
1889 continue;
1890 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
1891 nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex)
paul718e3742002-12-13 20:15:29 +00001892 {
hassoebf1ead2005-09-21 14:58:20 +00001893 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00001894 {
hassoebf1ead2005-09-21 14:58:20 +00001895 rib->refcnt--;
1896 route_unlock_node (rn);
1897 route_unlock_node (rn);
1898 return 0;
paul718e3742002-12-13 20:15:29 +00001899 }
hassoebf1ead2005-09-21 14:58:20 +00001900 same = rib;
1901 break;
paul718e3742002-12-13 20:15:29 +00001902 }
hassoebf1ead2005-09-21 14:58:20 +00001903 /* Make sure that the route found has the same gateway. */
1904 else if (gate == NULL ||
1905 ((nexthop = rib->nexthop) &&
1906 (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate) ||
1907 IPV6_ADDR_SAME (&nexthop->rgate.ipv6, gate))))
paul718e3742002-12-13 20:15:29 +00001908 {
hassoebf1ead2005-09-21 14:58:20 +00001909 same = rib;
1910 break;
paul718e3742002-12-13 20:15:29 +00001911 }
1912 }
1913
1914 /* If same type of route can't be found and this message is from
1915 kernel. */
1916 if (! same)
1917 {
1918 if (fib && type == ZEBRA_ROUTE_KERNEL)
1919 {
1920 /* Unset flags. */
1921 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1922 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1923
1924 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1925 }
1926 else
1927 {
1928 if (IS_ZEBRA_DEBUG_KERNEL)
1929 {
1930 if (gate)
ajsb6178002004-12-07 21:12:56 +00001931 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001932 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1933 p->prefixlen,
1934 inet_ntop (AF_INET6, gate, buf2, BUFSIZ),
1935 ifindex,
1936 type);
1937 else
ajsb6178002004-12-07 21:12:56 +00001938 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001939 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1940 p->prefixlen,
1941 ifindex,
1942 type);
1943 }
1944 route_unlock_node (rn);
1945 return ZEBRA_ERR_RTNOEXIST;
1946 }
1947 }
1948
paul4d38fdb2005-04-28 17:35:14 +00001949 /* Process changes. */
1950 rib_queue_add (&zebrad, rn, same);
1951
paul718e3742002-12-13 20:15:29 +00001952 if (same)
1953 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00001954
paul718e3742002-12-13 20:15:29 +00001955 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001956 return 0;
1957}
1958
1959/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00001960static void
paul718e3742002-12-13 20:15:29 +00001961static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
1962{
1963 struct rib *rib;
1964 struct route_table *table;
1965 struct route_node *rn;
1966
1967 /* Lookup table. */
1968 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1969 if (! table)
1970 return;
1971
1972 /* Lookup existing route */
1973 rn = route_node_get (table, p);
1974 for (rib = rn->info; rib; rib = rib->next)
1975 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1976 break;
1977
1978 if (rib)
1979 {
1980 /* Same distance static route is there. Update it with new
1981 nexthop. */
paul718e3742002-12-13 20:15:29 +00001982 route_unlock_node (rn);
1983
1984 switch (si->type)
1985 {
1986 case STATIC_IPV6_GATEWAY:
1987 nexthop_ipv6_add (rib, &si->ipv6);
1988 break;
1989 case STATIC_IPV6_IFNAME:
1990 nexthop_ifname_add (rib, si->ifname);
1991 break;
1992 case STATIC_IPV6_GATEWAY_IFNAME:
1993 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
1994 break;
1995 }
paul4d38fdb2005-04-28 17:35:14 +00001996 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00001997 }
1998 else
1999 {
2000 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002001 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2002
paul718e3742002-12-13 20:15:29 +00002003 rib->type = ZEBRA_ROUTE_STATIC;
2004 rib->distance = si->distance;
2005 rib->metric = 0;
2006 rib->nexthop_num = 0;
2007
2008 switch (si->type)
2009 {
2010 case STATIC_IPV6_GATEWAY:
2011 nexthop_ipv6_add (rib, &si->ipv6);
2012 break;
2013 case STATIC_IPV6_IFNAME:
2014 nexthop_ifname_add (rib, si->ifname);
2015 break;
2016 case STATIC_IPV6_GATEWAY_IFNAME:
2017 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2018 break;
2019 }
2020
hasso81dfcaa2003-05-25 19:21:25 +00002021 /* Save the flags of this static routes (reject, blackhole) */
2022 rib->flags = si->flags;
2023
paul718e3742002-12-13 20:15:29 +00002024 /* Link this rib to the tree. */
2025 rib_addnode (rn, rib);
2026
2027 /* Process this prefix. */
paul4d38fdb2005-04-28 17:35:14 +00002028 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00002029 }
2030}
2031
paula1ac18c2005-06-28 17:17:12 +00002032static int
paul718e3742002-12-13 20:15:29 +00002033static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2034{
2035 if (nexthop->type == NEXTHOP_TYPE_IPV6
2036 && si->type == STATIC_IPV6_GATEWAY
2037 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2038 return 1;
2039 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2040 && si->type == STATIC_IPV6_IFNAME
2041 && strcmp (nexthop->ifname, si->ifname) == 0)
2042 return 1;
2043 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2044 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2045 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2046 && strcmp (nexthop->ifname, si->ifname) == 0)
2047 return 1;
2048 return 0;;
2049}
2050
paula1ac18c2005-06-28 17:17:12 +00002051static void
paul718e3742002-12-13 20:15:29 +00002052static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2053{
2054 struct route_table *table;
2055 struct route_node *rn;
2056 struct rib *rib;
2057 struct nexthop *nexthop;
2058
2059 /* Lookup table. */
2060 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2061 if (! table)
2062 return;
2063
2064 /* Lookup existing route with type and distance. */
2065 rn = route_node_lookup (table, (struct prefix *) p);
2066 if (! rn)
2067 return;
2068
2069 for (rib = rn->info; rib; rib = rib->next)
2070 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2071 break;
2072 if (! rib)
2073 {
2074 route_unlock_node (rn);
2075 return;
2076 }
2077
2078 /* Lookup nexthop. */
2079 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2080 if (static_ipv6_nexthop_same (nexthop, si))
2081 break;
2082
2083 /* Can't find nexthop. */
2084 if (! nexthop)
2085 {
2086 route_unlock_node (rn);
2087 return;
2088 }
2089
2090 /* Check nexthop. */
2091 if (rib->nexthop_num == 1)
2092 {
2093 rib_delnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00002094 rib_queue_add (&zebrad, rn, rib);
paul718e3742002-12-13 20:15:29 +00002095 }
2096 else
2097 {
paul6baeb982003-10-28 03:47:15 +00002098 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2099 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002100 nexthop_delete (rib, nexthop);
2101 nexthop_free (nexthop);
2102 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00002103 }
paul718e3742002-12-13 20:15:29 +00002104 /* Unlock node. */
2105 route_unlock_node (rn);
2106}
2107
2108/* Add static route into static route configuration. */
2109int
2110static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002111 const char *ifname, u_char flags, u_char distance,
2112 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002113{
2114 struct route_node *rn;
2115 struct static_ipv6 *si;
2116 struct static_ipv6 *pp;
2117 struct static_ipv6 *cp;
2118 struct route_table *stable;
2119
2120 /* Lookup table. */
2121 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2122 if (! stable)
2123 return -1;
2124
2125 /* Lookup static route prefix. */
2126 rn = route_node_get (stable, p);
2127
2128 /* Do nothing if there is a same static route. */
2129 for (si = rn->info; si; si = si->next)
2130 {
2131 if (distance == si->distance
2132 && type == si->type
2133 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2134 && (! ifname || strcmp (ifname, si->ifname) == 0))
2135 {
2136 route_unlock_node (rn);
2137 return 0;
2138 }
2139 }
2140
2141 /* Make new static route structure. */
2142 si = XMALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
2143 memset (si, 0, sizeof (struct static_ipv6));
2144
2145 si->type = type;
2146 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002147 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002148
2149 switch (type)
2150 {
2151 case STATIC_IPV6_GATEWAY:
2152 si->ipv6 = *gate;
2153 break;
2154 case STATIC_IPV6_IFNAME:
2155 si->ifname = XSTRDUP (0, ifname);
2156 break;
2157 case STATIC_IPV6_GATEWAY_IFNAME:
2158 si->ipv6 = *gate;
2159 si->ifname = XSTRDUP (0, ifname);
2160 break;
2161 }
2162
2163 /* Add new static route information to the tree with sort by
2164 distance value and gateway address. */
2165 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2166 {
2167 if (si->distance < cp->distance)
2168 break;
2169 if (si->distance > cp->distance)
2170 continue;
2171 }
2172
2173 /* Make linked list. */
2174 if (pp)
2175 pp->next = si;
2176 else
2177 rn->info = si;
2178 if (cp)
2179 cp->prev = si;
2180 si->prev = pp;
2181 si->next = cp;
2182
2183 /* Install into rib. */
2184 static_install_ipv6 (p, si);
2185
2186 return 1;
2187}
2188
2189/* Delete static route from static route configuration. */
2190int
2191static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002192 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002193{
2194 struct route_node *rn;
2195 struct static_ipv6 *si;
2196 struct route_table *stable;
2197
2198 /* Lookup table. */
2199 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2200 if (! stable)
2201 return -1;
2202
2203 /* Lookup static route prefix. */
2204 rn = route_node_lookup (stable, p);
2205 if (! rn)
2206 return 0;
2207
2208 /* Find same static route is the tree */
2209 for (si = rn->info; si; si = si->next)
2210 if (distance == si->distance
2211 && type == si->type
2212 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2213 && (! ifname || strcmp (ifname, si->ifname) == 0))
2214 break;
2215
2216 /* Can't find static route. */
2217 if (! si)
2218 {
2219 route_unlock_node (rn);
2220 return 0;
2221 }
2222
2223 /* Install into rib. */
2224 static_uninstall_ipv6 (p, si);
2225
2226 /* Unlink static route from linked list. */
2227 if (si->prev)
2228 si->prev->next = si->next;
2229 else
2230 rn->info = si->next;
2231 if (si->next)
2232 si->next->prev = si->prev;
2233
2234 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002235 if (ifname)
2236 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00002237 XFREE (MTYPE_STATIC_IPV6, si);
2238
2239 return 1;
2240}
2241#endif /* HAVE_IPV6 */
2242
2243/* RIB update function. */
2244void
paula1ac18c2005-06-28 17:17:12 +00002245rib_update (void)
paul718e3742002-12-13 20:15:29 +00002246{
2247 struct route_node *rn;
2248 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00002249
paul718e3742002-12-13 20:15:29 +00002250 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2251 if (table)
2252 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002253 if (rn->info)
2254 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00002255
2256 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2257 if (table)
2258 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002259 if (rn->info)
2260 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00002261}
2262
2263/* Interface goes up. */
paula1ac18c2005-06-28 17:17:12 +00002264static void
paul718e3742002-12-13 20:15:29 +00002265rib_if_up (struct interface *ifp)
2266{
2267 rib_update ();
2268}
2269
2270/* Interface goes down. */
paula1ac18c2005-06-28 17:17:12 +00002271static void
paul718e3742002-12-13 20:15:29 +00002272rib_if_down (struct interface *ifp)
2273{
2274 rib_update ();
2275}
2276
2277/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00002278static void
paul718e3742002-12-13 20:15:29 +00002279rib_weed_table (struct route_table *table)
2280{
2281 struct route_node *rn;
2282 struct rib *rib;
2283 struct rib *next;
2284
2285 if (table)
2286 for (rn = route_top (table); rn; rn = route_next (rn))
2287 for (rib = rn->info; rib; rib = next)
2288 {
2289 next = rib->next;
2290
paulb21b19c2003-06-15 01:28:29 +00002291 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00002292 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00002293 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002294 }
2295}
2296
2297/* Delete all routes from non main table. */
2298void
paula1ac18c2005-06-28 17:17:12 +00002299rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00002300{
2301 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2302 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2303}
2304
2305/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00002306static void
paul718e3742002-12-13 20:15:29 +00002307rib_sweep_table (struct route_table *table)
2308{
2309 struct route_node *rn;
2310 struct rib *rib;
2311 struct rib *next;
2312 int ret = 0;
2313
2314 if (table)
2315 for (rn = route_top (table); rn; rn = route_next (rn))
2316 for (rib = rn->info; rib; rib = next)
2317 {
2318 next = rib->next;
2319
2320 if (rib->type == ZEBRA_ROUTE_KERNEL &&
2321 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
2322 {
2323 ret = rib_uninstall_kernel (rn, rib);
2324 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00002325 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002326 }
2327 }
2328}
2329
2330/* Sweep all RIB tables. */
2331void
paula1ac18c2005-06-28 17:17:12 +00002332rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00002333{
2334 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2335 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2336}
2337
2338/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00002339static void
paul718e3742002-12-13 20:15:29 +00002340rib_close_table (struct route_table *table)
2341{
2342 struct route_node *rn;
2343 struct rib *rib;
2344
2345 if (table)
2346 for (rn = route_top (table); rn; rn = route_next (rn))
2347 for (rib = rn->info; rib; rib = rib->next)
2348 if (! RIB_SYSTEM_ROUTE (rib)
2349 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2350 rib_uninstall_kernel (rn, rib);
2351}
2352
2353/* Close all RIB tables. */
2354void
paula1ac18c2005-06-28 17:17:12 +00002355rib_close (void)
paul718e3742002-12-13 20:15:29 +00002356{
2357 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2358 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2359}
2360
2361/* Routing information base initialize. */
2362void
paula1ac18c2005-06-28 17:17:12 +00002363rib_init (void)
paul718e3742002-12-13 20:15:29 +00002364{
paul4d38fdb2005-04-28 17:35:14 +00002365 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00002366 /* VRF initialization. */
2367 vrf_init ();
2368}