blob: da6a3a8eadb0e9d727bb5b8d503c3f6d3b96ba39 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* Routing Information Base.
2 * Copyright (C) 1997, 98, 99, 2001 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "prefix.h"
25#include "table.h"
26#include "memory.h"
27#include "str.h"
28#include "command.h"
29#include "if.h"
30#include "log.h"
31#include "sockunion.h"
paul4d38fdb2005-04-28 17:35:14 +000032#include "linklist.h"
33#include "thread.h"
34#include "workqueue.h"
paul718e3742002-12-13 20:15:29 +000035
36#include "zebra/rib.h"
37#include "zebra/rt.h"
38#include "zebra/zserv.h"
39#include "zebra/redistribute.h"
40#include "zebra/debug.h"
41
42/* Default rtm_table for all clients */
paulb21b19c2003-06-15 01:28:29 +000043extern struct zebra_t zebrad;
paul718e3742002-12-13 20:15:29 +000044
45/* Each route type's string and default distance value. */
46struct
47{
48 int key;
49 int distance;
50} route_info[] =
51{
52 {ZEBRA_ROUTE_SYSTEM, 0},
53 {ZEBRA_ROUTE_KERNEL, 0},
54 {ZEBRA_ROUTE_CONNECT, 0},
55 {ZEBRA_ROUTE_STATIC, 1},
56 {ZEBRA_ROUTE_RIP, 120},
57 {ZEBRA_ROUTE_RIPNG, 120},
58 {ZEBRA_ROUTE_OSPF, 110},
59 {ZEBRA_ROUTE_OSPF6, 110},
jardin9e867fe2003-12-23 08:56:18 +000060 {ZEBRA_ROUTE_ISIS, 115},
paul718e3742002-12-13 20:15:29 +000061 {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */}
62};
paul4d38fdb2005-04-28 17:35:14 +000063
64struct zebra_queue_node_t
65{
66 struct route_node *node;
67 struct rib *del;
68};
paul718e3742002-12-13 20:15:29 +000069
70/* Vector for routing table. */
71vector vrf_vector;
72
73/* Allocate new VRF. */
paula1ac18c2005-06-28 17:17:12 +000074static struct vrf *
hassofce954f2004-10-07 20:29:24 +000075vrf_alloc (const char *name)
paul718e3742002-12-13 20:15:29 +000076{
77 struct vrf *vrf;
78
79 vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
80
81 /* Put name. */
82 if (name)
83 vrf->name = XSTRDUP (MTYPE_VRF_NAME, name);
84
85 /* Allocate routing table and static table. */
86 vrf->table[AFI_IP][SAFI_UNICAST] = route_table_init ();
87 vrf->table[AFI_IP6][SAFI_UNICAST] = route_table_init ();
88 vrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
89 vrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
90
91 return vrf;
92}
93
94/* Free VRF. */
paula1ac18c2005-06-28 17:17:12 +000095static void
paul718e3742002-12-13 20:15:29 +000096vrf_free (struct vrf *vrf)
97{
98 if (vrf->name)
99 XFREE (MTYPE_VRF_NAME, vrf->name);
100 XFREE (MTYPE_VRF, vrf);
101}
102
103/* Lookup VRF by identifier. */
104struct vrf *
105vrf_lookup (u_int32_t id)
106{
107 return vector_lookup (vrf_vector, id);
108}
109
110/* Lookup VRF by name. */
paula1ac18c2005-06-28 17:17:12 +0000111static struct vrf *
paul718e3742002-12-13 20:15:29 +0000112vrf_lookup_by_name (char *name)
113{
hassofce954f2004-10-07 20:29:24 +0000114 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000115 struct vrf *vrf;
116
paul55468c82005-03-14 20:19:01 +0000117 for (i = 0; i < vector_active (vrf_vector); i++)
paul718e3742002-12-13 20:15:29 +0000118 if ((vrf = vector_slot (vrf_vector, i)) != NULL)
119 if (vrf->name && name && strcmp (vrf->name, name) == 0)
120 return vrf;
121 return NULL;
122}
123
124/* Initialize VRF. */
paula1ac18c2005-06-28 17:17:12 +0000125static void
126vrf_init (void)
paul718e3742002-12-13 20:15:29 +0000127{
128 struct vrf *default_table;
129
130 /* Allocate VRF vector. */
131 vrf_vector = vector_init (1);
132
133 /* Allocate default main table. */
134 default_table = vrf_alloc ("Default-IP-Routing-Table");
135
136 /* Default table index must be 0. */
137 vector_set_index (vrf_vector, 0, default_table);
138}
139
140/* Lookup route table. */
141struct route_table *
142vrf_table (afi_t afi, safi_t safi, u_int32_t id)
143{
144 struct vrf *vrf;
145
146 vrf = vrf_lookup (id);
147 if (! vrf)
148 return NULL;
149
150 return vrf->table[afi][safi];
151}
152
153/* Lookup static route table. */
154struct route_table *
155vrf_static_table (afi_t afi, safi_t safi, u_int32_t id)
156{
157 struct vrf *vrf;
158
159 vrf = vrf_lookup (id);
160 if (! vrf)
161 return NULL;
162
163 return vrf->stable[afi][safi];
164}
165
166/* Add nexthop to the end of the list. */
paula1ac18c2005-06-28 17:17:12 +0000167static void
paul718e3742002-12-13 20:15:29 +0000168nexthop_add (struct rib *rib, struct nexthop *nexthop)
169{
170 struct nexthop *last;
171
172 for (last = rib->nexthop; last && last->next; last = last->next)
173 ;
174 if (last)
175 last->next = nexthop;
176 else
177 rib->nexthop = nexthop;
178 nexthop->prev = last;
179
180 rib->nexthop_num++;
181}
182
183/* Delete specified nexthop from the list. */
paula1ac18c2005-06-28 17:17:12 +0000184static void
paul718e3742002-12-13 20:15:29 +0000185nexthop_delete (struct rib *rib, struct nexthop *nexthop)
186{
187 if (nexthop->next)
188 nexthop->next->prev = nexthop->prev;
189 if (nexthop->prev)
190 nexthop->prev->next = nexthop->next;
191 else
192 rib->nexthop = nexthop->next;
193 rib->nexthop_num--;
194}
195
196/* Free nexthop. */
paula1ac18c2005-06-28 17:17:12 +0000197static void
paul718e3742002-12-13 20:15:29 +0000198nexthop_free (struct nexthop *nexthop)
199{
paula4b70762003-05-16 17:19:48 +0000200 if (nexthop->ifname)
201 XFREE (0, nexthop->ifname);
paul718e3742002-12-13 20:15:29 +0000202 XFREE (MTYPE_NEXTHOP, nexthop);
203}
204
205struct nexthop *
206nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
207{
208 struct nexthop *nexthop;
209
210 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
211 memset (nexthop, 0, sizeof (struct nexthop));
212 nexthop->type = NEXTHOP_TYPE_IFINDEX;
213 nexthop->ifindex = ifindex;
214
215 nexthop_add (rib, nexthop);
216
217 return nexthop;
218}
219
220struct nexthop *
221nexthop_ifname_add (struct rib *rib, char *ifname)
222{
223 struct nexthop *nexthop;
224
225 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
226 memset (nexthop, 0, sizeof (struct nexthop));
227 nexthop->type = NEXTHOP_TYPE_IFNAME;
paula4b70762003-05-16 17:19:48 +0000228 nexthop->ifname = XSTRDUP (0, ifname);
paul718e3742002-12-13 20:15:29 +0000229
230 nexthop_add (rib, nexthop);
231
232 return nexthop;
233}
234
235struct nexthop *
236nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4)
237{
238 struct nexthop *nexthop;
239
240 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
241 memset (nexthop, 0, sizeof (struct nexthop));
242 nexthop->type = NEXTHOP_TYPE_IPV4;
243 nexthop->gate.ipv4 = *ipv4;
244
245 nexthop_add (rib, nexthop);
246
247 return nexthop;
248}
249
paula1ac18c2005-06-28 17:17:12 +0000250static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000251nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
252 unsigned int ifindex)
253{
254 struct nexthop *nexthop;
255
256 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
257 memset (nexthop, 0, sizeof (struct nexthop));
258 nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
259 nexthop->gate.ipv4 = *ipv4;
260 nexthop->ifindex = ifindex;
261
262 nexthop_add (rib, nexthop);
263
264 return nexthop;
265}
266
267#ifdef HAVE_IPV6
268struct nexthop *
269nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
270{
271 struct nexthop *nexthop;
272
273 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
274 memset (nexthop, 0, sizeof (struct nexthop));
275 nexthop->type = NEXTHOP_TYPE_IPV6;
276 nexthop->gate.ipv6 = *ipv6;
277
278 nexthop_add (rib, nexthop);
279
280 return nexthop;
281}
282
paula1ac18c2005-06-28 17:17:12 +0000283static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000284nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
285 char *ifname)
286{
287 struct nexthop *nexthop;
288
289 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
290 memset (nexthop, 0, sizeof (struct nexthop));
291 nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
292 nexthop->gate.ipv6 = *ipv6;
293 nexthop->ifname = XSTRDUP (0, ifname);
294
295 nexthop_add (rib, nexthop);
296
297 return nexthop;
298}
299
paula1ac18c2005-06-28 17:17:12 +0000300static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000301nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
302 unsigned int ifindex)
303{
304 struct nexthop *nexthop;
305
306 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
307 memset (nexthop, 0, sizeof (struct nexthop));
308 nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
309 nexthop->gate.ipv6 = *ipv6;
310 nexthop->ifindex = ifindex;
311
312 nexthop_add (rib, nexthop);
313
314 return nexthop;
315}
316#endif /* HAVE_IPV6 */
317
paul595db7f2003-05-25 21:35:06 +0000318struct nexthop *
319nexthop_blackhole_add (struct rib *rib)
320{
321 struct nexthop *nexthop;
322
323 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
324 memset (nexthop, 0, sizeof (struct nexthop));
325 nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
326 SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
327
328 nexthop_add (rib, nexthop);
329
330 return nexthop;
331}
332
paul718e3742002-12-13 20:15:29 +0000333/* If force flag is not set, do not modify falgs at all for uninstall
334 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000335static int
paul718e3742002-12-13 20:15:29 +0000336nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
337 struct route_node *top)
338{
339 struct prefix_ipv4 p;
340 struct route_table *table;
341 struct route_node *rn;
342 struct rib *match;
343 struct nexthop *newhop;
344
345 if (nexthop->type == NEXTHOP_TYPE_IPV4)
346 nexthop->ifindex = 0;
347
348 if (set)
349 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
350
351 /* Make lookup prefix. */
352 memset (&p, 0, sizeof (struct prefix_ipv4));
353 p.family = AF_INET;
354 p.prefixlen = IPV4_MAX_PREFIXLEN;
355 p.prefix = nexthop->gate.ipv4;
356
357 /* Lookup table. */
358 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
359 if (! table)
360 return 0;
361
362 rn = route_node_match (table, (struct prefix *) &p);
363 while (rn)
364 {
365 route_unlock_node (rn);
366
367 /* If lookup self prefix return immidiately. */
368 if (rn == top)
369 return 0;
370
371 /* Pick up selected route. */
372 for (match = rn->info; match; match = match->next)
373 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
374 break;
375
376 /* If there is no selected route or matched route is EGP, go up
377 tree. */
378 if (! match
379 || match->type == ZEBRA_ROUTE_BGP)
380 {
381 do {
382 rn = rn->parent;
383 } while (rn && rn->info == NULL);
384 if (rn)
385 route_lock_node (rn);
386 }
387 else
388 {
389 if (match->type == ZEBRA_ROUTE_CONNECT)
390 {
391 /* Directly point connected route. */
392 newhop = match->nexthop;
393 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
394 nexthop->ifindex = newhop->ifindex;
395
396 return 1;
397 }
398 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
399 {
400 for (newhop = match->nexthop; newhop; newhop = newhop->next)
401 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
402 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
403 {
404 if (set)
405 {
406 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
407 nexthop->rtype = newhop->type;
408 if (newhop->type == NEXTHOP_TYPE_IPV4 ||
409 newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
410 nexthop->rgate.ipv4 = newhop->gate.ipv4;
411 if (newhop->type == NEXTHOP_TYPE_IFINDEX
412 || newhop->type == NEXTHOP_TYPE_IFNAME
413 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
414 nexthop->rifindex = newhop->ifindex;
415 }
416 return 1;
417 }
418 return 0;
419 }
420 else
421 {
422 return 0;
423 }
424 }
425 }
426 return 0;
427}
428
429#ifdef HAVE_IPV6
430/* If force flag is not set, do not modify falgs at all for uninstall
431 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000432static int
paul718e3742002-12-13 20:15:29 +0000433nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
434 struct route_node *top)
435{
436 struct prefix_ipv6 p;
437 struct route_table *table;
438 struct route_node *rn;
439 struct rib *match;
440 struct nexthop *newhop;
441
442 if (nexthop->type == NEXTHOP_TYPE_IPV6)
443 nexthop->ifindex = 0;
444
445 if (set)
446 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
447
448 /* Make lookup prefix. */
449 memset (&p, 0, sizeof (struct prefix_ipv6));
450 p.family = AF_INET6;
451 p.prefixlen = IPV6_MAX_PREFIXLEN;
452 p.prefix = nexthop->gate.ipv6;
453
454 /* Lookup table. */
455 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
456 if (! table)
457 return 0;
458
459 rn = route_node_match (table, (struct prefix *) &p);
460 while (rn)
461 {
462 route_unlock_node (rn);
463
464 /* If lookup self prefix return immidiately. */
465 if (rn == top)
466 return 0;
467
468 /* Pick up selected route. */
469 for (match = rn->info; match; match = match->next)
470 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
471 break;
472
473 /* If there is no selected route or matched route is EGP, go up
474 tree. */
475 if (! match
476 || match->type == ZEBRA_ROUTE_BGP)
477 {
478 do {
479 rn = rn->parent;
480 } while (rn && rn->info == NULL);
481 if (rn)
482 route_lock_node (rn);
483 }
484 else
485 {
486 if (match->type == ZEBRA_ROUTE_CONNECT)
487 {
488 /* Directly point connected route. */
489 newhop = match->nexthop;
490
491 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
492 nexthop->ifindex = newhop->ifindex;
493
494 return 1;
495 }
496 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
497 {
498 for (newhop = match->nexthop; newhop; newhop = newhop->next)
499 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
500 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
501 {
502 if (set)
503 {
504 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
505 nexthop->rtype = newhop->type;
506 if (newhop->type == NEXTHOP_TYPE_IPV6
507 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
508 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
509 nexthop->rgate.ipv6 = newhop->gate.ipv6;
510 if (newhop->type == NEXTHOP_TYPE_IFINDEX
511 || newhop->type == NEXTHOP_TYPE_IFNAME
512 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
513 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
514 nexthop->rifindex = newhop->ifindex;
515 }
516 return 1;
517 }
518 return 0;
519 }
520 else
521 {
522 return 0;
523 }
524 }
525 }
526 return 0;
527}
528#endif /* HAVE_IPV6 */
529
530struct rib *
531rib_match_ipv4 (struct in_addr addr)
532{
533 struct prefix_ipv4 p;
534 struct route_table *table;
535 struct route_node *rn;
536 struct rib *match;
537 struct nexthop *newhop;
538
539 /* Lookup table. */
540 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
541 if (! table)
542 return 0;
543
544 memset (&p, 0, sizeof (struct prefix_ipv4));
545 p.family = AF_INET;
546 p.prefixlen = IPV4_MAX_PREFIXLEN;
547 p.prefix = addr;
548
549 rn = route_node_match (table, (struct prefix *) &p);
550
551 while (rn)
552 {
553 route_unlock_node (rn);
554
555 /* Pick up selected route. */
556 for (match = rn->info; match; match = match->next)
557 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
558 break;
559
560 /* If there is no selected route or matched route is EGP, go up
561 tree. */
562 if (! match
563 || match->type == ZEBRA_ROUTE_BGP)
564 {
565 do {
566 rn = rn->parent;
567 } while (rn && rn->info == NULL);
568 if (rn)
569 route_lock_node (rn);
570 }
571 else
572 {
573 if (match->type == ZEBRA_ROUTE_CONNECT)
574 /* Directly point connected route. */
575 return match;
576 else
577 {
578 for (newhop = match->nexthop; newhop; newhop = newhop->next)
579 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
580 return match;
581 return NULL;
582 }
583 }
584 }
585 return NULL;
586}
587
588struct rib *
589rib_lookup_ipv4 (struct prefix_ipv4 *p)
590{
591 struct route_table *table;
592 struct route_node *rn;
593 struct rib *match;
594 struct nexthop *nexthop;
595
596 /* Lookup table. */
597 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
598 if (! table)
599 return 0;
600
601 rn = route_node_lookup (table, (struct prefix *) p);
602
603 /* No route for this prefix. */
604 if (! rn)
605 return NULL;
606
607 /* Unlock node. */
608 route_unlock_node (rn);
609
610 /* Pick up selected route. */
611 for (match = rn->info; match; match = match->next)
612 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
613 break;
614
615 if (! match || match->type == ZEBRA_ROUTE_BGP)
616 return NULL;
617
618 if (match->type == ZEBRA_ROUTE_CONNECT)
619 return match;
620
621 for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
622 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
623 return match;
624
625 return NULL;
626}
627
628#ifdef HAVE_IPV6
629struct rib *
630rib_match_ipv6 (struct in6_addr *addr)
631{
632 struct prefix_ipv6 p;
633 struct route_table *table;
634 struct route_node *rn;
635 struct rib *match;
636 struct nexthop *newhop;
637
638 /* Lookup table. */
639 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
640 if (! table)
641 return 0;
642
643 memset (&p, 0, sizeof (struct prefix_ipv6));
644 p.family = AF_INET6;
645 p.prefixlen = IPV6_MAX_PREFIXLEN;
646 IPV6_ADDR_COPY (&p.prefix, addr);
647
648 rn = route_node_match (table, (struct prefix *) &p);
649
650 while (rn)
651 {
652 route_unlock_node (rn);
653
654 /* Pick up selected route. */
655 for (match = rn->info; match; match = match->next)
656 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
657 break;
658
659 /* If there is no selected route or matched route is EGP, go up
660 tree. */
661 if (! match
662 || match->type == ZEBRA_ROUTE_BGP)
663 {
664 do {
665 rn = rn->parent;
666 } while (rn && rn->info == NULL);
667 if (rn)
668 route_lock_node (rn);
669 }
670 else
671 {
672 if (match->type == ZEBRA_ROUTE_CONNECT)
673 /* Directly point connected route. */
674 return match;
675 else
676 {
677 for (newhop = match->nexthop; newhop; newhop = newhop->next)
678 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
679 return match;
680 return NULL;
681 }
682 }
683 }
684 return NULL;
685}
686#endif /* HAVE_IPV6 */
687
paula1ac18c2005-06-28 17:17:12 +0000688static int
paul718e3742002-12-13 20:15:29 +0000689nexthop_active_check (struct route_node *rn, struct rib *rib,
690 struct nexthop *nexthop, int set)
691{
692 struct interface *ifp;
693
694 switch (nexthop->type)
695 {
696 case NEXTHOP_TYPE_IFINDEX:
697 ifp = if_lookup_by_index (nexthop->ifindex);
698 if (ifp && if_is_up (ifp))
699 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
700 else
701 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
702 break;
703 case NEXTHOP_TYPE_IFNAME:
704 case NEXTHOP_TYPE_IPV6_IFNAME:
705 ifp = if_lookup_by_name (nexthop->ifname);
706 if (ifp && if_is_up (ifp))
707 {
708 if (set)
709 nexthop->ifindex = ifp->ifindex;
710 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
711 }
712 else
713 {
714 if (set)
715 nexthop->ifindex = 0;
716 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
717 }
718 break;
719 case NEXTHOP_TYPE_IPV4:
720 case NEXTHOP_TYPE_IPV4_IFINDEX:
721 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
722 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
723 else
724 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
725 break;
726#ifdef HAVE_IPV6
727 case NEXTHOP_TYPE_IPV6:
728 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
729 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
730 else
731 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
732 break;
733 case NEXTHOP_TYPE_IPV6_IFINDEX:
734 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
735 {
736 ifp = if_lookup_by_index (nexthop->ifindex);
737 if (ifp && if_is_up (ifp))
738 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
739 else
740 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
741 }
742 else
743 {
744 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
745 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
746 else
747 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
748 }
749 break;
750#endif /* HAVE_IPV6 */
paul595db7f2003-05-25 21:35:06 +0000751 case NEXTHOP_TYPE_BLACKHOLE:
752 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
753 break;
paul718e3742002-12-13 20:15:29 +0000754 default:
755 break;
756 }
757 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
758}
759
paula1ac18c2005-06-28 17:17:12 +0000760static int
paul718e3742002-12-13 20:15:29 +0000761nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
762{
763 struct nexthop *nexthop;
764 int active;
765
766 rib->nexthop_active_num = 0;
767 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
768
769 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
770 {
771 active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
paul6baeb982003-10-28 03:47:15 +0000772
773 nexthop_active_check (rn, rib, nexthop, set);
774 if ((MULTIPATH_NUM == 0 || rib->nexthop_active_num < MULTIPATH_NUM)
775 && active != CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
776 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
777
778 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
779 rib->nexthop_active_num++;
paul718e3742002-12-13 20:15:29 +0000780 }
781 return rib->nexthop_active_num;
782}
paul6baeb982003-10-28 03:47:15 +0000783
paul718e3742002-12-13 20:15:29 +0000784
785#define RIB_SYSTEM_ROUTE(R) \
786 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
787
paul4d38fdb2005-04-28 17:35:14 +0000788static struct rib *
789rib_lock (struct rib *rib)
790{
791 assert (rib->lock >= 0);
792
793 rib->lock++;
794 return rib;
795}
796
797static struct rib *
798rib_unlock (struct rib *rib)
paul718e3742002-12-13 20:15:29 +0000799{
800 struct nexthop *nexthop;
801 struct nexthop *next;
paul4d38fdb2005-04-28 17:35:14 +0000802
803 assert (rib->lock > 0);
804 rib->lock--;
paul718e3742002-12-13 20:15:29 +0000805
paul4d38fdb2005-04-28 17:35:14 +0000806 if (rib->lock == 0)
paul718e3742002-12-13 20:15:29 +0000807 {
paul4d38fdb2005-04-28 17:35:14 +0000808 for (nexthop = rib->nexthop; nexthop; nexthop = next)
809 {
810 next = nexthop->next;
811 nexthop_free (nexthop);
812 }
813 XFREE (MTYPE_RIB, rib);
814 return NULL;
paul718e3742002-12-13 20:15:29 +0000815 }
paul4d38fdb2005-04-28 17:35:14 +0000816 return rib;
paul718e3742002-12-13 20:15:29 +0000817}
818
paula1ac18c2005-06-28 17:17:12 +0000819static void
paul718e3742002-12-13 20:15:29 +0000820rib_install_kernel (struct route_node *rn, struct rib *rib)
821{
822 int ret = 0;
823 struct nexthop *nexthop;
824
825 switch (PREFIX_FAMILY (&rn->p))
826 {
827 case AF_INET:
828 ret = kernel_add_ipv4 (&rn->p, rib);
829 break;
830#ifdef HAVE_IPV6
831 case AF_INET6:
832 ret = kernel_add_ipv6 (&rn->p, rib);
833 break;
834#endif /* HAVE_IPV6 */
835 }
836
837 if (ret < 0)
838 {
839 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
840 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
841 }
842}
843
844/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +0000845static int
paul718e3742002-12-13 20:15:29 +0000846rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
847{
848 int ret = 0;
849 struct nexthop *nexthop;
850
851 switch (PREFIX_FAMILY (&rn->p))
852 {
853 case AF_INET:
854 ret = kernel_delete_ipv4 (&rn->p, rib);
855 break;
856#ifdef HAVE_IPV6
857 case AF_INET6:
858 ret = kernel_delete_ipv6 (&rn->p, rib);
859 break;
860#endif /* HAVE_IPV6 */
861 }
862
863 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
864 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
865
866 return ret;
867}
868
869/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +0000870static void
paul718e3742002-12-13 20:15:29 +0000871rib_uninstall (struct route_node *rn, struct rib *rib)
872{
873 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
874 {
875 redistribute_delete (&rn->p, rib);
876 if (! RIB_SYSTEM_ROUTE (rib))
877 rib_uninstall_kernel (rn, rib);
878 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
879 }
880}
881
882/* Core function for processing routing information base. */
paula1ac18c2005-06-28 17:17:12 +0000883static wq_item_status
paul4d38fdb2005-04-28 17:35:14 +0000884rib_process (struct zebra_queue_node_t *qnode)
paul718e3742002-12-13 20:15:29 +0000885{
886 struct rib *rib;
887 struct rib *next;
888 struct rib *fib = NULL;
889 struct rib *select = NULL;
paul4d38fdb2005-04-28 17:35:14 +0000890 struct rib *del = qnode->del;
891 struct route_node *rn = qnode->node;
pauld753e9e2003-01-22 19:45:50 +0000892 int installed = 0;
893 struct nexthop *nexthop = NULL;
paul4d38fdb2005-04-28 17:35:14 +0000894
895 assert (rn);
896
897 /* possibly should lock and unlock rib on each iteration. however, for
898 * now, we assume called functions are synchronous and dont delete RIBs
899 * (as the work-queue deconstructor for this function is supposed to be
900 * the canonical 'delete' path for RIBs). Further if called functions
901 * below were to made asynchronous they should themselves acquire any
902 * locks/refcounts as needed and not depend on this caller to do it for
903 * them
904 */
paul718e3742002-12-13 20:15:29 +0000905 for (rib = rn->info; rib; rib = next)
906 {
907 next = rib->next;
pauld753e9e2003-01-22 19:45:50 +0000908
paul718e3742002-12-13 20:15:29 +0000909 /* Currently installed rib. */
910 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
paul7021c422003-07-15 12:52:22 +0000911 fib = rib;
paul4d38fdb2005-04-28 17:35:14 +0000912
paul718e3742002-12-13 20:15:29 +0000913 /* Skip unreachable nexthop. */
914 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +0000915 continue;
paul718e3742002-12-13 20:15:29 +0000916
917 /* Infinit distance. */
918 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +0000919 continue;
paul718e3742002-12-13 20:15:29 +0000920
921 /* Newly selected rib. */
922 if (! select || rib->distance < select->distance
paul7021c422003-07-15 12:52:22 +0000923 || rib->type == ZEBRA_ROUTE_CONNECT)
924 select = rib;
paul718e3742002-12-13 20:15:29 +0000925 }
paul4d38fdb2005-04-28 17:35:14 +0000926
paul718e3742002-12-13 20:15:29 +0000927 /* Deleted route check. */
928 if (del && CHECK_FLAG (del->flags, ZEBRA_FLAG_SELECTED))
929 fib = del;
paul4d38fdb2005-04-28 17:35:14 +0000930
931 /* We possibly should lock fib and select here However, all functions
932 * below are 'inline' and not asynchronous And if any were to be
933 * converted, they should manage references themselves really.. See
934 * previous comment above.
935 */
936
paul718e3742002-12-13 20:15:29 +0000937 /* Same route is selected. */
938 if (select && select == fib)
939 {
940 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +0000941 {
942 redistribute_delete (&rn->p, select);
943 if (! RIB_SYSTEM_ROUTE (select))
944 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +0000945
paul4d38fdb2005-04-28 17:35:14 +0000946 /* Set real nexthop. */
947 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +0000948
paul4d38fdb2005-04-28 17:35:14 +0000949 if (! RIB_SYSTEM_ROUTE (select))
950 rib_install_kernel (rn, select);
951 redistribute_add (&rn->p, select);
952 }
pauld753e9e2003-01-22 19:45:50 +0000953 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +0000954 {
955 /* Housekeeping code to deal with
956 race conditions in kernel with linux
957 netlink reporting interface up before IPv4 or IPv6 protocol
958 is ready to add routes.
959 This makes sure the routes are IN the kernel.
960 */
pauld753e9e2003-01-22 19:45:50 +0000961
paul4d38fdb2005-04-28 17:35:14 +0000962 for (nexthop = select->nexthop; nexthop; nexthop = nexthop->next)
963 {
964 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
965 installed = 1;
966 }
967 if (! installed)
968 rib_install_kernel (rn, select);
969 }
970 return WQ_SUCCESS;
paul718e3742002-12-13 20:15:29 +0000971 }
972
973 /* Uninstall old rib from forwarding table. */
974 if (fib)
975 {
976 redistribute_delete (&rn->p, fib);
977 if (! RIB_SYSTEM_ROUTE (fib))
978 rib_uninstall_kernel (rn, fib);
979 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
980
981 /* Set real nexthop. */
982 nexthop_active_update (rn, fib, 1);
983 }
984
985 /* Install new rib into forwarding table. */
986 if (select)
987 {
988 /* Set real nexthop. */
989 nexthop_active_update (rn, select, 1);
990
991 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +0000992 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +0000993 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
994 redistribute_add (&rn->p, select);
995 }
paul4d38fdb2005-04-28 17:35:14 +0000996
997 return WQ_SUCCESS;
998
999}
1000
1001/* Add work queue item to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001002static void
paul4d38fdb2005-04-28 17:35:14 +00001003rib_queue_add_qnode (struct zebra_t *zebra, struct zebra_queue_node_t *qnode)
1004{
1005 route_lock_node (qnode->node);
1006
1007 if (IS_ZEBRA_DEBUG_EVENT)
1008 zlog_info ("rib_queue_add_qnode: work queue added");
1009
1010 assert (zebra && qnode && qnode->node);
1011
1012 if (qnode->del)
1013 rib_lock (qnode->del);
1014
1015 if (zebra->ribq == NULL)
1016 {
1017 zlog_err ("rib_queue_add_qnode: ribq work_queue does not exist!");
1018 route_unlock_node (qnode->node);
1019 return;
1020 }
1021
1022 work_queue_add (zebra->ribq, qnode);
1023
1024 return;
1025}
1026
1027/* Add route node and rib to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001028static void
paul4d38fdb2005-04-28 17:35:14 +00001029rib_queue_add (struct zebra_t *zebra, struct route_node *rn, struct rib *del)
1030{
1031 struct zebra_queue_node_t *qnode;
1032
1033 assert (zebra && rn);
1034
1035 qnode = (struct zebra_queue_node_t *)
1036 XCALLOC (MTYPE_RIB_QUEUE, sizeof (struct zebra_queue_node_t));
1037
1038 if (qnode == NULL)
1039 {
1040 zlog_err ("rib_queue_add: failed to allocate queue node memory, %s",
1041 strerror (errno));
1042 return;
1043 }
1044
1045 qnode->node = rn;
1046 qnode->del = del;
1047
1048 rib_queue_add_qnode (zebra, qnode);
1049
1050 return;
1051}
1052
1053/* free zebra_queue_node_t */
paula1ac18c2005-06-28 17:17:12 +00001054static void
paul4d38fdb2005-04-28 17:35:14 +00001055rib_queue_qnode_del (struct zebra_queue_node_t *qnode)
1056{
1057 route_unlock_node (qnode->node);
1058
1059 if (qnode->del)
1060 rib_unlock (qnode->del);
1061
1062 XFREE (MTYPE_RIB_QUEUE, qnode);
1063}
1064
1065/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001066static void
paul4d38fdb2005-04-28 17:35:14 +00001067rib_queue_init (struct zebra_t *zebra)
1068{
1069 assert (zebra);
1070
1071 if (! (zebra->ribq = work_queue_new (zebra->master,
1072 "zebra_rib_work_queue")))
1073 {
1074 zlog_err ("rib_queue_init: could not initialise work queue!");
1075 return;
1076 }
1077
1078 /* fill in the work queue spec */
1079 zebra->ribq->spec.workfunc = (wq_item_status (*) (void *))&rib_process;
1080 zebra->ribq->spec.errorfunc = NULL;
1081 zebra->ribq->spec.del_item_data = (void (*) (void *)) &rib_queue_qnode_del;
1082 /* XXX: TODO: These should be runtime configurable via vty */
1083 zebra->ribq->spec.max_retries = 3;
1084 zebra->ribq->spec.hold = 500;
1085 zebra->ribq->spec.delay = 10;
1086
1087 return;
paul718e3742002-12-13 20:15:29 +00001088}
1089
1090/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001091static void
paul718e3742002-12-13 20:15:29 +00001092rib_addnode (struct route_node *rn, struct rib *rib)
1093{
1094 struct rib *head;
paul4d38fdb2005-04-28 17:35:14 +00001095
1096 assert (rib && rn);
1097
1098 rib_lock (rib);
1099 route_lock_node (rn);
1100
paul718e3742002-12-13 20:15:29 +00001101 head = rn->info;
1102 if (head)
1103 head->prev = rib;
1104 rib->next = head;
1105 rn->info = rib;
1106}
1107
paula1ac18c2005-06-28 17:17:12 +00001108static void
paul718e3742002-12-13 20:15:29 +00001109rib_delnode (struct route_node *rn, struct rib *rib)
1110{
paul4d38fdb2005-04-28 17:35:14 +00001111 assert (rn && rib);
1112
paul718e3742002-12-13 20:15:29 +00001113 if (rib->next)
1114 rib->next->prev = rib->prev;
1115 if (rib->prev)
1116 rib->prev->next = rib->next;
1117 else
1118 rn->info = rib->next;
paul4d38fdb2005-04-28 17:35:14 +00001119
1120 rib_unlock (rib);
1121 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001122}
1123
1124int
1125rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
1126 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
1127 u_int32_t metric, u_char distance)
1128{
1129 struct rib *rib;
1130 struct rib *same = NULL;
1131 struct route_table *table;
1132 struct route_node *rn;
1133 struct nexthop *nexthop;
1134
1135 /* Lookup table. */
1136 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1137 if (! table)
1138 return 0;
1139
1140 /* Make it sure prefixlen is applied to the prefix. */
1141 apply_mask_ipv4 (p);
1142
1143 /* Set default distance by route type. */
1144 if (distance == 0)
1145 {
1146 distance = route_info[type].distance;
1147
1148 /* iBGP distance is 200. */
1149 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1150 distance = 200;
1151 }
1152
1153 /* Lookup route node.*/
1154 rn = route_node_get (table, (struct prefix *) p);
1155
1156 /* If same type of route are installed, treat it as a implicit
1157 withdraw. */
1158 for (rib = rn->info; rib; rib = rib->next)
1159 {
1160 if (rib->type == ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001161 {
1162 nexthop = rib->nexthop;
paul718e3742002-12-13 20:15:29 +00001163
paul4d38fdb2005-04-28 17:35:14 +00001164 /* Duplicate connected route comes in. */
1165 if (rib->type == type
1166 && nexthop && nexthop->type == NEXTHOP_TYPE_IFINDEX
1167 && nexthop->ifindex == ifindex)
1168 {
1169 rib->refcnt++;
1170 return 0 ;
1171 }
1172 }
paul718e3742002-12-13 20:15:29 +00001173 else if (rib->type == type)
paul4d38fdb2005-04-28 17:35:14 +00001174 {
1175 same = rib;
1176 break;
1177 }
paul718e3742002-12-13 20:15:29 +00001178 }
1179
1180 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001181 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001182 rib->type = type;
1183 rib->distance = distance;
1184 rib->flags = flags;
1185 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001186 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001187 rib->nexthop_num = 0;
1188 rib->uptime = time (NULL);
1189
1190 /* Nexthop settings. */
1191 if (gate)
1192 {
1193 if (ifindex)
1194 nexthop_ipv4_ifindex_add (rib, gate, ifindex);
1195 else
1196 nexthop_ipv4_add (rib, gate);
1197 }
1198 else
1199 nexthop_ifindex_add (rib, ifindex);
1200
1201 /* If this route is kernel route, set FIB flag to the route. */
1202 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1203 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1204 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1205
1206 /* Link new rib to node.*/
1207 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001208
paul718e3742002-12-13 20:15:29 +00001209 /* Process this route node. */
paul4d38fdb2005-04-28 17:35:14 +00001210 rib_queue_add (&zebrad, rn, same);
1211
paul718e3742002-12-13 20:15:29 +00001212 /* Free implicit route.*/
1213 if (same)
paul4d38fdb2005-04-28 17:35:14 +00001214 rib_delnode (rn, same);
1215
1216 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001217 return 0;
1218}
1219
1220int
1221rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib)
1222{
1223 struct route_table *table;
1224 struct route_node *rn;
1225 struct rib *same;
1226 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00001227
paul718e3742002-12-13 20:15:29 +00001228 /* Lookup table. */
1229 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1230 if (! table)
1231 return 0;
paul718e3742002-12-13 20:15:29 +00001232 /* Make it sure prefixlen is applied to the prefix. */
1233 apply_mask_ipv4 (p);
1234
1235 /* Set default distance by route type. */
1236 if (rib->distance == 0)
1237 {
1238 rib->distance = route_info[rib->type].distance;
1239
1240 /* iBGP distance is 200. */
1241 if (rib->type == ZEBRA_ROUTE_BGP
1242 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1243 rib->distance = 200;
1244 }
1245
1246 /* Lookup route node.*/
1247 rn = route_node_get (table, (struct prefix *) p);
1248
1249 /* If same type of route are installed, treat it as a implicit
1250 withdraw. */
1251 for (same = rn->info; same; same = same->next)
1252 {
1253 if (same->type == rib->type && same->table == rib->table
1254 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001255 break;
paul718e3742002-12-13 20:15:29 +00001256 }
paul4d38fdb2005-04-28 17:35:14 +00001257
paul718e3742002-12-13 20:15:29 +00001258 /* If this route is kernel route, set FIB flag to the route. */
1259 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
1260 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1261 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1262
1263 /* Link new rib to node.*/
1264 rib_addnode (rn, rib);
1265
1266 /* Process this route node. */
paul4d38fdb2005-04-28 17:35:14 +00001267 rib_queue_add (&zebrad, rn, same);
paul718e3742002-12-13 20:15:29 +00001268
1269 /* Free implicit route.*/
1270 if (same)
paul4d38fdb2005-04-28 17:35:14 +00001271 rib_delnode (rn, same);
1272
1273 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001274 return 0;
1275}
1276
1277int
1278rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
1279 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1280{
1281 struct route_table *table;
1282 struct route_node *rn;
1283 struct rib *rib;
1284 struct rib *fib = NULL;
1285 struct rib *same = NULL;
1286 struct nexthop *nexthop;
1287 char buf1[BUFSIZ];
1288 char buf2[BUFSIZ];
1289
1290 /* Lookup table. */
1291 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1292 if (! table)
1293 return 0;
1294
1295 /* Apply mask. */
1296 apply_mask_ipv4 (p);
1297
paul5ec90d22003-06-19 01:41:37 +00001298 if (IS_ZEBRA_DEBUG_KERNEL && gate)
ajsb6178002004-12-07 21:12:56 +00001299 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
paul5ec90d22003-06-19 01:41:37 +00001300 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1301 p->prefixlen,
1302 inet_ntoa (*gate),
1303 ifindex);
1304
paul718e3742002-12-13 20:15:29 +00001305 /* Lookup route node. */
1306 rn = route_node_lookup (table, (struct prefix *) p);
1307 if (! rn)
1308 {
1309 if (IS_ZEBRA_DEBUG_KERNEL)
1310 {
1311 if (gate)
ajsb6178002004-12-07 21:12:56 +00001312 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001313 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1314 p->prefixlen,
1315 inet_ntop (AF_INET, gate, buf2, BUFSIZ),
1316 ifindex);
1317 else
ajsb6178002004-12-07 21:12:56 +00001318 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001319 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1320 p->prefixlen,
1321 ifindex);
1322 }
1323 return ZEBRA_ERR_RTNOEXIST;
1324 }
1325
1326 /* Lookup same type route. */
1327 for (rib = rn->info; rib; rib = rib->next)
1328 {
1329 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1330 fib = rib;
1331
1332 if (rib->type == ZEBRA_ROUTE_CONNECT)
1333 {
1334 nexthop = rib->nexthop;
1335
1336 if (rib->type == type
1337 && nexthop && nexthop->type == NEXTHOP_TYPE_IFINDEX
1338 && nexthop->ifindex == ifindex)
1339 {
1340 if (rib->refcnt)
1341 {
1342 rib->refcnt--;
1343 route_unlock_node (rn);
1344 route_unlock_node (rn);
1345 return 0;
1346 }
1347 same = rib;
1348 break;
1349 }
1350 }
paul5ec90d22003-06-19 01:41:37 +00001351 else if (gate)
1352 {
1353 nexthop = rib->nexthop;
1354
1355 /* Make sure that the route found has the same gateway. */
1356 if (rib->type == type
1357 && nexthop &&
1358 (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
1359 IPV4_ADDR_SAME (&nexthop->rgate.ipv4, gate)) )
1360 {
1361 same = rib;
1362 break;
1363 }
1364 }
paul718e3742002-12-13 20:15:29 +00001365 else
1366 {
1367 if (rib->type == type)
1368 {
1369 same = rib;
1370 break;
1371 }
1372 }
1373 }
1374
1375 /* If same type of route can't be found and this message is from
1376 kernel. */
1377 if (! same)
1378 {
1379 if (fib && type == ZEBRA_ROUTE_KERNEL)
1380 {
1381 /* Unset flags. */
1382 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1383 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1384
1385 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1386 }
1387 else
1388 {
1389 if (IS_ZEBRA_DEBUG_KERNEL)
1390 {
1391 if (gate)
ajsb6178002004-12-07 21:12:56 +00001392 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001393 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1394 p->prefixlen,
1395 inet_ntop (AF_INET, gate, buf2, BUFSIZ),
1396 ifindex,
1397 type);
1398 else
ajsb6178002004-12-07 21:12:56 +00001399 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001400 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1401 p->prefixlen,
1402 ifindex,
1403 type);
1404 }
1405 route_unlock_node (rn);
1406 return ZEBRA_ERR_RTNOEXIST;
1407 }
1408 }
paul4d38fdb2005-04-28 17:35:14 +00001409
1410 /* Process changes. */
1411 rib_queue_add (&zebrad, rn, same);
paul718e3742002-12-13 20:15:29 +00001412
1413 if (same)
1414 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00001415
paul718e3742002-12-13 20:15:29 +00001416 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001417 return 0;
1418}
1419
1420/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00001421static void
paul718e3742002-12-13 20:15:29 +00001422static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
1423{
1424 struct rib *rib;
1425 struct route_node *rn;
1426 struct route_table *table;
1427
1428 /* Lookup table. */
1429 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1430 if (! table)
1431 return;
1432
1433 /* Lookup existing route */
1434 rn = route_node_get (table, p);
1435 for (rib = rn->info; rib; rib = rib->next)
1436 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1437 break;
1438
1439 if (rib)
1440 {
1441 /* Same distance static route is there. Update it with new
1442 nexthop. */
paul718e3742002-12-13 20:15:29 +00001443 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001444 switch (si->type)
paul7021c422003-07-15 12:52:22 +00001445 {
1446 case STATIC_IPV4_GATEWAY:
1447 nexthop_ipv4_add (rib, &si->gate.ipv4);
1448 break;
1449 case STATIC_IPV4_IFNAME:
1450 nexthop_ifname_add (rib, si->gate.ifname);
1451 break;
1452 case STATIC_IPV4_BLACKHOLE:
1453 nexthop_blackhole_add (rib);
1454 break;
paul4d38fdb2005-04-28 17:35:14 +00001455 }
1456 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00001457 }
1458 else
1459 {
1460 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00001461 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
1462
paul718e3742002-12-13 20:15:29 +00001463 rib->type = ZEBRA_ROUTE_STATIC;
1464 rib->distance = si->distance;
1465 rib->metric = 0;
1466 rib->nexthop_num = 0;
1467
1468 switch (si->type)
paul7021c422003-07-15 12:52:22 +00001469 {
1470 case STATIC_IPV4_GATEWAY:
1471 nexthop_ipv4_add (rib, &si->gate.ipv4);
1472 break;
1473 case STATIC_IPV4_IFNAME:
1474 nexthop_ifname_add (rib, si->gate.ifname);
1475 break;
1476 case STATIC_IPV4_BLACKHOLE:
1477 nexthop_blackhole_add (rib);
1478 break;
1479 }
paul718e3742002-12-13 20:15:29 +00001480
hasso81dfcaa2003-05-25 19:21:25 +00001481 /* Save the flags of this static routes (reject, blackhole) */
1482 rib->flags = si->flags;
1483
paul718e3742002-12-13 20:15:29 +00001484 /* Link this rib to the tree. */
1485 rib_addnode (rn, rib);
1486
1487 /* Process this prefix. */
paul4d38fdb2005-04-28 17:35:14 +00001488 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00001489 }
1490}
1491
paula1ac18c2005-06-28 17:17:12 +00001492static int
paul718e3742002-12-13 20:15:29 +00001493static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
1494{
1495 if (nexthop->type == NEXTHOP_TYPE_IPV4
1496 && si->type == STATIC_IPV4_GATEWAY
1497 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
1498 return 1;
1499 if (nexthop->type == NEXTHOP_TYPE_IFNAME
1500 && si->type == STATIC_IPV4_IFNAME
1501 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
1502 return 1;
paul595db7f2003-05-25 21:35:06 +00001503 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
1504 && si->type == STATIC_IPV4_BLACKHOLE)
1505 return 1;
paul718e3742002-12-13 20:15:29 +00001506 return 0;;
1507}
1508
1509/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00001510static void
paul718e3742002-12-13 20:15:29 +00001511static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
1512{
1513 struct route_node *rn;
1514 struct rib *rib;
1515 struct nexthop *nexthop;
1516 struct route_table *table;
1517
1518 /* Lookup table. */
1519 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1520 if (! table)
1521 return;
paul4d38fdb2005-04-28 17:35:14 +00001522
paul718e3742002-12-13 20:15:29 +00001523 /* Lookup existing route with type and distance. */
1524 rn = route_node_lookup (table, p);
1525 if (! rn)
1526 return;
1527
1528 for (rib = rn->info; rib; rib = rib->next)
1529 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1530 break;
1531
1532 if (! rib)
1533 {
1534 route_unlock_node (rn);
1535 return;
1536 }
1537
1538 /* Lookup nexthop. */
1539 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1540 if (static_ipv4_nexthop_same (nexthop, si))
1541 break;
1542
1543 /* Can't find nexthop. */
1544 if (! nexthop)
1545 {
1546 route_unlock_node (rn);
1547 return;
1548 }
1549
1550 /* Check nexthop. */
1551 if (rib->nexthop_num == 1)
1552 {
paul4d38fdb2005-04-28 17:35:14 +00001553 rib_queue_add (&zebrad, rn, rib);
paul718e3742002-12-13 20:15:29 +00001554 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00001555 }
1556 else
1557 {
paul6baeb982003-10-28 03:47:15 +00001558 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1559 rib_uninstall (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001560 rib_queue_add (&zebrad, rn, rib);
paul718e3742002-12-13 20:15:29 +00001561 }
paul718e3742002-12-13 20:15:29 +00001562 /* Unlock node. */
1563 route_unlock_node (rn);
1564}
1565
1566/* Add static route into static route configuration. */
1567int
hasso39db97e2004-10-12 20:50:58 +00001568static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00001569 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001570{
1571 u_char type = 0;
1572 struct route_node *rn;
1573 struct static_ipv4 *si;
1574 struct static_ipv4 *pp;
1575 struct static_ipv4 *cp;
1576 struct static_ipv4 *update = NULL;
1577 struct route_table *stable;
1578
1579 /* Lookup table. */
1580 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
1581 if (! stable)
1582 return -1;
1583
1584 /* Lookup static route prefix. */
1585 rn = route_node_get (stable, p);
1586
1587 /* Make flags. */
1588 if (gate)
1589 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00001590 else if (ifname)
paul718e3742002-12-13 20:15:29 +00001591 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00001592 else
1593 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00001594
1595 /* Do nothing if there is a same static route. */
1596 for (si = rn->info; si; si = si->next)
1597 {
1598 if (type == si->type
1599 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
1600 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
1601 {
1602 if (distance == si->distance)
1603 {
1604 route_unlock_node (rn);
1605 return 0;
1606 }
1607 else
1608 update = si;
1609 }
1610 }
1611
1612 /* Distance chaged. */
1613 if (update)
1614 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
1615
1616 /* Make new static route structure. */
1617 si = XMALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
1618 memset (si, 0, sizeof (struct static_ipv4));
1619
1620 si->type = type;
1621 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00001622 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00001623
1624 if (gate)
1625 si->gate.ipv4 = *gate;
1626 if (ifname)
1627 si->gate.ifname = XSTRDUP (0, ifname);
1628
1629 /* Add new static route information to the tree with sort by
1630 distance value and gateway address. */
1631 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
1632 {
1633 if (si->distance < cp->distance)
1634 break;
1635 if (si->distance > cp->distance)
1636 continue;
1637 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
1638 {
1639 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
1640 break;
1641 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
1642 continue;
1643 }
1644 }
1645
1646 /* Make linked list. */
1647 if (pp)
1648 pp->next = si;
1649 else
1650 rn->info = si;
1651 if (cp)
1652 cp->prev = si;
1653 si->prev = pp;
1654 si->next = cp;
1655
1656 /* Install into rib. */
1657 static_install_ipv4 (p, si);
1658
1659 return 1;
1660}
1661
1662/* Delete static route from static route configuration. */
1663int
hasso39db97e2004-10-12 20:50:58 +00001664static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00001665 u_char distance, u_int32_t vrf_id)
1666{
1667 u_char type = 0;
1668 struct route_node *rn;
1669 struct static_ipv4 *si;
1670 struct route_table *stable;
1671
1672 /* Lookup table. */
1673 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
1674 if (! stable)
1675 return -1;
1676
1677 /* Lookup static route prefix. */
1678 rn = route_node_lookup (stable, p);
1679 if (! rn)
1680 return 0;
1681
1682 /* Make flags. */
1683 if (gate)
1684 type = STATIC_IPV4_GATEWAY;
1685 else if (ifname)
1686 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00001687 else
1688 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00001689
1690 /* Find same static route is the tree */
1691 for (si = rn->info; si; si = si->next)
1692 if (type == si->type
1693 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
1694 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
1695 break;
1696
1697 /* Can't find static route. */
1698 if (! si)
1699 {
1700 route_unlock_node (rn);
1701 return 0;
1702 }
1703
1704 /* Install into rib. */
1705 static_uninstall_ipv4 (p, si);
1706
1707 /* Unlink static route from linked list. */
1708 if (si->prev)
1709 si->prev->next = si->next;
1710 else
1711 rn->info = si->next;
1712 if (si->next)
1713 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00001714 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001715
1716 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00001717 if (ifname)
1718 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00001719 XFREE (MTYPE_STATIC_IPV4, si);
1720
paul143a3852003-09-29 20:06:13 +00001721 route_unlock_node (rn);
1722
paul718e3742002-12-13 20:15:29 +00001723 return 1;
1724}
1725
1726
1727#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00001728static int
paul718e3742002-12-13 20:15:29 +00001729rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
1730 struct in6_addr *gate, unsigned int ifindex, int table)
1731{
hasso726f9b22003-05-25 21:04:54 +00001732 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
1733#if defined (MUSICA) || defined (LINUX)
1734 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
1735 if (p->prefixlen == 96)
1736 return 0;
1737#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00001738 return 1;
hasso726f9b22003-05-25 21:04:54 +00001739 }
paul718e3742002-12-13 20:15:29 +00001740 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
1741 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
1742 {
1743 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
1744 return 1;
1745 }
1746 return 0;
1747}
1748
1749int
1750rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
1751 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1752{
1753 struct rib *rib;
1754 struct rib *same = NULL;
1755 struct route_table *table;
1756 struct route_node *rn;
1757 struct nexthop *nexthop;
1758
1759 int distance;
1760 u_int32_t metric = 0;
1761
1762 /* 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. */
1771 distance = route_info[type].distance;
1772
1773 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1774 distance = 200;
1775
1776 /* Filter bogus route. */
1777 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
1778 return 0;
1779
1780 /* Lookup route node.*/
1781 rn = route_node_get (table, (struct prefix *) p);
1782
1783 /* If same type of route are installed, treat it as a implicit
1784 withdraw. */
1785 for (rib = rn->info; rib; rib = rib->next)
1786 {
1787 if (rib->type == ZEBRA_ROUTE_CONNECT)
1788 {
1789 nexthop = rib->nexthop;
1790
1791 if (rib->type == type
1792 && nexthop && nexthop->type == NEXTHOP_TYPE_IFINDEX
1793 && nexthop->ifindex == ifindex)
1794 {
1795 rib->refcnt++;
1796 return 0;
1797 }
1798 }
1799 else if (rib->type == type)
1800 {
1801 same = rib;
paul718e3742002-12-13 20:15:29 +00001802 break;
1803 }
1804 }
1805
1806 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001807 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
1808
paul718e3742002-12-13 20:15:29 +00001809 rib->type = type;
1810 rib->distance = distance;
1811 rib->flags = flags;
1812 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001813 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001814 rib->nexthop_num = 0;
1815 rib->uptime = time (NULL);
1816
1817 /* Nexthop settings. */
1818 if (gate)
1819 {
1820 if (ifindex)
1821 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
1822 else
1823 nexthop_ipv6_add (rib, gate);
1824 }
1825 else
1826 nexthop_ifindex_add (rib, ifindex);
1827
1828 /* If this route is kernel route, set FIB flag to the route. */
1829 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1830 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1831 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1832
1833 /* Link new rib to node.*/
1834 rib_addnode (rn, rib);
1835
1836 /* Process this route node. */
paul4d38fdb2005-04-28 17:35:14 +00001837 rib_queue_add (&zebrad, rn, same);
1838
paul718e3742002-12-13 20:15:29 +00001839 /* Free implicit route.*/
1840 if (same)
paul4d38fdb2005-04-28 17:35:14 +00001841 rib_delnode (rn, same);
1842
1843 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001844 return 0;
1845}
1846
1847int
1848rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
1849 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1850{
1851 struct route_table *table;
1852 struct route_node *rn;
1853 struct rib *rib;
1854 struct rib *fib = NULL;
1855 struct rib *same = NULL;
1856 struct nexthop *nexthop;
1857 char buf1[BUFSIZ];
1858 char buf2[BUFSIZ];
1859
1860 /* Apply mask. */
1861 apply_mask_ipv6 (p);
1862
1863 /* Lookup table. */
1864 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1865 if (! table)
1866 return 0;
paul4d38fdb2005-04-28 17:35:14 +00001867
paul718e3742002-12-13 20:15:29 +00001868 /* Lookup route node. */
1869 rn = route_node_lookup (table, (struct prefix *) p);
1870 if (! rn)
1871 {
1872 if (IS_ZEBRA_DEBUG_KERNEL)
1873 {
1874 if (gate)
ajsb6178002004-12-07 21:12:56 +00001875 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001876 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1877 p->prefixlen,
1878 inet_ntop (AF_INET6, gate, buf2, BUFSIZ),
1879 ifindex);
1880 else
ajsb6178002004-12-07 21:12:56 +00001881 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001882 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1883 p->prefixlen,
1884 ifindex);
1885 }
1886 return ZEBRA_ERR_RTNOEXIST;
1887 }
1888
1889 /* Lookup same type route. */
1890 for (rib = rn->info; rib; rib = rib->next)
1891 {
1892 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1893 fib = rib;
1894
1895 if (rib->type == ZEBRA_ROUTE_CONNECT)
1896 {
1897 nexthop = rib->nexthop;
1898
1899 if (rib->type == type
1900 && nexthop && nexthop->type == NEXTHOP_TYPE_IFINDEX
1901 && nexthop->ifindex == ifindex)
1902 {
1903 if (rib->refcnt)
1904 {
1905 rib->refcnt--;
1906 route_unlock_node (rn);
1907 route_unlock_node (rn);
1908 return 0;
1909 }
1910 same = rib;
1911 break;
1912 }
1913 }
1914 else
1915 {
1916 if (rib->type == type)
1917 {
1918 same = rib;
1919 break;
1920 }
1921 }
1922 }
1923
1924 /* If same type of route can't be found and this message is from
1925 kernel. */
1926 if (! same)
1927 {
1928 if (fib && type == ZEBRA_ROUTE_KERNEL)
1929 {
1930 /* Unset flags. */
1931 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1932 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1933
1934 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1935 }
1936 else
1937 {
1938 if (IS_ZEBRA_DEBUG_KERNEL)
1939 {
1940 if (gate)
ajsb6178002004-12-07 21:12:56 +00001941 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001942 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1943 p->prefixlen,
1944 inet_ntop (AF_INET6, gate, buf2, BUFSIZ),
1945 ifindex,
1946 type);
1947 else
ajsb6178002004-12-07 21:12:56 +00001948 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001949 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
1950 p->prefixlen,
1951 ifindex,
1952 type);
1953 }
1954 route_unlock_node (rn);
1955 return ZEBRA_ERR_RTNOEXIST;
1956 }
1957 }
1958
paul4d38fdb2005-04-28 17:35:14 +00001959 /* Process changes. */
1960 rib_queue_add (&zebrad, rn, same);
1961
paul718e3742002-12-13 20:15:29 +00001962 if (same)
1963 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00001964
paul718e3742002-12-13 20:15:29 +00001965 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001966 return 0;
1967}
1968
1969/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00001970static void
paul718e3742002-12-13 20:15:29 +00001971static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
1972{
1973 struct rib *rib;
1974 struct route_table *table;
1975 struct route_node *rn;
1976
1977 /* Lookup table. */
1978 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1979 if (! table)
1980 return;
1981
1982 /* Lookup existing route */
1983 rn = route_node_get (table, p);
1984 for (rib = rn->info; rib; rib = rib->next)
1985 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1986 break;
1987
1988 if (rib)
1989 {
1990 /* Same distance static route is there. Update it with new
1991 nexthop. */
paul718e3742002-12-13 20:15:29 +00001992 route_unlock_node (rn);
1993
1994 switch (si->type)
1995 {
1996 case STATIC_IPV6_GATEWAY:
1997 nexthop_ipv6_add (rib, &si->ipv6);
1998 break;
1999 case STATIC_IPV6_IFNAME:
2000 nexthop_ifname_add (rib, si->ifname);
2001 break;
2002 case STATIC_IPV6_GATEWAY_IFNAME:
2003 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2004 break;
2005 }
paul4d38fdb2005-04-28 17:35:14 +00002006 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00002007 }
2008 else
2009 {
2010 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002011 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2012
paul718e3742002-12-13 20:15:29 +00002013 rib->type = ZEBRA_ROUTE_STATIC;
2014 rib->distance = si->distance;
2015 rib->metric = 0;
2016 rib->nexthop_num = 0;
2017
2018 switch (si->type)
2019 {
2020 case STATIC_IPV6_GATEWAY:
2021 nexthop_ipv6_add (rib, &si->ipv6);
2022 break;
2023 case STATIC_IPV6_IFNAME:
2024 nexthop_ifname_add (rib, si->ifname);
2025 break;
2026 case STATIC_IPV6_GATEWAY_IFNAME:
2027 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2028 break;
2029 }
2030
hasso81dfcaa2003-05-25 19:21:25 +00002031 /* Save the flags of this static routes (reject, blackhole) */
2032 rib->flags = si->flags;
2033
paul718e3742002-12-13 20:15:29 +00002034 /* Link this rib to the tree. */
2035 rib_addnode (rn, rib);
2036
2037 /* Process this prefix. */
paul4d38fdb2005-04-28 17:35:14 +00002038 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00002039 }
2040}
2041
paula1ac18c2005-06-28 17:17:12 +00002042static int
paul718e3742002-12-13 20:15:29 +00002043static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2044{
2045 if (nexthop->type == NEXTHOP_TYPE_IPV6
2046 && si->type == STATIC_IPV6_GATEWAY
2047 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2048 return 1;
2049 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2050 && si->type == STATIC_IPV6_IFNAME
2051 && strcmp (nexthop->ifname, si->ifname) == 0)
2052 return 1;
2053 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2054 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2055 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2056 && strcmp (nexthop->ifname, si->ifname) == 0)
2057 return 1;
2058 return 0;;
2059}
2060
paula1ac18c2005-06-28 17:17:12 +00002061static void
paul718e3742002-12-13 20:15:29 +00002062static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2063{
2064 struct route_table *table;
2065 struct route_node *rn;
2066 struct rib *rib;
2067 struct nexthop *nexthop;
2068
2069 /* Lookup table. */
2070 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2071 if (! table)
2072 return;
2073
2074 /* Lookup existing route with type and distance. */
2075 rn = route_node_lookup (table, (struct prefix *) p);
2076 if (! rn)
2077 return;
2078
2079 for (rib = rn->info; rib; rib = rib->next)
2080 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2081 break;
2082 if (! rib)
2083 {
2084 route_unlock_node (rn);
2085 return;
2086 }
2087
2088 /* Lookup nexthop. */
2089 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2090 if (static_ipv6_nexthop_same (nexthop, si))
2091 break;
2092
2093 /* Can't find nexthop. */
2094 if (! nexthop)
2095 {
2096 route_unlock_node (rn);
2097 return;
2098 }
2099
2100 /* Check nexthop. */
2101 if (rib->nexthop_num == 1)
2102 {
2103 rib_delnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00002104 rib_queue_add (&zebrad, rn, rib);
paul718e3742002-12-13 20:15:29 +00002105 }
2106 else
2107 {
paul6baeb982003-10-28 03:47:15 +00002108 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2109 rib_uninstall (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00002110 rib_queue_add (&zebrad, rn, rib);
paul718e3742002-12-13 20:15:29 +00002111 }
paul718e3742002-12-13 20:15:29 +00002112 /* Unlock node. */
2113 route_unlock_node (rn);
2114}
2115
2116/* Add static route into static route configuration. */
2117int
2118static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002119 const char *ifname, u_char flags, u_char distance,
2120 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002121{
2122 struct route_node *rn;
2123 struct static_ipv6 *si;
2124 struct static_ipv6 *pp;
2125 struct static_ipv6 *cp;
2126 struct route_table *stable;
2127
2128 /* Lookup table. */
2129 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2130 if (! stable)
2131 return -1;
2132
2133 /* Lookup static route prefix. */
2134 rn = route_node_get (stable, p);
2135
2136 /* Do nothing if there is a same static route. */
2137 for (si = rn->info; si; si = si->next)
2138 {
2139 if (distance == si->distance
2140 && type == si->type
2141 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2142 && (! ifname || strcmp (ifname, si->ifname) == 0))
2143 {
2144 route_unlock_node (rn);
2145 return 0;
2146 }
2147 }
2148
2149 /* Make new static route structure. */
2150 si = XMALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
2151 memset (si, 0, sizeof (struct static_ipv6));
2152
2153 si->type = type;
2154 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002155 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002156
2157 switch (type)
2158 {
2159 case STATIC_IPV6_GATEWAY:
2160 si->ipv6 = *gate;
2161 break;
2162 case STATIC_IPV6_IFNAME:
2163 si->ifname = XSTRDUP (0, ifname);
2164 break;
2165 case STATIC_IPV6_GATEWAY_IFNAME:
2166 si->ipv6 = *gate;
2167 si->ifname = XSTRDUP (0, ifname);
2168 break;
2169 }
2170
2171 /* Add new static route information to the tree with sort by
2172 distance value and gateway address. */
2173 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2174 {
2175 if (si->distance < cp->distance)
2176 break;
2177 if (si->distance > cp->distance)
2178 continue;
2179 }
2180
2181 /* Make linked list. */
2182 if (pp)
2183 pp->next = si;
2184 else
2185 rn->info = si;
2186 if (cp)
2187 cp->prev = si;
2188 si->prev = pp;
2189 si->next = cp;
2190
2191 /* Install into rib. */
2192 static_install_ipv6 (p, si);
2193
2194 return 1;
2195}
2196
2197/* Delete static route from static route configuration. */
2198int
2199static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002200 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002201{
2202 struct route_node *rn;
2203 struct static_ipv6 *si;
2204 struct route_table *stable;
2205
2206 /* Lookup table. */
2207 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2208 if (! stable)
2209 return -1;
2210
2211 /* Lookup static route prefix. */
2212 rn = route_node_lookup (stable, p);
2213 if (! rn)
2214 return 0;
2215
2216 /* Find same static route is the tree */
2217 for (si = rn->info; si; si = si->next)
2218 if (distance == si->distance
2219 && type == si->type
2220 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2221 && (! ifname || strcmp (ifname, si->ifname) == 0))
2222 break;
2223
2224 /* Can't find static route. */
2225 if (! si)
2226 {
2227 route_unlock_node (rn);
2228 return 0;
2229 }
2230
2231 /* Install into rib. */
2232 static_uninstall_ipv6 (p, si);
2233
2234 /* Unlink static route from linked list. */
2235 if (si->prev)
2236 si->prev->next = si->next;
2237 else
2238 rn->info = si->next;
2239 if (si->next)
2240 si->next->prev = si->prev;
2241
2242 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002243 if (ifname)
2244 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00002245 XFREE (MTYPE_STATIC_IPV6, si);
2246
2247 return 1;
2248}
2249#endif /* HAVE_IPV6 */
2250
2251/* RIB update function. */
2252void
paula1ac18c2005-06-28 17:17:12 +00002253rib_update (void)
paul718e3742002-12-13 20:15:29 +00002254{
2255 struct route_node *rn;
2256 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00002257
paul718e3742002-12-13 20:15:29 +00002258 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2259 if (table)
2260 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002261 if (rn->info)
2262 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00002263
2264 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2265 if (table)
2266 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002267 if (rn->info)
2268 rib_queue_add (&zebrad, rn, NULL);
paul718e3742002-12-13 20:15:29 +00002269}
2270
2271/* Interface goes up. */
paula1ac18c2005-06-28 17:17:12 +00002272static void
paul718e3742002-12-13 20:15:29 +00002273rib_if_up (struct interface *ifp)
2274{
2275 rib_update ();
2276}
2277
2278/* Interface goes down. */
paula1ac18c2005-06-28 17:17:12 +00002279static void
paul718e3742002-12-13 20:15:29 +00002280rib_if_down (struct interface *ifp)
2281{
2282 rib_update ();
2283}
2284
2285/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00002286static void
paul718e3742002-12-13 20:15:29 +00002287rib_weed_table (struct route_table *table)
2288{
2289 struct route_node *rn;
2290 struct rib *rib;
2291 struct rib *next;
2292
2293 if (table)
2294 for (rn = route_top (table); rn; rn = route_next (rn))
2295 for (rib = rn->info; rib; rib = next)
2296 {
2297 next = rib->next;
2298
paulb21b19c2003-06-15 01:28:29 +00002299 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00002300 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00002301 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002302 }
2303}
2304
2305/* Delete all routes from non main table. */
2306void
paula1ac18c2005-06-28 17:17:12 +00002307rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00002308{
2309 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2310 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2311}
2312
2313/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00002314static void
paul718e3742002-12-13 20:15:29 +00002315rib_sweep_table (struct route_table *table)
2316{
2317 struct route_node *rn;
2318 struct rib *rib;
2319 struct rib *next;
2320 int ret = 0;
2321
2322 if (table)
2323 for (rn = route_top (table); rn; rn = route_next (rn))
2324 for (rib = rn->info; rib; rib = next)
2325 {
2326 next = rib->next;
2327
2328 if (rib->type == ZEBRA_ROUTE_KERNEL &&
2329 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
2330 {
2331 ret = rib_uninstall_kernel (rn, rib);
2332 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00002333 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002334 }
2335 }
2336}
2337
2338/* Sweep all RIB tables. */
2339void
paula1ac18c2005-06-28 17:17:12 +00002340rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00002341{
2342 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2343 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2344}
2345
2346/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00002347static void
paul718e3742002-12-13 20:15:29 +00002348rib_close_table (struct route_table *table)
2349{
2350 struct route_node *rn;
2351 struct rib *rib;
2352
2353 if (table)
2354 for (rn = route_top (table); rn; rn = route_next (rn))
2355 for (rib = rn->info; rib; rib = rib->next)
2356 if (! RIB_SYSTEM_ROUTE (rib)
2357 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2358 rib_uninstall_kernel (rn, rib);
2359}
2360
2361/* Close all RIB tables. */
2362void
paula1ac18c2005-06-28 17:17:12 +00002363rib_close (void)
paul718e3742002-12-13 20:15:29 +00002364{
2365 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2366 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2367}
2368
2369/* Routing information base initialize. */
2370void
paula1ac18c2005-06-28 17:17:12 +00002371rib_init (void)
paul718e3742002-12-13 20:15:29 +00002372{
paul4d38fdb2005-04-28 17:35:14 +00002373 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00002374 /* VRF initialization. */
2375 vrf_init ();
2376}