]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_rib.c
[ospfd] Fix bad SPF calculation on some topologies - incorrect sorting
[mirror_frr.git] / zebra / zebra_rib.c
CommitLineData
718e3744 1/* 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"
4d38fdb4 32#include "linklist.h"
33#include "thread.h"
34#include "workqueue.h"
7514fb77
PJ
35#include "prefix.h"
36#include "routemap.h"
718e3744 37
38#include "zebra/rib.h"
39#include "zebra/rt.h"
40#include "zebra/zserv.h"
41#include "zebra/redistribute.h"
42#include "zebra/debug.h"
43
44/* Default rtm_table for all clients */
b21b19c5 45extern struct zebra_t zebrad;
718e3744 46
457eb9af
PJ
47/* Hold time for RIB process, should be very minimal.
48 * it is useful to able to set it otherwise for testing, hence exported
49 * as global here for test-rig code.
50 */
51int rib_process_hold_time = 10;
52
718e3744 53/* Each route type's string and default distance value. */
54struct
55{
56 int key;
57 int distance;
58} route_info[] =
59{
60 {ZEBRA_ROUTE_SYSTEM, 0},
61 {ZEBRA_ROUTE_KERNEL, 0},
62 {ZEBRA_ROUTE_CONNECT, 0},
63 {ZEBRA_ROUTE_STATIC, 1},
64 {ZEBRA_ROUTE_RIP, 120},
65 {ZEBRA_ROUTE_RIPNG, 120},
66 {ZEBRA_ROUTE_OSPF, 110},
67 {ZEBRA_ROUTE_OSPF6, 110},
9e867fe6 68 {ZEBRA_ROUTE_ISIS, 115},
718e3744 69 {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */}
70};
71\f
72/* Vector for routing table. */
73vector vrf_vector;
74
75/* Allocate new VRF. */
a1ac18c4 76static struct vrf *
fce954f8 77vrf_alloc (const char *name)
718e3744 78{
79 struct vrf *vrf;
80
81 vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
82
83 /* Put name. */
84 if (name)
85 vrf->name = XSTRDUP (MTYPE_VRF_NAME, name);
86
87 /* Allocate routing table and static table. */
88 vrf->table[AFI_IP][SAFI_UNICAST] = route_table_init ();
89 vrf->table[AFI_IP6][SAFI_UNICAST] = route_table_init ();
90 vrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
91 vrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
92
93 return vrf;
94}
95
96/* Free VRF. */
a1ac18c4 97static void
718e3744 98vrf_free (struct vrf *vrf)
99{
100 if (vrf->name)
101 XFREE (MTYPE_VRF_NAME, vrf->name);
102 XFREE (MTYPE_VRF, vrf);
103}
104
105/* Lookup VRF by identifier. */
106struct vrf *
107vrf_lookup (u_int32_t id)
108{
109 return vector_lookup (vrf_vector, id);
110}
111
112/* Lookup VRF by name. */
a1ac18c4 113static struct vrf *
718e3744 114vrf_lookup_by_name (char *name)
115{
fce954f8 116 unsigned int i;
718e3744 117 struct vrf *vrf;
118
55468c86 119 for (i = 0; i < vector_active (vrf_vector); i++)
718e3744 120 if ((vrf = vector_slot (vrf_vector, i)) != NULL)
121 if (vrf->name && name && strcmp (vrf->name, name) == 0)
122 return vrf;
123 return NULL;
124}
125
126/* Initialize VRF. */
a1ac18c4 127static void
128vrf_init (void)
718e3744 129{
130 struct vrf *default_table;
131
132 /* Allocate VRF vector. */
133 vrf_vector = vector_init (1);
134
135 /* Allocate default main table. */
136 default_table = vrf_alloc ("Default-IP-Routing-Table");
137
138 /* Default table index must be 0. */
139 vector_set_index (vrf_vector, 0, default_table);
140}
141
142/* Lookup route table. */
143struct route_table *
144vrf_table (afi_t afi, safi_t safi, u_int32_t id)
145{
146 struct vrf *vrf;
147
148 vrf = vrf_lookup (id);
149 if (! vrf)
150 return NULL;
151
152 return vrf->table[afi][safi];
153}
154
155/* Lookup static route table. */
156struct route_table *
157vrf_static_table (afi_t afi, safi_t safi, u_int32_t id)
158{
159 struct vrf *vrf;
160
161 vrf = vrf_lookup (id);
162 if (! vrf)
163 return NULL;
164
165 return vrf->stable[afi][safi];
166}
167\f
168/* Add nexthop to the end of the list. */
a1ac18c4 169static void
718e3744 170nexthop_add (struct rib *rib, struct nexthop *nexthop)
171{
172 struct nexthop *last;
173
174 for (last = rib->nexthop; last && last->next; last = last->next)
175 ;
176 if (last)
177 last->next = nexthop;
178 else
179 rib->nexthop = nexthop;
180 nexthop->prev = last;
181
182 rib->nexthop_num++;
183}
184
185/* Delete specified nexthop from the list. */
a1ac18c4 186static void
718e3744 187nexthop_delete (struct rib *rib, struct nexthop *nexthop)
188{
189 if (nexthop->next)
190 nexthop->next->prev = nexthop->prev;
191 if (nexthop->prev)
192 nexthop->prev->next = nexthop->next;
193 else
194 rib->nexthop = nexthop->next;
195 rib->nexthop_num--;
196}
197
198/* Free nexthop. */
a1ac18c4 199static void
718e3744 200nexthop_free (struct nexthop *nexthop)
201{
a4b70768 202 if (nexthop->ifname)
203 XFREE (0, nexthop->ifname);
718e3744 204 XFREE (MTYPE_NEXTHOP, nexthop);
205}
206
207struct nexthop *
208nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
209{
210 struct nexthop *nexthop;
211
212 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
213 memset (nexthop, 0, sizeof (struct nexthop));
214 nexthop->type = NEXTHOP_TYPE_IFINDEX;
215 nexthop->ifindex = ifindex;
216
217 nexthop_add (rib, nexthop);
218
219 return nexthop;
220}
221
222struct nexthop *
223nexthop_ifname_add (struct rib *rib, char *ifname)
224{
225 struct nexthop *nexthop;
226
227 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
228 memset (nexthop, 0, sizeof (struct nexthop));
229 nexthop->type = NEXTHOP_TYPE_IFNAME;
a4b70768 230 nexthop->ifname = XSTRDUP (0, ifname);
718e3744 231
232 nexthop_add (rib, nexthop);
233
234 return nexthop;
235}
236
237struct nexthop *
7514fb77 238nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src)
718e3744 239{
240 struct nexthop *nexthop;
241
242 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
243 memset (nexthop, 0, sizeof (struct nexthop));
244 nexthop->type = NEXTHOP_TYPE_IPV4;
245 nexthop->gate.ipv4 = *ipv4;
7514fb77
PJ
246 if (src)
247 nexthop->src.ipv4 = *src;
718e3744 248
249 nexthop_add (rib, nexthop);
250
251 return nexthop;
252}
253
a1ac18c4 254static struct nexthop *
718e3744 255nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
7514fb77 256 struct in_addr *src, unsigned int ifindex)
718e3744 257{
258 struct nexthop *nexthop;
259
260 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
261 memset (nexthop, 0, sizeof (struct nexthop));
262 nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
263 nexthop->gate.ipv4 = *ipv4;
7514fb77
PJ
264 if (src)
265 nexthop->src.ipv4 = *src;
718e3744 266 nexthop->ifindex = ifindex;
267
268 nexthop_add (rib, nexthop);
269
270 return nexthop;
271}
272
273#ifdef HAVE_IPV6
274struct nexthop *
275nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
276{
277 struct nexthop *nexthop;
278
279 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
280 memset (nexthop, 0, sizeof (struct nexthop));
281 nexthop->type = NEXTHOP_TYPE_IPV6;
282 nexthop->gate.ipv6 = *ipv6;
283
284 nexthop_add (rib, nexthop);
285
286 return nexthop;
287}
288
a1ac18c4 289static struct nexthop *
718e3744 290nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
291 char *ifname)
292{
293 struct nexthop *nexthop;
294
295 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
296 memset (nexthop, 0, sizeof (struct nexthop));
297 nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
298 nexthop->gate.ipv6 = *ipv6;
299 nexthop->ifname = XSTRDUP (0, ifname);
300
301 nexthop_add (rib, nexthop);
302
303 return nexthop;
304}
305
a1ac18c4 306static struct nexthop *
718e3744 307nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
308 unsigned int ifindex)
309{
310 struct nexthop *nexthop;
311
312 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
313 memset (nexthop, 0, sizeof (struct nexthop));
314 nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
315 nexthop->gate.ipv6 = *ipv6;
316 nexthop->ifindex = ifindex;
317
318 nexthop_add (rib, nexthop);
319
320 return nexthop;
321}
322#endif /* HAVE_IPV6 */
323
595db7f1 324struct nexthop *
325nexthop_blackhole_add (struct rib *rib)
326{
327 struct nexthop *nexthop;
328
329 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
330 memset (nexthop, 0, sizeof (struct nexthop));
331 nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
332 SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
333
334 nexthop_add (rib, nexthop);
335
336 return nexthop;
337}
338
718e3744 339/* If force flag is not set, do not modify falgs at all for uninstall
340 the route from FIB. */
a1ac18c4 341static int
718e3744 342nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
343 struct route_node *top)
344{
345 struct prefix_ipv4 p;
346 struct route_table *table;
347 struct route_node *rn;
348 struct rib *match;
349 struct nexthop *newhop;
350
351 if (nexthop->type == NEXTHOP_TYPE_IPV4)
352 nexthop->ifindex = 0;
353
354 if (set)
355 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
356
357 /* Make lookup prefix. */
358 memset (&p, 0, sizeof (struct prefix_ipv4));
359 p.family = AF_INET;
360 p.prefixlen = IPV4_MAX_PREFIXLEN;
361 p.prefix = nexthop->gate.ipv4;
362
363 /* Lookup table. */
364 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
365 if (! table)
366 return 0;
367
368 rn = route_node_match (table, (struct prefix *) &p);
369 while (rn)
370 {
371 route_unlock_node (rn);
372
373 /* If lookup self prefix return immidiately. */
374 if (rn == top)
375 return 0;
376
377 /* Pick up selected route. */
378 for (match = rn->info; match; match = match->next)
379 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
380 break;
381
382 /* If there is no selected route or matched route is EGP, go up
383 tree. */
384 if (! match
385 || match->type == ZEBRA_ROUTE_BGP)
386 {
387 do {
388 rn = rn->parent;
389 } while (rn && rn->info == NULL);
390 if (rn)
391 route_lock_node (rn);
392 }
393 else
394 {
395 if (match->type == ZEBRA_ROUTE_CONNECT)
396 {
397 /* Directly point connected route. */
398 newhop = match->nexthop;
399 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
400 nexthop->ifindex = newhop->ifindex;
401
402 return 1;
403 }
404 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
405 {
406 for (newhop = match->nexthop; newhop; newhop = newhop->next)
407 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
408 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
409 {
410 if (set)
411 {
412 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
413 nexthop->rtype = newhop->type;
414 if (newhop->type == NEXTHOP_TYPE_IPV4 ||
415 newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
416 nexthop->rgate.ipv4 = newhop->gate.ipv4;
417 if (newhop->type == NEXTHOP_TYPE_IFINDEX
418 || newhop->type == NEXTHOP_TYPE_IFNAME
419 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
420 nexthop->rifindex = newhop->ifindex;
421 }
422 return 1;
423 }
424 return 0;
425 }
426 else
427 {
428 return 0;
429 }
430 }
431 }
432 return 0;
433}
434
435#ifdef HAVE_IPV6
436/* If force flag is not set, do not modify falgs at all for uninstall
437 the route from FIB. */
a1ac18c4 438static int
718e3744 439nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
440 struct route_node *top)
441{
442 struct prefix_ipv6 p;
443 struct route_table *table;
444 struct route_node *rn;
445 struct rib *match;
446 struct nexthop *newhop;
447
448 if (nexthop->type == NEXTHOP_TYPE_IPV6)
449 nexthop->ifindex = 0;
450
451 if (set)
452 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
453
454 /* Make lookup prefix. */
455 memset (&p, 0, sizeof (struct prefix_ipv6));
456 p.family = AF_INET6;
457 p.prefixlen = IPV6_MAX_PREFIXLEN;
458 p.prefix = nexthop->gate.ipv6;
459
460 /* Lookup table. */
461 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
462 if (! table)
463 return 0;
464
465 rn = route_node_match (table, (struct prefix *) &p);
466 while (rn)
467 {
468 route_unlock_node (rn);
469
470 /* If lookup self prefix return immidiately. */
471 if (rn == top)
472 return 0;
473
474 /* Pick up selected route. */
475 for (match = rn->info; match; match = match->next)
476 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
477 break;
478
479 /* If there is no selected route or matched route is EGP, go up
480 tree. */
481 if (! match
482 || match->type == ZEBRA_ROUTE_BGP)
483 {
484 do {
485 rn = rn->parent;
486 } while (rn && rn->info == NULL);
487 if (rn)
488 route_lock_node (rn);
489 }
490 else
491 {
492 if (match->type == ZEBRA_ROUTE_CONNECT)
493 {
494 /* Directly point connected route. */
495 newhop = match->nexthop;
496
497 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
498 nexthop->ifindex = newhop->ifindex;
499
500 return 1;
501 }
502 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
503 {
504 for (newhop = match->nexthop; newhop; newhop = newhop->next)
505 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
506 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
507 {
508 if (set)
509 {
510 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
511 nexthop->rtype = newhop->type;
512 if (newhop->type == NEXTHOP_TYPE_IPV6
513 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
514 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
515 nexthop->rgate.ipv6 = newhop->gate.ipv6;
516 if (newhop->type == NEXTHOP_TYPE_IFINDEX
517 || newhop->type == NEXTHOP_TYPE_IFNAME
518 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
519 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
520 nexthop->rifindex = newhop->ifindex;
521 }
522 return 1;
523 }
524 return 0;
525 }
526 else
527 {
528 return 0;
529 }
530 }
531 }
532 return 0;
533}
534#endif /* HAVE_IPV6 */
535
536struct rib *
537rib_match_ipv4 (struct in_addr addr)
538{
539 struct prefix_ipv4 p;
540 struct route_table *table;
541 struct route_node *rn;
542 struct rib *match;
543 struct nexthop *newhop;
544
545 /* Lookup table. */
546 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
547 if (! table)
548 return 0;
549
550 memset (&p, 0, sizeof (struct prefix_ipv4));
551 p.family = AF_INET;
552 p.prefixlen = IPV4_MAX_PREFIXLEN;
553 p.prefix = addr;
554
555 rn = route_node_match (table, (struct prefix *) &p);
556
557 while (rn)
558 {
559 route_unlock_node (rn);
560
561 /* Pick up selected route. */
562 for (match = rn->info; match; match = match->next)
563 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
564 break;
565
566 /* If there is no selected route or matched route is EGP, go up
567 tree. */
568 if (! match
569 || match->type == ZEBRA_ROUTE_BGP)
570 {
571 do {
572 rn = rn->parent;
573 } while (rn && rn->info == NULL);
574 if (rn)
575 route_lock_node (rn);
576 }
577 else
578 {
579 if (match->type == ZEBRA_ROUTE_CONNECT)
580 /* Directly point connected route. */
581 return match;
582 else
583 {
584 for (newhop = match->nexthop; newhop; newhop = newhop->next)
585 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
586 return match;
587 return NULL;
588 }
589 }
590 }
591 return NULL;
592}
593
594struct rib *
595rib_lookup_ipv4 (struct prefix_ipv4 *p)
596{
597 struct route_table *table;
598 struct route_node *rn;
599 struct rib *match;
600 struct nexthop *nexthop;
601
602 /* Lookup table. */
603 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
604 if (! table)
605 return 0;
606
607 rn = route_node_lookup (table, (struct prefix *) p);
608
609 /* No route for this prefix. */
610 if (! rn)
611 return NULL;
612
613 /* Unlock node. */
614 route_unlock_node (rn);
615
616 /* Pick up selected route. */
617 for (match = rn->info; match; match = match->next)
618 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
619 break;
620
621 if (! match || match->type == ZEBRA_ROUTE_BGP)
622 return NULL;
623
624 if (match->type == ZEBRA_ROUTE_CONNECT)
625 return match;
626
627 for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
628 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
629 return match;
630
631 return NULL;
632}
633
634#ifdef HAVE_IPV6
635struct rib *
636rib_match_ipv6 (struct in6_addr *addr)
637{
638 struct prefix_ipv6 p;
639 struct route_table *table;
640 struct route_node *rn;
641 struct rib *match;
642 struct nexthop *newhop;
643
644 /* Lookup table. */
645 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
646 if (! table)
647 return 0;
648
649 memset (&p, 0, sizeof (struct prefix_ipv6));
650 p.family = AF_INET6;
651 p.prefixlen = IPV6_MAX_PREFIXLEN;
652 IPV6_ADDR_COPY (&p.prefix, addr);
653
654 rn = route_node_match (table, (struct prefix *) &p);
655
656 while (rn)
657 {
658 route_unlock_node (rn);
659
660 /* Pick up selected route. */
661 for (match = rn->info; match; match = match->next)
662 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
663 break;
664
665 /* If there is no selected route or matched route is EGP, go up
666 tree. */
667 if (! match
668 || match->type == ZEBRA_ROUTE_BGP)
669 {
670 do {
671 rn = rn->parent;
672 } while (rn && rn->info == NULL);
673 if (rn)
674 route_lock_node (rn);
675 }
676 else
677 {
678 if (match->type == ZEBRA_ROUTE_CONNECT)
679 /* Directly point connected route. */
680 return match;
681 else
682 {
683 for (newhop = match->nexthop; newhop; newhop = newhop->next)
684 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
685 return match;
686 return NULL;
687 }
688 }
689 }
690 return NULL;
691}
692#endif /* HAVE_IPV6 */
693
7514fb77
PJ
694#define RIB_SYSTEM_ROUTE(R) \
695 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
696
a1ac18c4 697static int
718e3744 698nexthop_active_check (struct route_node *rn, struct rib *rib,
699 struct nexthop *nexthop, int set)
700{
701 struct interface *ifp;
7514fb77
PJ
702 route_map_result_t ret = RMAP_MATCH;
703 extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
704 struct route_map *rmap;
705 int family;
718e3744 706
7514fb77 707 family = 0;
718e3744 708 switch (nexthop->type)
709 {
710 case NEXTHOP_TYPE_IFINDEX:
711 ifp = if_lookup_by_index (nexthop->ifindex);
712 if (ifp && if_is_up (ifp))
713 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
714 else
715 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
716 break;
718e3744 717 case NEXTHOP_TYPE_IPV6_IFNAME:
7514fb77
PJ
718 family = AFI_IP6;
719 case NEXTHOP_TYPE_IFNAME:
718e3744 720 ifp = if_lookup_by_name (nexthop->ifname);
721 if (ifp && if_is_up (ifp))
722 {
723 if (set)
724 nexthop->ifindex = ifp->ifindex;
725 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
726 }
727 else
728 {
729 if (set)
730 nexthop->ifindex = 0;
731 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
732 }
733 break;
734 case NEXTHOP_TYPE_IPV4:
735 case NEXTHOP_TYPE_IPV4_IFINDEX:
7514fb77 736 family = AFI_IP;
718e3744 737 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
738 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
739 else
740 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
741 break;
742#ifdef HAVE_IPV6
743 case NEXTHOP_TYPE_IPV6:
7514fb77 744 family = AFI_IP6;
718e3744 745 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
746 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
747 else
748 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
749 break;
750 case NEXTHOP_TYPE_IPV6_IFINDEX:
7514fb77 751 family = AFI_IP6;
718e3744 752 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
753 {
754 ifp = if_lookup_by_index (nexthop->ifindex);
755 if (ifp && if_is_up (ifp))
756 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
757 else
758 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
759 }
760 else
761 {
762 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
763 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
764 else
765 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
766 }
767 break;
768#endif /* HAVE_IPV6 */
595db7f1 769 case NEXTHOP_TYPE_BLACKHOLE:
770 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
771 break;
718e3744 772 default:
773 break;
774 }
7514fb77
PJ
775 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
776 return 0;
777
778 if (RIB_SYSTEM_ROUTE(rib) ||
779 (family == AFI_IP && rn->p.family != AF_INET) ||
780 (family == AFI_IP6 && rn->p.family != AF_INET6))
781 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
782
783 rmap = 0;
784 if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
785 proto_rm[family][rib->type])
786 rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
787 if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
788 rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
789 if (rmap) {
790 ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, nexthop);
791 }
792
793 if (ret == RMAP_DENYMATCH)
794 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
718e3744 795 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
796}
797
a1ac18c4 798static int
718e3744 799nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
800{
801 struct nexthop *nexthop;
802 int active;
803
804 rib->nexthop_active_num = 0;
805 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
806
807 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
808 {
809 active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
6baeb988 810
811 nexthop_active_check (rn, rib, nexthop, set);
812 if ((MULTIPATH_NUM == 0 || rib->nexthop_active_num < MULTIPATH_NUM)
813 && active != CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
814 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
815
816 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
817 rib->nexthop_active_num++;
718e3744 818 }
819 return rib->nexthop_active_num;
820}
6baeb988 821
718e3744 822\f
718e3744 823
a1ac18c4 824static void
718e3744 825rib_install_kernel (struct route_node *rn, struct rib *rib)
826{
827 int ret = 0;
828 struct nexthop *nexthop;
829
830 switch (PREFIX_FAMILY (&rn->p))
831 {
832 case AF_INET:
833 ret = kernel_add_ipv4 (&rn->p, rib);
834 break;
835#ifdef HAVE_IPV6
836 case AF_INET6:
837 ret = kernel_add_ipv6 (&rn->p, rib);
838 break;
839#endif /* HAVE_IPV6 */
840 }
841
842 if (ret < 0)
843 {
844 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
845 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
846 }
847}
848
849/* Uninstall the route from kernel. */
a1ac18c4 850static int
718e3744 851rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
852{
853 int ret = 0;
854 struct nexthop *nexthop;
855
856 switch (PREFIX_FAMILY (&rn->p))
857 {
858 case AF_INET:
859 ret = kernel_delete_ipv4 (&rn->p, rib);
860 break;
861#ifdef HAVE_IPV6
862 case AF_INET6:
863 ret = kernel_delete_ipv6 (&rn->p, rib);
864 break;
865#endif /* HAVE_IPV6 */
866 }
867
868 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
869 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
870
871 return ret;
872}
873
874/* Uninstall the route from kernel. */
a1ac18c4 875static void
718e3744 876rib_uninstall (struct route_node *rn, struct rib *rib)
877{
878 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
879 {
880 redistribute_delete (&rn->p, rib);
881 if (! RIB_SYSTEM_ROUTE (rib))
882 rib_uninstall_kernel (rn, rib);
883 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
884 }
885}
886
6d691129
PJ
887static void rib_unlink (struct route_node *, struct rib *);
888
718e3744 889/* Core function for processing routing information base. */
a1ac18c4 890static wq_item_status
0fb58d5d 891rib_process (struct work_queue *wq, void *data)
718e3744 892{
893 struct rib *rib;
894 struct rib *next;
895 struct rib *fib = NULL;
896 struct rib *select = NULL;
6d691129
PJ
897 struct rib *del = NULL;
898 struct route_node *rn = data;
d753e9ee 899 int installed = 0;
900 struct nexthop *nexthop = NULL;
4d38fdb4 901
902 assert (rn);
903
718e3744 904 for (rib = rn->info; rib; rib = next)
905 {
906 next = rib->next;
d753e9ee 907
718e3744 908 /* Currently installed rib. */
909 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
6d691129
PJ
910 {
911 assert (fib == NULL);
912 fib = rib;
913 }
914
915 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
916 * which we need to do do further work with below.
917 */
918 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
919 {
920 if (rib != fib)
921 {
922 if (IS_ZEBRA_DEBUG_RIB)
923 zlog_debug ("%s: rn %p, removing rib %p", __func__, rn, rib);
924 rib_unlink (rn, rib);
925 }
926 else
927 del = rib;
928
929 continue;
930 }
4d38fdb4 931
718e3744 932 /* Skip unreachable nexthop. */
933 if (! nexthop_active_update (rn, rib, 0))
7021c425 934 continue;
718e3744 935
936 /* Infinit distance. */
937 if (rib->distance == DISTANCE_INFINITY)
7021c425 938 continue;
718e3744 939
af887b51 940 /* Newly selected rib, the common case. */
941 if (!select)
942 {
943 select = rib;
944 continue;
945 }
946
947 /* filter route selection in following order:
af887b51 948 * - connected beats other types
a8d9c1f9 949 * - lower distance beats higher
af887b51 950 * - lower metric beats higher for equal distance
951 * - last, hence oldest, route wins tie break.
952 */
a1038a15 953
954 /* Connected routes. Pick the last connected
955 * route of the set of lowest metric connected routes.
956 */
a8d9c1f9 957 if (rib->type == ZEBRA_ROUTE_CONNECT)
958 {
a1038a15 959 if (select->type != ZEBRA_ROUTE_CONNECT
a8d9c1f9 960 || rib->metric <= select->metric)
a1038a15 961 select = rib;
962 continue;
a8d9c1f9 963 }
964 else if (select->type == ZEBRA_ROUTE_CONNECT)
965 continue;
966
967 /* higher distance loses */
968 if (rib->distance > select->distance)
969 continue;
970
971 /* lower wins */
972 if (rib->distance < select->distance)
973 {
af887b51 974 select = rib;
a8d9c1f9 975 continue;
976 }
977
978 /* metric tie-breaks equal distance */
979 if (rib->metric <= select->metric)
980 select = rib;
718e3744 981 }
4d38fdb4 982
718e3744 983 /* Same route is selected. */
984 if (select && select == fib)
985 {
6d691129
PJ
986 if (IS_ZEBRA_DEBUG_RIB)
987 zlog_debug ("%s: Updating existing route, select %p, fib %p",
988 __func__, select, fib);
718e3744 989 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
4d38fdb4 990 {
991 redistribute_delete (&rn->p, select);
992 if (! RIB_SYSTEM_ROUTE (select))
993 rib_uninstall_kernel (rn, select);
718e3744 994
4d38fdb4 995 /* Set real nexthop. */
996 nexthop_active_update (rn, select, 1);
718e3744 997
4d38fdb4 998 if (! RIB_SYSTEM_ROUTE (select))
999 rib_install_kernel (rn, select);
1000 redistribute_add (&rn->p, select);
1001 }
d753e9ee 1002 else if (! RIB_SYSTEM_ROUTE (select))
4d38fdb4 1003 {
1004 /* Housekeeping code to deal with
1005 race conditions in kernel with linux
1006 netlink reporting interface up before IPv4 or IPv6 protocol
1007 is ready to add routes.
1008 This makes sure the routes are IN the kernel.
1009 */
1010
1011 for (nexthop = select->nexthop; nexthop; nexthop = nexthop->next)
1012 {
1013 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1014 installed = 1;
1015 }
1016 if (! installed)
1017 rib_install_kernel (rn, select);
1018 }
6d691129 1019 goto end;
718e3744 1020 }
1021
1022 /* Uninstall old rib from forwarding table. */
1023 if (fib)
1024 {
6d691129
PJ
1025 if (IS_ZEBRA_DEBUG_RIB)
1026 zlog_debug ("%s: Removing existing route, fib %p", __func__, fib);
718e3744 1027 redistribute_delete (&rn->p, fib);
1028 if (! RIB_SYSTEM_ROUTE (fib))
1029 rib_uninstall_kernel (rn, fib);
1030 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1031
1032 /* Set real nexthop. */
1033 nexthop_active_update (rn, fib, 1);
1034 }
1035
1036 /* Install new rib into forwarding table. */
1037 if (select)
1038 {
6d691129
PJ
1039 if (IS_ZEBRA_DEBUG_RIB)
1040 zlog_debug ("%s: Adding route, select %p", __func__, select);
718e3744 1041 /* Set real nexthop. */
1042 nexthop_active_update (rn, select, 1);
1043
1044 if (! RIB_SYSTEM_ROUTE (select))
4d38fdb4 1045 rib_install_kernel (rn, select);
718e3744 1046 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1047 redistribute_add (&rn->p, select);
1048 }
4d38fdb4 1049
6d691129
PJ
1050 /* FIB route was removed, should be deleted */
1051 if (del)
1052 {
1053 if (IS_ZEBRA_DEBUG_RIB)
1054 zlog_debug ("%s: Deleting fib %p, rn %p", __func__, del, rn);
1055 rib_unlink (rn, del);
1056 }
4d38fdb4 1057
6d691129
PJ
1058end:
1059 if (IS_ZEBRA_DEBUG_RIB_Q)
1060 zlog_debug ("%s: rn %p dequeued", __func__, rn);
1061 if (rn->info)
1062 UNSET_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED);
1063 route_unlock_node (rn); /* rib queue lock */
1064 return WQ_SUCCESS;
4d38fdb4 1065}
1066
6d691129 1067/* Add route_node to work queue and schedule processing */
a1ac18c4 1068static void
6d691129 1069rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
4d38fdb4 1070{
6d691129 1071 assert (zebra && rn);
4d38fdb4 1072
6d691129
PJ
1073 /* Pointless to queue a route_node with no RIB entries to add or remove */
1074 if (!rn->info)
1075 {
1076 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1077 __func__, rn, rn->lock);
1078 zlog_backtrace(LOG_DEBUG);
1079 return;
1080 }
1081
1082 /* Route-table node already queued, so nothing to do */
1083 if (CHECK_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED))
1084 {
1085 if (IS_ZEBRA_DEBUG_RIB_Q)
1086 zlog_debug ("%s: rn %p already queued", __func__, rn);
1087 return;
1088 }
4d38fdb4 1089
6d691129
PJ
1090 route_lock_node (rn); /* rib queue lock */
1091
1092 if (IS_ZEBRA_DEBUG_RIB_Q)
1093 zlog_info ("%s: work queue added", __func__);
1094
1095 assert (zebra);
4d38fdb4 1096
4d38fdb4 1097 if (zebra->ribq == NULL)
1098 {
6d691129
PJ
1099 zlog_err ("%s: work_queue does not exist!", __func__);
1100 route_unlock_node (rn);
4d38fdb4 1101 return;
1102 }
1103
6d691129 1104 work_queue_add (zebra->ribq, rn);
4d38fdb4 1105
6d691129 1106 SET_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED);
4d38fdb4 1107
6d691129
PJ
1108 if (IS_ZEBRA_DEBUG_RIB_Q)
1109 zlog_debug ("%s: rn %p queued", __func__, rn);
4d38fdb4 1110
6d691129 1111 return;
4d38fdb4 1112}
1113
1114/* initialise zebra rib work queue */
a1ac18c4 1115static void
4d38fdb4 1116rib_queue_init (struct zebra_t *zebra)
1117{
1118 assert (zebra);
1119
1120 if (! (zebra->ribq = work_queue_new (zebra->master,
6d691129 1121 "route_node processing")))
4d38fdb4 1122 {
6d691129 1123 zlog_err ("%s: could not initialise work queue!", __func__);
4d38fdb4 1124 return;
1125 }
1126
1127 /* fill in the work queue spec */
0fb58d5d 1128 zebra->ribq->spec.workfunc = &rib_process;
4d38fdb4 1129 zebra->ribq->spec.errorfunc = NULL;
4d38fdb4 1130 /* XXX: TODO: These should be runtime configurable via vty */
1131 zebra->ribq->spec.max_retries = 3;
457eb9af 1132 zebra->ribq->spec.hold = rib_process_hold_time;
4d38fdb4 1133
1134 return;
718e3744 1135}
1136
6d691129
PJ
1137/* RIB updates are processed via a queue of pointers to route_nodes.
1138 *
1139 * The queue length is bounded by the maximal size of the routing table,
1140 * as a route_node will not be requeued, if already queued.
1141 *
3c0755dc
PJ
1142 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1143 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1144 * and then submit route_node to queue for best-path selection later.
1145 * Order of add/delete state changes are preserved for any given RIB.
6d691129
PJ
1146 *
1147 * Deleted RIBs are reaped during best-path selection.
1148 *
1149 * rib_addnode
1150 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
3c0755dc
PJ
1151 * |-------->| | best RIB, if required
1152 * | |
1153 * static_install->|->rib_addqueue...... -> rib_process
1154 * | |
1155 * |-------->| |-> rib_unlink
6d691129
PJ
1156 * |-> set RIB_ENTRY_REMOVE |
1157 * rib_delnode (RIB freed)
1158 *
1159 *
1160 * Queueing state for a route_node is kept in the head RIB entry, this
1161 * state must be preserved as and when the head RIB entry of a
1162 * route_node is changed by rib_unlink / rib_link. A small complication,
1163 * but saves having to allocate a dedicated object for this.
1164 *
1165 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1166 *
1167 * - route_nodes: refcounted by:
1168 * - RIBs attached to route_node:
1169 * - managed by: rib_link/unlink
1170 * - route_node processing queue
1171 * - managed by: rib_addqueue, rib_process.
1172 *
1173 */
1174
718e3744 1175/* Add RIB to head of the route node. */
a1ac18c4 1176static void
6d691129 1177rib_link (struct route_node *rn, struct rib *rib)
718e3744 1178{
1179 struct rib *head;
4d38fdb4 1180
1181 assert (rib && rn);
1182
6d691129
PJ
1183 route_lock_node (rn); /* rn route table reference */
1184
1185 if (IS_ZEBRA_DEBUG_RIB)
1186 zlog_debug ("%s: rn %p, rib %p", __func__, rn, rib);
1187
718e3744 1188 head = rn->info;
1189 if (head)
6d691129
PJ
1190 {
1191 if (IS_ZEBRA_DEBUG_RIB)
1192 zlog_debug ("%s: new head, rn_status copied over", __func__);
1193 head->prev = rib;
1194 /* Transfer the rn status flags to the new head RIB */
1195 rib->rn_status = head->rn_status;
1196 }
718e3744 1197 rib->next = head;
1198 rn->info = rib;
6d691129 1199 rib_queue_add (&zebrad, rn);
718e3744 1200}
1201
a1ac18c4 1202static void
6d691129 1203rib_addnode (struct route_node *rn, struct rib *rib)
718e3744 1204{
6d691129
PJ
1205 /* RIB node has been un-removed before route-node is processed.
1206 * route_node must hence already be on the queue for processing..
1207 */
1208 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1209 {
1210 if (IS_ZEBRA_DEBUG_RIB)
1211 zlog_debug ("%s: rn %p, un-removed rib %p",
1212 __func__, rn, rib);
1213 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1214 return;
1215 }
1216 rib_link (rn, rib);
1217}
1218
1219static void
1220rib_unlink (struct route_node *rn, struct rib *rib)
1221{
1222 struct nexthop *nexthop, *next;
1223
4d38fdb4 1224 assert (rn && rib);
6d691129
PJ
1225
1226 if (IS_ZEBRA_DEBUG_RIB)
1227 zlog_debug ("%s: rn %p, rib %p",
1228 __func__, rn, rib);
1229
718e3744 1230 if (rib->next)
1231 rib->next->prev = rib->prev;
6d691129 1232
718e3744 1233 if (rib->prev)
1234 rib->prev->next = rib->next;
1235 else
6d691129
PJ
1236 {
1237 rn->info = rib->next;
1238
1239 if (rn->info)
1240 {
1241 if (IS_ZEBRA_DEBUG_RIB)
1242 zlog_debug ("%s: rn %p, rib %p, new head copy",
1243 __func__, rn, rib);
1244 rib->next->rn_status = rib->rn_status;
1245 }
1246 }
1247
1248 /* free RIB and nexthops */
1249 for (nexthop = rib->nexthop; nexthop; nexthop = next)
1250 {
1251 next = nexthop->next;
1252 nexthop_free (nexthop);
1253 }
1254 XFREE (MTYPE_RIB, rib);
1255
1256 route_unlock_node (rn); /* rn route table reference */
1257}
1258
1259static void
1260rib_delnode (struct route_node *rn, struct rib *rib)
1261{
1262 if (IS_ZEBRA_DEBUG_RIB)
1263 zlog_debug ("%s: rn %p, rib %p, removing", __func__, rn, rib);
1264 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1265 rib_queue_add (&zebrad, rn);
718e3744 1266}
1267
1268int
1269rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
7514fb77
PJ
1270 struct in_addr *gate, struct in_addr *src,
1271 unsigned int ifindex, u_int32_t vrf_id,
718e3744 1272 u_int32_t metric, u_char distance)
1273{
1274 struct rib *rib;
1275 struct rib *same = NULL;
1276 struct route_table *table;
1277 struct route_node *rn;
1278 struct nexthop *nexthop;
1279
1280 /* Lookup table. */
1281 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1282 if (! table)
1283 return 0;
1284
1285 /* Make it sure prefixlen is applied to the prefix. */
1286 apply_mask_ipv4 (p);
1287
1288 /* Set default distance by route type. */
1289 if (distance == 0)
1290 {
1291 distance = route_info[type].distance;
1292
1293 /* iBGP distance is 200. */
1294 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1295 distance = 200;
1296 }
1297
1298 /* Lookup route node.*/
1299 rn = route_node_get (table, (struct prefix *) p);
1300
1301 /* If same type of route are installed, treat it as a implicit
1302 withdraw. */
1303 for (rib = rn->info; rib; rib = rib->next)
1304 {
6d691129
PJ
1305 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1306 continue;
1307
ebf1ead0 1308 if (rib->type != type)
1309 continue;
1310 if (rib->type != ZEBRA_ROUTE_CONNECT)
4d38fdb4 1311 {
1312 same = rib;
1313 break;
1314 }
ebf1ead0 1315 /* Duplicate connected route comes in. */
1316 else if ((nexthop = rib->nexthop) &&
1317 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
6d691129
PJ
1318 nexthop->ifindex == ifindex &&
1319 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
ebf1ead0 1320 {
1321 rib->refcnt++;
1322 return 0 ;
1323 }
718e3744 1324 }
1325
1326 /* Allocate new rib structure. */
4d38fdb4 1327 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
718e3744 1328 rib->type = type;
1329 rib->distance = distance;
1330 rib->flags = flags;
1331 rib->metric = metric;
b5f45021 1332 rib->table = vrf_id;
718e3744 1333 rib->nexthop_num = 0;
1334 rib->uptime = time (NULL);
1335
1336 /* Nexthop settings. */
1337 if (gate)
1338 {
1339 if (ifindex)
7514fb77 1340 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
718e3744 1341 else
7514fb77 1342 nexthop_ipv4_add (rib, gate, src);
718e3744 1343 }
1344 else
1345 nexthop_ifindex_add (rib, ifindex);
1346
1347 /* If this route is kernel route, set FIB flag to the route. */
1348 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1349 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1350 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1351
1352 /* Link new rib to node.*/
1353 rib_addnode (rn, rib);
4d38fdb4 1354
718e3744 1355 /* Free implicit route.*/
1356 if (same)
4d38fdb4 1357 rib_delnode (rn, same);
1358
1359 route_unlock_node (rn);
718e3744 1360 return 0;
1361}
1362
1363int
1364rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib)
1365{
1366 struct route_table *table;
1367 struct route_node *rn;
1368 struct rib *same;
1369 struct nexthop *nexthop;
4d38fdb4 1370
718e3744 1371 /* Lookup table. */
1372 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1373 if (! table)
1374 return 0;
718e3744 1375 /* Make it sure prefixlen is applied to the prefix. */
1376 apply_mask_ipv4 (p);
1377
1378 /* Set default distance by route type. */
1379 if (rib->distance == 0)
1380 {
1381 rib->distance = route_info[rib->type].distance;
1382
1383 /* iBGP distance is 200. */
1384 if (rib->type == ZEBRA_ROUTE_BGP
1385 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1386 rib->distance = 200;
1387 }
1388
1389 /* Lookup route node.*/
1390 rn = route_node_get (table, (struct prefix *) p);
1391
1392 /* If same type of route are installed, treat it as a implicit
1393 withdraw. */
1394 for (same = rn->info; same; same = same->next)
1395 {
0b8c4f1d 1396 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
6d691129
PJ
1397 continue;
1398
718e3744 1399 if (same->type == rib->type && same->table == rib->table
1400 && same->type != ZEBRA_ROUTE_CONNECT)
4d38fdb4 1401 break;
718e3744 1402 }
4d38fdb4 1403
718e3744 1404 /* If this route is kernel route, set FIB flag to the route. */
1405 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
1406 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1407 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1408
1409 /* Link new rib to node.*/
1410 rib_addnode (rn, rib);
1411
718e3744 1412 /* Free implicit route.*/
1413 if (same)
4d38fdb4 1414 rib_delnode (rn, same);
1415
1416 route_unlock_node (rn);
718e3744 1417 return 0;
1418}
1419
ebf1ead0 1420/* XXX factor with rib_delete_ipv6 */
718e3744 1421int
1422rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
1423 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1424{
1425 struct route_table *table;
1426 struct route_node *rn;
1427 struct rib *rib;
1428 struct rib *fib = NULL;
1429 struct rib *same = NULL;
1430 struct nexthop *nexthop;
1431 char buf1[BUFSIZ];
1432 char buf2[BUFSIZ];
1433
1434 /* Lookup table. */
1435 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1436 if (! table)
1437 return 0;
1438
1439 /* Apply mask. */
1440 apply_mask_ipv4 (p);
1441
5ec90d28 1442 if (IS_ZEBRA_DEBUG_KERNEL && gate)
b6178002 1443 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
5ec90d28 1444 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1445 p->prefixlen,
1446 inet_ntoa (*gate),
1447 ifindex);
1448
718e3744 1449 /* Lookup route node. */
1450 rn = route_node_lookup (table, (struct prefix *) p);
1451 if (! rn)
1452 {
1453 if (IS_ZEBRA_DEBUG_KERNEL)
1454 {
1455 if (gate)
b6178002 1456 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
718e3744 1457 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1458 p->prefixlen,
1459 inet_ntop (AF_INET, gate, buf2, BUFSIZ),
1460 ifindex);
1461 else
b6178002 1462 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
718e3744 1463 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1464 p->prefixlen,
1465 ifindex);
1466 }
1467 return ZEBRA_ERR_RTNOEXIST;
1468 }
1469
1470 /* Lookup same type route. */
1471 for (rib = rn->info; rib; rib = rib->next)
1472 {
6d691129
PJ
1473 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1474 continue;
1475
718e3744 1476 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1477 fib = rib;
1478
ebf1ead0 1479 if (rib->type != type)
1480 continue;
1481 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
1482 nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex)
718e3744 1483 {
ebf1ead0 1484 if (rib->refcnt)
718e3744 1485 {
ebf1ead0 1486 rib->refcnt--;
1487 route_unlock_node (rn);
1488 route_unlock_node (rn);
1489 return 0;
718e3744 1490 }
ebf1ead0 1491 same = rib;
1492 break;
718e3744 1493 }
ebf1ead0 1494 /* Make sure that the route found has the same gateway. */
1495 else if (gate == NULL ||
1496 ((nexthop = rib->nexthop) &&
1497 (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
1498 IPV4_ADDR_SAME (&nexthop->rgate.ipv4, gate))))
5ec90d28 1499 {
ebf1ead0 1500 same = rib;
1501 break;
718e3744 1502 }
1503 }
1504
1505 /* If same type of route can't be found and this message is from
1506 kernel. */
1507 if (! same)
1508 {
1509 if (fib && type == ZEBRA_ROUTE_KERNEL)
1510 {
1511 /* Unset flags. */
1512 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1513 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1514
1515 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1516 }
1517 else
1518 {
1519 if (IS_ZEBRA_DEBUG_KERNEL)
1520 {
1521 if (gate)
b6178002 1522 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
718e3744 1523 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1524 p->prefixlen,
1525 inet_ntop (AF_INET, gate, buf2, BUFSIZ),
1526 ifindex,
1527 type);
1528 else
b6178002 1529 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
718e3744 1530 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1531 p->prefixlen,
1532 ifindex,
1533 type);
1534 }
1535 route_unlock_node (rn);
1536 return ZEBRA_ERR_RTNOEXIST;
1537 }
1538 }
4d38fdb4 1539
718e3744 1540 if (same)
4d38fdb4 1541 rib_delnode (rn, same);
1542
718e3744 1543 route_unlock_node (rn);
718e3744 1544 return 0;
1545}
1546\f
1547/* Install static route into rib. */
a1ac18c4 1548static void
718e3744 1549static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
1550{
1551 struct rib *rib;
1552 struct route_node *rn;
1553 struct route_table *table;
1554
1555 /* Lookup table. */
1556 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1557 if (! table)
1558 return;
1559
1560 /* Lookup existing route */
1561 rn = route_node_get (table, p);
1562 for (rib = rn->info; rib; rib = rib->next)
6d691129
PJ
1563 {
1564 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1565 continue;
1566
1567 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1568 break;
1569 }
718e3744 1570
1571 if (rib)
1572 {
1573 /* Same distance static route is there. Update it with new
1574 nexthop. */
718e3744 1575 route_unlock_node (rn);
718e3744 1576 switch (si->type)
7021c425 1577 {
1578 case STATIC_IPV4_GATEWAY:
7514fb77 1579 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
7021c425 1580 break;
1581 case STATIC_IPV4_IFNAME:
1582 nexthop_ifname_add (rib, si->gate.ifname);
1583 break;
1584 case STATIC_IPV4_BLACKHOLE:
1585 nexthop_blackhole_add (rib);
1586 break;
4d38fdb4 1587 }
3c0755dc 1588 rib_queue_add (&zebrad, rn);
718e3744 1589 }
1590 else
1591 {
1592 /* This is new static route. */
4d38fdb4 1593 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
1594
718e3744 1595 rib->type = ZEBRA_ROUTE_STATIC;
1596 rib->distance = si->distance;
1597 rib->metric = 0;
1598 rib->nexthop_num = 0;
1599
1600 switch (si->type)
7021c425 1601 {
1602 case STATIC_IPV4_GATEWAY:
7514fb77 1603 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
7021c425 1604 break;
1605 case STATIC_IPV4_IFNAME:
1606 nexthop_ifname_add (rib, si->gate.ifname);
1607 break;
1608 case STATIC_IPV4_BLACKHOLE:
1609 nexthop_blackhole_add (rib);
1610 break;
1611 }
718e3744 1612
81dfcaa2 1613 /* Save the flags of this static routes (reject, blackhole) */
1614 rib->flags = si->flags;
1615
718e3744 1616 /* Link this rib to the tree. */
1617 rib_addnode (rn, rib);
718e3744 1618 }
1619}
1620
a1ac18c4 1621static int
718e3744 1622static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
1623{
1624 if (nexthop->type == NEXTHOP_TYPE_IPV4
1625 && si->type == STATIC_IPV4_GATEWAY
1626 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
1627 return 1;
1628 if (nexthop->type == NEXTHOP_TYPE_IFNAME
1629 && si->type == STATIC_IPV4_IFNAME
1630 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
1631 return 1;
595db7f1 1632 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
1633 && si->type == STATIC_IPV4_BLACKHOLE)
1634 return 1;
e8e1946e 1635 return 0;
718e3744 1636}
1637
1638/* Uninstall static route from RIB. */
a1ac18c4 1639static void
718e3744 1640static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
1641{
1642 struct route_node *rn;
1643 struct rib *rib;
1644 struct nexthop *nexthop;
1645 struct route_table *table;
1646
1647 /* Lookup table. */
1648 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1649 if (! table)
1650 return;
4d38fdb4 1651
718e3744 1652 /* Lookup existing route with type and distance. */
1653 rn = route_node_lookup (table, p);
1654 if (! rn)
1655 return;
1656
1657 for (rib = rn->info; rib; rib = rib->next)
6d691129
PJ
1658 {
1659 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1660 continue;
1661
1662 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1663 break;
1664 }
718e3744 1665
1666 if (! rib)
1667 {
1668 route_unlock_node (rn);
1669 return;
1670 }
1671
1672 /* Lookup nexthop. */
1673 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1674 if (static_ipv4_nexthop_same (nexthop, si))
1675 break;
1676
1677 /* Can't find nexthop. */
1678 if (! nexthop)
1679 {
1680 route_unlock_node (rn);
1681 return;
1682 }
1683
1684 /* Check nexthop. */
1685 if (rib->nexthop_num == 1)
6d691129 1686 rib_delnode (rn, rib);
718e3744 1687 else
1688 {
6baeb988 1689 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1690 rib_uninstall (rn, rib);
319572cc 1691 nexthop_delete (rib, nexthop);
1692 nexthop_free (nexthop);
6d691129 1693 rib_queue_add (&zebrad, rn);
718e3744 1694 }
718e3744 1695 /* Unlock node. */
1696 route_unlock_node (rn);
1697}
1698
1699/* Add static route into static route configuration. */
1700int
39db97e4 1701static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
81dfcaa2 1702 u_char flags, u_char distance, u_int32_t vrf_id)
718e3744 1703{
1704 u_char type = 0;
1705 struct route_node *rn;
1706 struct static_ipv4 *si;
1707 struct static_ipv4 *pp;
1708 struct static_ipv4 *cp;
1709 struct static_ipv4 *update = NULL;
1710 struct route_table *stable;
1711
1712 /* Lookup table. */
1713 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
1714 if (! stable)
1715 return -1;
1716
1717 /* Lookup static route prefix. */
1718 rn = route_node_get (stable, p);
1719
1720 /* Make flags. */
1721 if (gate)
1722 type = STATIC_IPV4_GATEWAY;
368aa3f0 1723 else if (ifname)
718e3744 1724 type = STATIC_IPV4_IFNAME;
595db7f1 1725 else
1726 type = STATIC_IPV4_BLACKHOLE;
718e3744 1727
1728 /* Do nothing if there is a same static route. */
1729 for (si = rn->info; si; si = si->next)
1730 {
1731 if (type == si->type
1732 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
1733 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
1734 {
1735 if (distance == si->distance)
1736 {
1737 route_unlock_node (rn);
1738 return 0;
1739 }
1740 else
1741 update = si;
1742 }
1743 }
1744
3c0755dc 1745 /* Distance changed. */
718e3744 1746 if (update)
1747 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
1748
1749 /* Make new static route structure. */
1750 si = XMALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
1751 memset (si, 0, sizeof (struct static_ipv4));
1752
1753 si->type = type;
1754 si->distance = distance;
81dfcaa2 1755 si->flags = flags;
718e3744 1756
1757 if (gate)
1758 si->gate.ipv4 = *gate;
1759 if (ifname)
1760 si->gate.ifname = XSTRDUP (0, ifname);
1761
1762 /* Add new static route information to the tree with sort by
1763 distance value and gateway address. */
1764 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
1765 {
1766 if (si->distance < cp->distance)
1767 break;
1768 if (si->distance > cp->distance)
1769 continue;
1770 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
1771 {
1772 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
1773 break;
1774 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
1775 continue;
1776 }
1777 }
1778
1779 /* Make linked list. */
1780 if (pp)
1781 pp->next = si;
1782 else
1783 rn->info = si;
1784 if (cp)
1785 cp->prev = si;
1786 si->prev = pp;
1787 si->next = cp;
1788
1789 /* Install into rib. */
1790 static_install_ipv4 (p, si);
1791
1792 return 1;
1793}
1794
1795/* Delete static route from static route configuration. */
1796int
39db97e4 1797static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
718e3744 1798 u_char distance, u_int32_t vrf_id)
1799{
1800 u_char type = 0;
1801 struct route_node *rn;
1802 struct static_ipv4 *si;
1803 struct route_table *stable;
1804
1805 /* Lookup table. */
1806 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
1807 if (! stable)
1808 return -1;
1809
1810 /* Lookup static route prefix. */
1811 rn = route_node_lookup (stable, p);
1812 if (! rn)
1813 return 0;
1814
1815 /* Make flags. */
1816 if (gate)
1817 type = STATIC_IPV4_GATEWAY;
1818 else if (ifname)
1819 type = STATIC_IPV4_IFNAME;
595db7f1 1820 else
1821 type = STATIC_IPV4_BLACKHOLE;
718e3744 1822
1823 /* Find same static route is the tree */
1824 for (si = rn->info; si; si = si->next)
1825 if (type == si->type
1826 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
1827 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
1828 break;
1829
1830 /* Can't find static route. */
1831 if (! si)
1832 {
1833 route_unlock_node (rn);
1834 return 0;
1835 }
1836
1837 /* Install into rib. */
1838 static_uninstall_ipv4 (p, si);
1839
1840 /* Unlink static route from linked list. */
1841 if (si->prev)
1842 si->prev->next = si->next;
1843 else
1844 rn->info = si->next;
1845 if (si->next)
1846 si->next->prev = si->prev;
143a385f 1847 route_unlock_node (rn);
718e3744 1848
1849 /* Free static route configuration. */
a0f6acd8 1850 if (ifname)
1851 XFREE (0, si->gate.ifname);
718e3744 1852 XFREE (MTYPE_STATIC_IPV4, si);
1853
143a385f 1854 route_unlock_node (rn);
1855
718e3744 1856 return 1;
1857}
1858
1859\f
1860#ifdef HAVE_IPV6
a1ac18c4 1861static int
718e3744 1862rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
1863 struct in6_addr *gate, unsigned int ifindex, int table)
1864{
726f9b2b 1865 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
1866#if defined (MUSICA) || defined (LINUX)
1867 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
1868 if (p->prefixlen == 96)
1869 return 0;
1870#endif /* MUSICA */
718e3744 1871 return 1;
726f9b2b 1872 }
718e3744 1873 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
1874 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
1875 {
1876 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
1877 return 1;
1878 }
1879 return 0;
1880}
1881
1882int
1883rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
be61c4eb 1884 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
1885 u_int32_t metric, u_char distance)
718e3744 1886{
1887 struct rib *rib;
1888 struct rib *same = NULL;
1889 struct route_table *table;
1890 struct route_node *rn;
1891 struct nexthop *nexthop;
1892
718e3744 1893 /* Lookup table. */
1894 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1895 if (! table)
1896 return 0;
1897
1898 /* Make sure mask is applied. */
1899 apply_mask_ipv6 (p);
1900
1901 /* Set default distance by route type. */
be61c4eb 1902 if (!distance)
1903 distance = route_info[type].distance;
718e3744 1904
1905 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1906 distance = 200;
1907
1908 /* Filter bogus route. */
1909 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
1910 return 0;
1911
1912 /* Lookup route node.*/
1913 rn = route_node_get (table, (struct prefix *) p);
1914
1915 /* If same type of route are installed, treat it as a implicit
1916 withdraw. */
1917 for (rib = rn->info; rib; rib = rib->next)
1918 {
6d691129
PJ
1919 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1920 continue;
1921
ebf1ead0 1922 if (rib->type != type)
1923 continue;
1924 if (rib->type != ZEBRA_ROUTE_CONNECT)
718e3744 1925 {
1926 same = rib;
718e3744 1927 break;
1928 }
ebf1ead0 1929 else if ((nexthop = rib->nexthop) &&
1930 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
1931 nexthop->ifindex == ifindex)
1932 {
1933 rib->refcnt++;
1934 return 0;
1935 }
718e3744 1936 }
1937
1938 /* Allocate new rib structure. */
4d38fdb4 1939 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
1940
718e3744 1941 rib->type = type;
1942 rib->distance = distance;
1943 rib->flags = flags;
1944 rib->metric = metric;
b5f45021 1945 rib->table = vrf_id;
718e3744 1946 rib->nexthop_num = 0;
1947 rib->uptime = time (NULL);
1948
1949 /* Nexthop settings. */
1950 if (gate)
1951 {
1952 if (ifindex)
1953 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
1954 else
1955 nexthop_ipv6_add (rib, gate);
1956 }
1957 else
1958 nexthop_ifindex_add (rib, ifindex);
1959
1960 /* If this route is kernel route, set FIB flag to the route. */
1961 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1962 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1963 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1964
1965 /* Link new rib to node.*/
1966 rib_addnode (rn, rib);
1967
718e3744 1968 /* Free implicit route.*/
1969 if (same)
4d38fdb4 1970 rib_delnode (rn, same);
1971
1972 route_unlock_node (rn);
718e3744 1973 return 0;
1974}
1975
ebf1ead0 1976/* XXX factor with rib_delete_ipv6 */
718e3744 1977int
1978rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
1979 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1980{
1981 struct route_table *table;
1982 struct route_node *rn;
1983 struct rib *rib;
1984 struct rib *fib = NULL;
1985 struct rib *same = NULL;
1986 struct nexthop *nexthop;
1987 char buf1[BUFSIZ];
1988 char buf2[BUFSIZ];
1989
1990 /* Apply mask. */
1991 apply_mask_ipv6 (p);
1992
1993 /* Lookup table. */
1994 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1995 if (! table)
1996 return 0;
4d38fdb4 1997
718e3744 1998 /* Lookup route node. */
1999 rn = route_node_lookup (table, (struct prefix *) p);
2000 if (! rn)
2001 {
2002 if (IS_ZEBRA_DEBUG_KERNEL)
2003 {
2004 if (gate)
b6178002 2005 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
718e3744 2006 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
2007 p->prefixlen,
2008 inet_ntop (AF_INET6, gate, buf2, BUFSIZ),
2009 ifindex);
2010 else
b6178002 2011 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
718e3744 2012 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
2013 p->prefixlen,
2014 ifindex);
2015 }
2016 return ZEBRA_ERR_RTNOEXIST;
2017 }
2018
2019 /* Lookup same type route. */
2020 for (rib = rn->info; rib; rib = rib->next)
2021 {
6d691129
PJ
2022 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2023 continue;
2024
718e3744 2025 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2026 fib = rib;
2027
ebf1ead0 2028 if (rib->type != type)
2029 continue;
2030 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
2031 nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex)
718e3744 2032 {
ebf1ead0 2033 if (rib->refcnt)
718e3744 2034 {
ebf1ead0 2035 rib->refcnt--;
2036 route_unlock_node (rn);
2037 route_unlock_node (rn);
2038 return 0;
718e3744 2039 }
ebf1ead0 2040 same = rib;
2041 break;
718e3744 2042 }
ebf1ead0 2043 /* Make sure that the route found has the same gateway. */
2044 else if (gate == NULL ||
2045 ((nexthop = rib->nexthop) &&
2046 (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate) ||
2047 IPV6_ADDR_SAME (&nexthop->rgate.ipv6, gate))))
718e3744 2048 {
ebf1ead0 2049 same = rib;
2050 break;
718e3744 2051 }
2052 }
2053
2054 /* If same type of route can't be found and this message is from
2055 kernel. */
2056 if (! same)
2057 {
2058 if (fib && type == ZEBRA_ROUTE_KERNEL)
2059 {
2060 /* Unset flags. */
2061 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2062 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2063
2064 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2065 }
2066 else
2067 {
2068 if (IS_ZEBRA_DEBUG_KERNEL)
2069 {
2070 if (gate)
b6178002 2071 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
718e3744 2072 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
2073 p->prefixlen,
2074 inet_ntop (AF_INET6, gate, buf2, BUFSIZ),
2075 ifindex,
2076 type);
2077 else
b6178002 2078 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
718e3744 2079 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
2080 p->prefixlen,
2081 ifindex,
2082 type);
2083 }
2084 route_unlock_node (rn);
2085 return ZEBRA_ERR_RTNOEXIST;
2086 }
2087 }
2088
718e3744 2089 if (same)
4d38fdb4 2090 rib_delnode (rn, same);
2091
718e3744 2092 route_unlock_node (rn);
718e3744 2093 return 0;
2094}
2095\f
2096/* Install static route into rib. */
a1ac18c4 2097static void
718e3744 2098static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2099{
2100 struct rib *rib;
2101 struct route_table *table;
2102 struct route_node *rn;
2103
2104 /* Lookup table. */
2105 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2106 if (! table)
2107 return;
2108
2109 /* Lookup existing route */
2110 rn = route_node_get (table, p);
2111 for (rib = rn->info; rib; rib = rib->next)
6d691129
PJ
2112 {
2113 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2114 continue;
2115
2116 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2117 break;
2118 }
718e3744 2119
2120 if (rib)
2121 {
2122 /* Same distance static route is there. Update it with new
2123 nexthop. */
718e3744 2124 route_unlock_node (rn);
2125
2126 switch (si->type)
2127 {
2128 case STATIC_IPV6_GATEWAY:
2129 nexthop_ipv6_add (rib, &si->ipv6);
2130 break;
2131 case STATIC_IPV6_IFNAME:
2132 nexthop_ifname_add (rib, si->ifname);
2133 break;
2134 case STATIC_IPV6_GATEWAY_IFNAME:
2135 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2136 break;
2137 }
3c0755dc 2138 rib_queue_add (&zebrad, rn);
718e3744 2139 }
2140 else
2141 {
2142 /* This is new static route. */
4d38fdb4 2143 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2144
718e3744 2145 rib->type = ZEBRA_ROUTE_STATIC;
2146 rib->distance = si->distance;
2147 rib->metric = 0;
2148 rib->nexthop_num = 0;
2149
2150 switch (si->type)
2151 {
2152 case STATIC_IPV6_GATEWAY:
2153 nexthop_ipv6_add (rib, &si->ipv6);
2154 break;
2155 case STATIC_IPV6_IFNAME:
2156 nexthop_ifname_add (rib, si->ifname);
2157 break;
2158 case STATIC_IPV6_GATEWAY_IFNAME:
2159 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2160 break;
2161 }
2162
81dfcaa2 2163 /* Save the flags of this static routes (reject, blackhole) */
2164 rib->flags = si->flags;
2165
718e3744 2166 /* Link this rib to the tree. */
2167 rib_addnode (rn, rib);
718e3744 2168 }
2169}
2170
a1ac18c4 2171static int
718e3744 2172static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2173{
2174 if (nexthop->type == NEXTHOP_TYPE_IPV6
2175 && si->type == STATIC_IPV6_GATEWAY
2176 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2177 return 1;
2178 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2179 && si->type == STATIC_IPV6_IFNAME
2180 && strcmp (nexthop->ifname, si->ifname) == 0)
2181 return 1;
2182 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2183 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2184 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2185 && strcmp (nexthop->ifname, si->ifname) == 0)
2186 return 1;
e8e1946e 2187 return 0;
718e3744 2188}
2189
a1ac18c4 2190static void
718e3744 2191static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2192{
2193 struct route_table *table;
2194 struct route_node *rn;
2195 struct rib *rib;
2196 struct nexthop *nexthop;
2197
2198 /* Lookup table. */
2199 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2200 if (! table)
2201 return;
2202
2203 /* Lookup existing route with type and distance. */
2204 rn = route_node_lookup (table, (struct prefix *) p);
2205 if (! rn)
2206 return;
2207
2208 for (rib = rn->info; rib; rib = rib->next)
6d691129
PJ
2209 {
2210 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2211 continue;
2212
2213 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2214 break;
2215 }
2216
718e3744 2217 if (! rib)
2218 {
2219 route_unlock_node (rn);
2220 return;
2221 }
2222
2223 /* Lookup nexthop. */
2224 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2225 if (static_ipv6_nexthop_same (nexthop, si))
2226 break;
2227
2228 /* Can't find nexthop. */
2229 if (! nexthop)
2230 {
2231 route_unlock_node (rn);
2232 return;
2233 }
2234
2235 /* Check nexthop. */
2236 if (rib->nexthop_num == 1)
2237 {
2238 rib_delnode (rn, rib);
718e3744 2239 }
2240 else
2241 {
6baeb988 2242 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2243 rib_uninstall (rn, rib);
319572cc 2244 nexthop_delete (rib, nexthop);
2245 nexthop_free (nexthop);
6d691129 2246 rib_queue_add (&zebrad, rn);
718e3744 2247 }
718e3744 2248 /* Unlock node. */
2249 route_unlock_node (rn);
2250}
2251
2252/* Add static route into static route configuration. */
2253int
2254static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
39db97e4 2255 const char *ifname, u_char flags, u_char distance,
2256 u_int32_t vrf_id)
718e3744 2257{
2258 struct route_node *rn;
2259 struct static_ipv6 *si;
2260 struct static_ipv6 *pp;
2261 struct static_ipv6 *cp;
2262 struct route_table *stable;
2263
2264 /* Lookup table. */
2265 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2266 if (! stable)
2267 return -1;
27b47253
PJ
2268
2269 if (!gate &&
2270 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
2271 return -1;
2272
2273 if (!ifname &&
2274 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
2275 return -1;
718e3744 2276
2277 /* Lookup static route prefix. */
2278 rn = route_node_get (stable, p);
2279
2280 /* Do nothing if there is a same static route. */
2281 for (si = rn->info; si; si = si->next)
2282 {
2283 if (distance == si->distance
2284 && type == si->type
2285 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2286 && (! ifname || strcmp (ifname, si->ifname) == 0))
2287 {
2288 route_unlock_node (rn);
2289 return 0;
2290 }
2291 }
2292
2293 /* Make new static route structure. */
2294 si = XMALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
2295 memset (si, 0, sizeof (struct static_ipv6));
2296
2297 si->type = type;
2298 si->distance = distance;
81dfcaa2 2299 si->flags = flags;
718e3744 2300
2301 switch (type)
2302 {
2303 case STATIC_IPV6_GATEWAY:
2304 si->ipv6 = *gate;
2305 break;
2306 case STATIC_IPV6_IFNAME:
2307 si->ifname = XSTRDUP (0, ifname);
2308 break;
2309 case STATIC_IPV6_GATEWAY_IFNAME:
2310 si->ipv6 = *gate;
2311 si->ifname = XSTRDUP (0, ifname);
2312 break;
2313 }
2314
2315 /* Add new static route information to the tree with sort by
2316 distance value and gateway address. */
2317 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2318 {
2319 if (si->distance < cp->distance)
2320 break;
2321 if (si->distance > cp->distance)
2322 continue;
2323 }
2324
2325 /* Make linked list. */
2326 if (pp)
2327 pp->next = si;
2328 else
2329 rn->info = si;
2330 if (cp)
2331 cp->prev = si;
2332 si->prev = pp;
2333 si->next = cp;
2334
2335 /* Install into rib. */
2336 static_install_ipv6 (p, si);
2337
2338 return 1;
2339}
2340
2341/* Delete static route from static route configuration. */
2342int
2343static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
39db97e4 2344 const char *ifname, u_char distance, u_int32_t vrf_id)
718e3744 2345{
2346 struct route_node *rn;
2347 struct static_ipv6 *si;
2348 struct route_table *stable;
2349
2350 /* Lookup table. */
2351 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2352 if (! stable)
2353 return -1;
2354
2355 /* Lookup static route prefix. */
2356 rn = route_node_lookup (stable, p);
2357 if (! rn)
2358 return 0;
2359
2360 /* Find same static route is the tree */
2361 for (si = rn->info; si; si = si->next)
2362 if (distance == si->distance
2363 && type == si->type
2364 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2365 && (! ifname || strcmp (ifname, si->ifname) == 0))
2366 break;
2367
2368 /* Can't find static route. */
2369 if (! si)
2370 {
2371 route_unlock_node (rn);
2372 return 0;
2373 }
2374
2375 /* Install into rib. */
2376 static_uninstall_ipv6 (p, si);
2377
2378 /* Unlink static route from linked list. */
2379 if (si->prev)
2380 si->prev->next = si->next;
2381 else
2382 rn->info = si->next;
2383 if (si->next)
2384 si->next->prev = si->prev;
2385
2386 /* Free static route configuration. */
a0f6acd8 2387 if (ifname)
2388 XFREE (0, si->ifname);
718e3744 2389 XFREE (MTYPE_STATIC_IPV6, si);
2390
2391 return 1;
2392}
2393#endif /* HAVE_IPV6 */
2394\f
2395/* RIB update function. */
2396void
a1ac18c4 2397rib_update (void)
718e3744 2398{
2399 struct route_node *rn;
2400 struct route_table *table;
4d38fdb4 2401
718e3744 2402 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2403 if (table)
2404 for (rn = route_top (table); rn; rn = route_next (rn))
4d38fdb4 2405 if (rn->info)
6d691129 2406 rib_queue_add (&zebrad, rn);
718e3744 2407
2408 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2409 if (table)
2410 for (rn = route_top (table); rn; rn = route_next (rn))
4d38fdb4 2411 if (rn->info)
6d691129 2412 rib_queue_add (&zebrad, rn);
718e3744 2413}
2414
2415/* Interface goes up. */
a1ac18c4 2416static void
718e3744 2417rib_if_up (struct interface *ifp)
2418{
2419 rib_update ();
2420}
2421
2422/* Interface goes down. */
a1ac18c4 2423static void
718e3744 2424rib_if_down (struct interface *ifp)
2425{
2426 rib_update ();
2427}
2428\f
2429/* Remove all routes which comes from non main table. */
a1ac18c4 2430static void
718e3744 2431rib_weed_table (struct route_table *table)
2432{
2433 struct route_node *rn;
2434 struct rib *rib;
2435 struct rib *next;
2436
2437 if (table)
2438 for (rn = route_top (table); rn; rn = route_next (rn))
2439 for (rib = rn->info; rib; rib = next)
2440 {
2441 next = rib->next;
2442
6d691129
PJ
2443 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2444 continue;
2445
b21b19c5 2446 if (rib->table != zebrad.rtm_table_default &&
718e3744 2447 rib->table != RT_TABLE_MAIN)
4d38fdb4 2448 rib_delnode (rn, rib);
718e3744 2449 }
2450}
2451
2452/* Delete all routes from non main table. */
2453void
a1ac18c4 2454rib_weed_tables (void)
718e3744 2455{
2456 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2457 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2458}
2459\f
2460/* Delete self installed routes after zebra is relaunched. */
a1ac18c4 2461static void
718e3744 2462rib_sweep_table (struct route_table *table)
2463{
2464 struct route_node *rn;
2465 struct rib *rib;
2466 struct rib *next;
2467 int ret = 0;
2468
2469 if (table)
2470 for (rn = route_top (table); rn; rn = route_next (rn))
2471 for (rib = rn->info; rib; rib = next)
2472 {
2473 next = rib->next;
2474
6d691129
PJ
2475 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2476 continue;
2477
718e3744 2478 if (rib->type == ZEBRA_ROUTE_KERNEL &&
2479 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
2480 {
2481 ret = rib_uninstall_kernel (rn, rib);
2482 if (! ret)
4d38fdb4 2483 rib_delnode (rn, rib);
718e3744 2484 }
2485 }
2486}
2487
2488/* Sweep all RIB tables. */
2489void
a1ac18c4 2490rib_sweep_route (void)
718e3744 2491{
2492 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2493 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2494}
2495\f
2496/* Close RIB and clean up kernel routes. */
a1ac18c4 2497static void
718e3744 2498rib_close_table (struct route_table *table)
2499{
2500 struct route_node *rn;
2501 struct rib *rib;
2502
2503 if (table)
2504 for (rn = route_top (table); rn; rn = route_next (rn))
2505 for (rib = rn->info; rib; rib = rib->next)
6d691129
PJ
2506 {
2507 if (! RIB_SYSTEM_ROUTE (rib)
2508 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2509 rib_uninstall_kernel (rn, rib);
2510 }
718e3744 2511}
2512
2513/* Close all RIB tables. */
2514void
a1ac18c4 2515rib_close (void)
718e3744 2516{
2517 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2518 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2519}
2520\f
2521/* Routing information base initialize. */
2522void
a1ac18c4 2523rib_init (void)
718e3744 2524{
4d38fdb4 2525 rib_queue_init (&zebrad);
718e3744 2526 /* VRF initialization. */
2527 vrf_init ();
2528}