]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_rib.c
bgpd-nht-import-check-fix.patch
[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"
fb018d25 37#include "nexthop.h"
718e3744 38
39#include "zebra/rib.h"
40#include "zebra/rt.h"
41#include "zebra/zserv.h"
42#include "zebra/redistribute.h"
43#include "zebra/debug.h"
5adc2528 44#include "zebra/zebra_fpm.h"
fb018d25 45#include "zebra/zebra_rnh.h"
718e3744 46
47/* Default rtm_table for all clients */
b21b19c5 48extern struct zebra_t zebrad;
718e3744 49
457eb9af
PJ
50/* Hold time for RIB process, should be very minimal.
51 * it is useful to able to set it otherwise for testing, hence exported
52 * as global here for test-rig code.
53 */
54int rib_process_hold_time = 10;
55
718e3744 56/* Each route type's string and default distance value. */
d145bc00 57static const struct
718e3744 58{
59 int key;
60 int distance;
5734509c 61} route_info[ZEBRA_ROUTE_MAX] =
718e3744 62{
5734509c
PJ
63 [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0},
64 [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0},
65 [ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0},
66 [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1},
67 [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120},
68 [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120},
69 [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110},
70 [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110},
71 [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115},
72 [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */},
73 [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 95},
7052f228 74 /* no entry/default: 150 */
718e3744 75};
6b0655a2 76
718e3744 77/* Vector for routing table. */
d145bc00 78static vector vrf_vector;
718e3744 79
1b5ed1b0
AS
80/*
81 * vrf_table_create
82 */
83static void
84vrf_table_create (struct vrf *vrf, afi_t afi, safi_t safi)
85{
86 rib_table_info_t *info;
87 struct route_table *table;
88
89 assert (!vrf->table[afi][safi]);
90
91 table = route_table_init ();
92 vrf->table[afi][safi] = table;
93
94 info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
95 info->vrf = vrf;
96 info->afi = afi;
97 info->safi = safi;
98 table->info = info;
99}
100
718e3744 101/* Allocate new VRF. */
a1ac18c4 102static struct vrf *
fce954f8 103vrf_alloc (const char *name)
718e3744 104{
105 struct vrf *vrf;
106
107 vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
108
109 /* Put name. */
110 if (name)
111 vrf->name = XSTRDUP (MTYPE_VRF_NAME, name);
112
113 /* Allocate routing table and static table. */
1b5ed1b0
AS
114 vrf_table_create (vrf, AFI_IP, SAFI_UNICAST);
115 vrf_table_create (vrf, AFI_IP6, SAFI_UNICAST);
718e3744 116 vrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
117 vrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
1b5ed1b0
AS
118 vrf_table_create (vrf, AFI_IP, SAFI_MULTICAST);
119 vrf_table_create (vrf, AFI_IP6, SAFI_MULTICAST);
cddf391b
B
120 vrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
121 vrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
122
fb018d25
DS
123 vrf->rnh_table[AFI_IP] = route_table_init();
124 vrf->rnh_table[AFI_IP6] = route_table_init();
718e3744 125
078430f6
DS
126 vrf->import_check_table[AFI_IP] = route_table_init();
127 vrf->import_check_table[AFI_IP6] = route_table_init();
128
718e3744 129 return vrf;
130}
131
718e3744 132/* Lookup VRF by identifier. */
133struct vrf *
134vrf_lookup (u_int32_t id)
135{
136 return vector_lookup (vrf_vector, id);
137}
138
718e3744 139/* Initialize VRF. */
a1ac18c4 140static void
141vrf_init (void)
718e3744 142{
143 struct vrf *default_table;
144
145 /* Allocate VRF vector. */
146 vrf_vector = vector_init (1);
147
148 /* Allocate default main table. */
149 default_table = vrf_alloc ("Default-IP-Routing-Table");
150
151 /* Default table index must be 0. */
152 vector_set_index (vrf_vector, 0, default_table);
153}
154
155/* Lookup route table. */
156struct route_table *
157vrf_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
9499bf2b
LR
165 if( afi >= AFI_MAX || safi >= SAFI_MAX )
166 return NULL;
167
718e3744 168 return vrf->table[afi][safi];
169}
170
171/* Lookup static route table. */
172struct route_table *
173vrf_static_table (afi_t afi, safi_t safi, u_int32_t id)
174{
175 struct vrf *vrf;
176
177 vrf = vrf_lookup (id);
178 if (! vrf)
179 return NULL;
180
9499bf2b
LR
181 if( afi >= AFI_MAX || safi >= SAFI_MAX )
182 return NULL;
183
718e3744 184 return vrf->stable[afi][safi];
185}
6b0655a2 186
7a4bb9c5
DS
187struct route_table *
188vrf_other_route_table (afi_t afi, u_int32_t table_id, u_int32_t vrf_id)
189{
190 struct vrf *vrf;
191
192 vrf = vrf_lookup (vrf_id);
193 if (! vrf)
194 return NULL;
195
196 if(afi >= AFI_MAX)
197 return NULL;
198
199 if (table_id >= ZEBRA_KERNEL_TABLE_MAX)
200 return NULL;
201
202 if (vrf->other_table[afi][table_id] == NULL)
203 {
204 vrf->other_table[afi][table_id] = route_table_init();
205 }
206
207 return (vrf->other_table[afi][table_id]);
208}
209
210int
211is_zebra_valid_kernel_table(u_int32_t table_id)
212{
213 if ((table_id > ZEBRA_KERNEL_TABLE_MAX) ||
214 (table_id == RT_TABLE_UNSPEC) ||
215 (table_id == RT_TABLE_LOCAL) ||
216 (table_id == RT_TABLE_COMPAT))
217 return 0;
218 else
219 return 1;
220}
221
222int
223is_zebra_main_routing_table(u_int32_t table_id)
224{
225 if ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default))
226 return 1;
227 return 0;
228}
229
fa713d9e 230/* Add nexthop to the end of a nexthop list. */
6e26278c 231void
fa713d9e 232_nexthop_add (struct nexthop **target, struct nexthop *nexthop)
718e3744 233{
234 struct nexthop *last;
235
fa713d9e 236 for (last = *target; last && last->next; last = last->next)
718e3744 237 ;
238 if (last)
239 last->next = nexthop;
240 else
fa713d9e 241 *target = nexthop;
718e3744 242 nexthop->prev = last;
fa713d9e 243}
718e3744 244
fa713d9e 245/* Add nexthop to the end of a rib node's nexthop list */
fb018d25 246void
fa713d9e
CF
247nexthop_add (struct rib *rib, struct nexthop *nexthop)
248{
249 _nexthop_add(&rib->nexthop, nexthop);
718e3744 250 rib->nexthop_num++;
251}
252
6e26278c
DS
253static void
254_copy_nexthops (struct nexthop **tnh, struct nexthop *nh)
255{
256 struct nexthop *nexthop;
257 struct nexthop *nh1;
258
259 for (nh1 = nh; nh1; nh1 = nh1->next)
260 {
261 nexthop = nexthop_new();
262 nexthop->flags = nh->flags;
263 nexthop->type = nh->type;
264 nexthop->ifindex = nh->ifindex;
265 if (nh->ifname)
266 nexthop->ifname = XSTRDUP(0, nh->ifname);
267 memcpy(&(nexthop->gate), &(nh->gate), sizeof(union g_addr));
268 memcpy(&(nexthop->src), &(nh->src), sizeof(union g_addr));
269 _nexthop_add(tnh, nexthop);
270
271 if (CHECK_FLAG(nh1->flags, NEXTHOP_FLAG_RECURSIVE))
272 _copy_nexthops(&nexthop->resolved, nh1->resolved);
273 }
274}
275
276/**
277 * copy_nexthop - copy a nexthop to the rib structure.
278 */
279void
280copy_nexthops (struct rib *rib, struct nexthop *nh)
281{
282 struct nexthop *nexthop;
283
284 nexthop = nexthop_new();
285 nexthop->flags = nh->flags;
286 nexthop->type = nh->type;
287 nexthop->ifindex = nh->ifindex;
288 if (nh->ifname)
289 nexthop->ifname = XSTRDUP(0, nh->ifname);
290 memcpy(&(nexthop->gate), &(nh->gate), sizeof(union g_addr));
291 memcpy(&(nexthop->src), &(nh->src), sizeof(union g_addr));
292 nexthop_add(rib, nexthop);
293 if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_RECURSIVE))
294 _copy_nexthops(&nexthop->resolved, nh->resolved);
295}
296
718e3744 297/* Delete specified nexthop from the list. */
a1ac18c4 298static void
718e3744 299nexthop_delete (struct rib *rib, struct nexthop *nexthop)
300{
301 if (nexthop->next)
302 nexthop->next->prev = nexthop->prev;
303 if (nexthop->prev)
304 nexthop->prev->next = nexthop->next;
305 else
306 rib->nexthop = nexthop->next;
307 rib->nexthop_num--;
308}
309
310/* Free nexthop. */
fb018d25 311void
6e26278c 312nexthop_free (struct nexthop *nexthop, struct route_node *rn)
718e3744 313{
a4b70768 314 if (nexthop->ifname)
315 XFREE (0, nexthop->ifname);
fa713d9e 316 if (nexthop->resolved)
6e26278c 317 nexthops_free(nexthop->resolved, rn);
718e3744 318 XFREE (MTYPE_NEXTHOP, nexthop);
319}
320
fa713d9e 321/* Frees a list of nexthops */
fb018d25 322void
6e26278c 323nexthops_free (struct nexthop *nexthop, struct route_node *rn)
fa713d9e
CF
324{
325 struct nexthop *nh, *next;
6e26278c 326 struct prefix nh_p;
fa713d9e
CF
327
328 for (nh = nexthop; nh; nh = next)
329 {
330 next = nh->next;
6e26278c
DS
331 if (nh->type == NEXTHOP_TYPE_IPV4)
332 {
333 nh_p.family = AF_INET;
334 nh_p.prefixlen = IPV4_MAX_BITLEN;
335 nh_p.u.prefix4 = nh->gate.ipv4;
70c0f184 336 zebra_deregister_rnh_static_nh(&nh_p, rn);
6e26278c
DS
337 }
338 else if (nh->type == NEXTHOP_TYPE_IPV6)
339 {
340 nh_p.family = AF_INET6;
341 nh_p.prefixlen = IPV6_MAX_BITLEN;
342 nh_p.u.prefix6 = nh->gate.ipv6;
70c0f184 343 zebra_deregister_rnh_static_nh(&nh_p, rn);
6e26278c 344 }
6e26278c 345 nexthop_free (nh, rn);
fa713d9e
CF
346 }
347}
348
718e3744 349struct nexthop *
350nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
351{
352 struct nexthop *nexthop;
353
393deb9b 354 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
718e3744 355 nexthop->type = NEXTHOP_TYPE_IFINDEX;
356 nexthop->ifindex = ifindex;
357
358 nexthop_add (rib, nexthop);
359
360 return nexthop;
361}
362
363struct nexthop *
364nexthop_ifname_add (struct rib *rib, char *ifname)
365{
366 struct nexthop *nexthop;
367
393deb9b 368 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
718e3744 369 nexthop->type = NEXTHOP_TYPE_IFNAME;
a4b70768 370 nexthop->ifname = XSTRDUP (0, ifname);
718e3744 371
372 nexthop_add (rib, nexthop);
373
374 return nexthop;
375}
376
377struct nexthop *
7514fb77 378nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src)
718e3744 379{
380 struct nexthop *nexthop;
381
393deb9b 382 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
718e3744 383 nexthop->type = NEXTHOP_TYPE_IPV4;
384 nexthop->gate.ipv4 = *ipv4;
7514fb77
PJ
385 if (src)
386 nexthop->src.ipv4 = *src;
718e3744 387
388 nexthop_add (rib, nexthop);
389
390 return nexthop;
391}
392
26e2ae36 393struct nexthop *
718e3744 394nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
7514fb77 395 struct in_addr *src, unsigned int ifindex)
718e3744 396{
397 struct nexthop *nexthop;
398
393deb9b 399 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
718e3744 400 nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
401 nexthop->gate.ipv4 = *ipv4;
7514fb77
PJ
402 if (src)
403 nexthop->src.ipv4 = *src;
718e3744 404 nexthop->ifindex = ifindex;
405
406 nexthop_add (rib, nexthop);
407
408 return nexthop;
409}
410
c8a1cb5c
DS
411struct nexthop *
412nexthop_ipv4_ifindex_ol_add (struct rib *rib, const struct in_addr *ipv4,
413 const struct in_addr *src, const unsigned int ifindex)
414{
415 struct nexthop *nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
416
417 nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
418 IPV4_ADDR_COPY (&nexthop->gate.ipv4, ipv4);
419 if (src)
420 IPV4_ADDR_COPY (&nexthop->src.ipv4, src);
421 nexthop->ifindex = ifindex;
422 SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK);
423 nexthop_add (rib, nexthop);
424 return nexthop;
425}
426
718e3744 427#ifdef HAVE_IPV6
428struct nexthop *
429nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
430{
431 struct nexthop *nexthop;
432
393deb9b 433 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
718e3744 434 nexthop->type = NEXTHOP_TYPE_IPV6;
435 nexthop->gate.ipv6 = *ipv6;
436
437 nexthop_add (rib, nexthop);
438
439 return nexthop;
440}
441
41fc2714 442struct nexthop *
718e3744 443nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
444 char *ifname)
445{
446 struct nexthop *nexthop;
447
393deb9b 448 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
718e3744 449 nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
450 nexthop->gate.ipv6 = *ipv6;
451 nexthop->ifname = XSTRDUP (0, ifname);
452
453 nexthop_add (rib, nexthop);
454
455 return nexthop;
456}
457
41fc2714 458struct nexthop *
718e3744 459nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
460 unsigned int ifindex)
461{
462 struct nexthop *nexthop;
463
393deb9b 464 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
718e3744 465 nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
466 nexthop->gate.ipv6 = *ipv6;
467 nexthop->ifindex = ifindex;
468
469 nexthop_add (rib, nexthop);
470
471 return nexthop;
472}
473#endif /* HAVE_IPV6 */
474
595db7f1 475struct nexthop *
476nexthop_blackhole_add (struct rib *rib)
477{
478 struct nexthop *nexthop;
479
393deb9b 480 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
595db7f1 481 nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
482 SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
483
484 nexthop_add (rib, nexthop);
485
486 return nexthop;
487}
488
fa713d9e
CF
489/* This method checks whether a recursive nexthop has at
490 * least one resolved nexthop in the fib.
491 */
492int
493nexthop_has_fib_child(struct nexthop *nexthop)
494{
495 struct nexthop *nh;
496
497 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
498 return 0;
499
500 for (nh = nexthop->resolved; nh; nh = nh->next)
501 if (CHECK_FLAG (nh->flags, NEXTHOP_FLAG_FIB))
502 return 1;
503
504 return 0;
505}
506
718e3744 507/* If force flag is not set, do not modify falgs at all for uninstall
508 the route from FIB. */
a1ac18c4 509static int
718e3744 510nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
511 struct route_node *top)
512{
513 struct prefix_ipv4 p;
514 struct route_table *table;
515 struct route_node *rn;
516 struct rib *match;
fa713d9e 517 int resolved;
6e26278c 518 struct nexthop *newhop, *tnewhop;
fa713d9e 519 struct nexthop *resolved_hop;
6e26278c 520 int recursing = 0;
c8a1cb5c 521 struct interface *ifp;
718e3744 522
523 if (nexthop->type == NEXTHOP_TYPE_IPV4)
524 nexthop->ifindex = 0;
525
526 if (set)
fa713d9e
CF
527 {
528 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
6e26278c 529 nexthops_free(nexthop->resolved, top);
fa713d9e
CF
530 nexthop->resolved = NULL;
531 }
718e3744 532
6e26278c
DS
533 /* Skip nexthops that have been filtered out due to route-map */
534 /* The nexthops are specific to this route and so the same */
535 /* nexthop for a different route may not have this flag set */
536 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FILTERED))
537 return 0;
538
c8a1cb5c
DS
539 /* onlink flag is an indication that we need to only check that
540 * the link is up, we won't find the GW address in the routing
541 * table.
542 */
543 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
544 {
545 ifp = if_lookup_by_index (nexthop->ifindex);
546 if (ifp && if_is_operative(ifp))
547 return 1;
548 else
549 return 0;
550 }
551
718e3744 552 /* Make lookup prefix. */
553 memset (&p, 0, sizeof (struct prefix_ipv4));
554 p.family = AF_INET;
555 p.prefixlen = IPV4_MAX_PREFIXLEN;
556 p.prefix = nexthop->gate.ipv4;
557
558 /* Lookup table. */
559 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
560 if (! table)
561 return 0;
562
563 rn = route_node_match (table, (struct prefix *) &p);
564 while (rn)
565 {
566 route_unlock_node (rn);
567
a50c107e 568 /* If lookup self prefix return immediately. */
718e3744 569 if (rn == top)
570 return 0;
571
572 /* Pick up selected route. */
9fd92e3c 573 RNODE_FOREACH_RIB (rn, match)
16814f96
SH
574 {
575 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
576 continue;
577 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
578 break;
579 }
718e3744 580
581 /* If there is no selected route or matched route is EGP, go up
582 tree. */
6e26278c 583 if (! match)
718e3744 584 {
585 do {
586 rn = rn->parent;
587 } while (rn && rn->info == NULL);
588 if (rn)
589 route_lock_node (rn);
590 }
591 else
592 {
48a53dc7
CF
593 /* If the longest prefix match for the nexthop yields
594 * a blackhole, mark it as inactive. */
595 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE)
596 || CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT))
597 return 0;
598
718e3744 599 if (match->type == ZEBRA_ROUTE_CONNECT)
600 {
601 /* Directly point connected route. */
602 newhop = match->nexthop;
603 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
604 nexthop->ifindex = newhop->ifindex;
605
606 return 1;
607 }
608 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
609 {
fa713d9e 610 resolved = 0;
718e3744 611 for (newhop = match->nexthop; newhop; newhop = newhop->next)
612 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
613 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
614 {
615 if (set)
616 {
617 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
6e26278c 618 SET_FLAG(rib->status, RIB_ENTRY_NEXTHOPS_CHANGED);
fa713d9e
CF
619
620 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
621 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
c3e6b595
CF
622 /* If the resolving route specifies a gateway, use it */
623 if (newhop->type == NEXTHOP_TYPE_IPV4
624 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX
625 || newhop->type == NEXTHOP_TYPE_IPV4_IFNAME)
626 {
627 resolved_hop->type = newhop->type;
628 resolved_hop->gate.ipv4 = newhop->gate.ipv4;
629
630 if (newhop->ifindex)
631 {
632 resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
633 resolved_hop->ifindex = newhop->ifindex;
f44f6668
DS
634 if (newhop->flags & NEXTHOP_FLAG_ONLINK)
635 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
c3e6b595
CF
636 }
637 }
638
639 /* If the resolving route is an interface route,
640 * it means the gateway we are looking up is connected
641 * to that interface. (The actual network is _not_ onlink).
642 * Therefore, the resolved route should have the original
643 * gateway as nexthop as it is directly connected.
644 *
645 * On Linux, we have to set the onlink netlink flag because
646 * otherwise, the kernel won't accept the route. */
718e3744 647 if (newhop->type == NEXTHOP_TYPE_IFINDEX
c3e6b595
CF
648 || newhop->type == NEXTHOP_TYPE_IFNAME)
649 {
650 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
651 resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
652 resolved_hop->gate.ipv4 = nexthop->gate.ipv4;
653 resolved_hop->ifindex = newhop->ifindex;
654 }
fa713d9e 655
6e26278c
DS
656 _nexthop_add(&nexthop->resolved, resolved_hop);
657 }
658 resolved = 1;
659 }
660 return resolved;
661 }
662 else if (rib->type == ZEBRA_ROUTE_STATIC)
663 {
664 resolved = 0;
665 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
666 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
667 {
668 if (set)
669 {
670 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
671
672 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
673 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
674 /* If the resolving route specifies a gateway, use it */
675 if (newhop->type == NEXTHOP_TYPE_IPV4
676 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX
677 || newhop->type == NEXTHOP_TYPE_IPV4_IFNAME)
678 {
679 resolved_hop->type = newhop->type;
680 resolved_hop->gate.ipv4 = newhop->gate.ipv4;
681
682 if (newhop->ifindex)
683 {
684 resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
685 resolved_hop->ifindex = newhop->ifindex;
f44f6668
DS
686 if (newhop->flags & NEXTHOP_FLAG_ONLINK)
687 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
6e26278c
DS
688 }
689 }
690
691 /* If the resolving route is an interface route,
692 * it means the gateway we are looking up is connected
693 * to that interface. (The actual network is _not_ onlink).
694 * Therefore, the resolved route should have the original
695 * gateway as nexthop as it is directly connected.
696 *
697 * On Linux, we have to set the onlink netlink flag because
698 * otherwise, the kernel won't accept the route.
699 */
700 if (newhop->type == NEXTHOP_TYPE_IFINDEX
701 || newhop->type == NEXTHOP_TYPE_IFNAME)
702 {
703 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
704 resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
705 resolved_hop->gate.ipv4 = nexthop->gate.ipv4;
706 resolved_hop->ifindex = newhop->ifindex;
707 }
708
fa713d9e 709 _nexthop_add(&nexthop->resolved, resolved_hop);
718e3744 710 }
fa713d9e 711 resolved = 1;
718e3744 712 }
fa713d9e 713 return resolved;
718e3744 714 }
715 else
716 {
717 return 0;
718 }
719 }
720 }
721 return 0;
722}
723
724#ifdef HAVE_IPV6
725/* If force flag is not set, do not modify falgs at all for uninstall
726 the route from FIB. */
a1ac18c4 727static int
718e3744 728nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
729 struct route_node *top)
730{
731 struct prefix_ipv6 p;
732 struct route_table *table;
733 struct route_node *rn;
734 struct rib *match;
fa713d9e 735 int resolved;
6e26278c
DS
736 struct nexthop *newhop, *tnewhop;
737 int recursing = 0;
fa713d9e 738 struct nexthop *resolved_hop;
718e3744 739
740 if (nexthop->type == NEXTHOP_TYPE_IPV6)
741 nexthop->ifindex = 0;
742
743 if (set)
fa713d9e
CF
744 {
745 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
6e26278c 746 nexthops_free(nexthop->resolved, top);
fa713d9e
CF
747 nexthop->resolved = NULL;
748 }
718e3744 749
6e26278c
DS
750 /* Skip nexthops that have been filtered out due to route-map */
751 /* The nexthops are specific to this route and so the same */
752 /* nexthop for a different route may not have this flag set */
753 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FILTERED))
754 return 0;
755
718e3744 756 /* Make lookup prefix. */
757 memset (&p, 0, sizeof (struct prefix_ipv6));
758 p.family = AF_INET6;
759 p.prefixlen = IPV6_MAX_PREFIXLEN;
760 p.prefix = nexthop->gate.ipv6;
761
762 /* Lookup table. */
763 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
764 if (! table)
765 return 0;
766
767 rn = route_node_match (table, (struct prefix *) &p);
768 while (rn)
769 {
770 route_unlock_node (rn);
771
a50c107e 772 /* If lookup self prefix return immediately. */
718e3744 773 if (rn == top)
774 return 0;
775
776 /* Pick up selected route. */
9fd92e3c 777 RNODE_FOREACH_RIB (rn, match)
16814f96
SH
778 {
779 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
780 continue;
781 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
782 break;
783 }
718e3744 784
785 /* If there is no selected route or matched route is EGP, go up
786 tree. */
6e26278c 787 if (! match)
718e3744 788 {
789 do {
790 rn = rn->parent;
791 } while (rn && rn->info == NULL);
792 if (rn)
793 route_lock_node (rn);
794 }
795 else
796 {
48a53dc7
CF
797 /* If the longest prefix match for the nexthop yields
798 * a blackhole, mark it as inactive. */
799 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE)
800 || CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT))
801 return 0;
802
718e3744 803 if (match->type == ZEBRA_ROUTE_CONNECT)
804 {
805 /* Directly point connected route. */
806 newhop = match->nexthop;
807
808 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
809 nexthop->ifindex = newhop->ifindex;
810
811 return 1;
812 }
813 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
814 {
fa713d9e 815 resolved = 0;
718e3744 816 for (newhop = match->nexthop; newhop; newhop = newhop->next)
817 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
818 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
6e26278c
DS
819 {
820 if (set)
821 {
822 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
823 SET_FLAG(rib->status, RIB_ENTRY_NEXTHOPS_CHANGED);
824
825 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
826 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
827 /* See nexthop_active_ipv4 for a description how the
828 * resolved nexthop is constructed. */
829 if (newhop->type == NEXTHOP_TYPE_IPV6
830 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
831 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
832 {
833 resolved_hop->type = newhop->type;
834 resolved_hop->gate.ipv6 = newhop->gate.ipv6;
835
836 if (newhop->ifindex)
837 {
838 resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
839 resolved_hop->ifindex = newhop->ifindex;
840 }
841 }
842
843 if (newhop->type == NEXTHOP_TYPE_IFINDEX
844 || newhop->type == NEXTHOP_TYPE_IFNAME)
845 {
846 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
847 resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
848 resolved_hop->gate.ipv6 = nexthop->gate.ipv6;
849 resolved_hop->ifindex = newhop->ifindex;
850 }
851
852 _nexthop_add(&nexthop->resolved, resolved_hop);
853 }
854 resolved = 1;
855 }
856 return resolved;
857 }
858 else if (rib->type == ZEBRA_ROUTE_STATIC)
859 {
860 resolved = 0;
861 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
862 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
718e3744 863 {
864 if (set)
865 {
866 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
fa713d9e
CF
867
868 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
869 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
c3e6b595
CF
870 /* See nexthop_active_ipv4 for a description how the
871 * resolved nexthop is constructed. */
718e3744 872 if (newhop->type == NEXTHOP_TYPE_IPV6
873 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
874 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
c3e6b595
CF
875 {
876 resolved_hop->type = newhop->type;
877 resolved_hop->gate.ipv6 = newhop->gate.ipv6;
878
879 if (newhop->ifindex)
880 {
881 resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
882 resolved_hop->ifindex = newhop->ifindex;
883 }
884 }
fa713d9e 885
718e3744 886 if (newhop->type == NEXTHOP_TYPE_IFINDEX
c3e6b595
CF
887 || newhop->type == NEXTHOP_TYPE_IFNAME)
888 {
889 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
890 resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
891 resolved_hop->gate.ipv6 = nexthop->gate.ipv6;
892 resolved_hop->ifindex = newhop->ifindex;
893 }
fa713d9e
CF
894
895 _nexthop_add(&nexthop->resolved, resolved_hop);
718e3744 896 }
fa713d9e 897 resolved = 1;
718e3744 898 }
fa713d9e 899 return resolved;
718e3744 900 }
901 else
902 {
903 return 0;
904 }
905 }
906 }
907 return 0;
908}
909#endif /* HAVE_IPV6 */
910
911struct rib *
912rib_match_ipv4 (struct in_addr addr)
913{
914 struct prefix_ipv4 p;
915 struct route_table *table;
916 struct route_node *rn;
917 struct rib *match;
fa713d9e
CF
918 struct nexthop *newhop, *tnewhop;
919 int recursing;
718e3744 920
921 /* Lookup table. */
922 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
923 if (! table)
924 return 0;
925
926 memset (&p, 0, sizeof (struct prefix_ipv4));
927 p.family = AF_INET;
928 p.prefixlen = IPV4_MAX_PREFIXLEN;
929 p.prefix = addr;
930
931 rn = route_node_match (table, (struct prefix *) &p);
932
933 while (rn)
934 {
935 route_unlock_node (rn);
936
937 /* Pick up selected route. */
9fd92e3c 938 RNODE_FOREACH_RIB (rn, match)
16814f96
SH
939 {
940 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
941 continue;
942 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
943 break;
944 }
718e3744 945
946 /* If there is no selected route or matched route is EGP, go up
947 tree. */
6e26278c 948 if (! match)
718e3744 949 {
950 do {
951 rn = rn->parent;
952 } while (rn && rn->info == NULL);
953 if (rn)
954 route_lock_node (rn);
955 }
956 else
957 {
958 if (match->type == ZEBRA_ROUTE_CONNECT)
959 /* Directly point connected route. */
960 return match;
961 else
962 {
fa713d9e 963 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
718e3744 964 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
965 return match;
966 return NULL;
967 }
968 }
969 }
970 return NULL;
971}
972
973struct rib *
974rib_lookup_ipv4 (struct prefix_ipv4 *p)
975{
976 struct route_table *table;
977 struct route_node *rn;
978 struct rib *match;
fa713d9e
CF
979 struct nexthop *nexthop, *tnexthop;
980 int recursing;
718e3744 981
982 /* Lookup table. */
983 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
984 if (! table)
985 return 0;
986
987 rn = route_node_lookup (table, (struct prefix *) p);
988
989 /* No route for this prefix. */
990 if (! rn)
991 return NULL;
992
993 /* Unlock node. */
994 route_unlock_node (rn);
995
9fd92e3c 996 RNODE_FOREACH_RIB (rn, match)
16814f96
SH
997 {
998 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
999 continue;
1000 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
1001 break;
1002 }
718e3744 1003
6e26278c 1004 if (! match)
718e3744 1005 return NULL;
1006
1007 if (match->type == ZEBRA_ROUTE_CONNECT)
1008 return match;
1009
fa713d9e 1010 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
718e3744 1011 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1012 return match;
1013
1014 return NULL;
1015}
1016
dc95824a
DO
1017/*
1018 * This clone function, unlike its original rib_lookup_ipv4(), checks
1019 * if specified IPv4 route record (prefix/mask -> gate) exists in
1020 * the whole RIB and has ZEBRA_FLAG_SELECTED set.
1021 *
1022 * Return values:
1023 * -1: error
1024 * 0: exact match found
1025 * 1: a match was found with a different gate
1026 * 2: connected route found
1027 * 3: no matches found
1028 */
1029int
1030rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
1031{
1032 struct route_table *table;
1033 struct route_node *rn;
1034 struct rib *match;
fa713d9e
CF
1035 struct nexthop *nexthop, *tnexthop;
1036 int recursing;
1037 int nexthops_active;
dc95824a
DO
1038
1039 /* Lookup table. */
1040 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1041 if (! table)
1042 return ZEBRA_RIB_LOOKUP_ERROR;
1043
1044 /* Scan the RIB table for exactly matching RIB entry. */
1045 rn = route_node_lookup (table, (struct prefix *) p);
1046
1047 /* No route for this prefix. */
1048 if (! rn)
1049 return ZEBRA_RIB_NOTFOUND;
1050
1051 /* Unlock node. */
1052 route_unlock_node (rn);
1053
1054 /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
9fd92e3c 1055 RNODE_FOREACH_RIB (rn, match)
16814f96
SH
1056 {
1057 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
1058 continue;
1059 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
1060 break;
1061 }
dc95824a
DO
1062
1063 /* None such found :( */
1064 if (!match)
1065 return ZEBRA_RIB_NOTFOUND;
1066
1067 if (match->type == ZEBRA_ROUTE_CONNECT)
1068 return ZEBRA_RIB_FOUND_CONNECTED;
1069
1070 /* Ok, we have a cood candidate, let's check it's nexthop list... */
fa713d9e
CF
1071 nexthops_active = 0;
1072 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
dc95824a 1073 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
dc95824a 1074 {
fa713d9e
CF
1075 nexthops_active = 1;
1076 if (nexthop->gate.ipv4.s_addr == sockunion2ip (qgate))
1077 return ZEBRA_RIB_FOUND_EXACT;
dc95824a 1078 if (IS_ZEBRA_DEBUG_RIB)
fa713d9e
CF
1079 {
1080 char gate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
1081 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
1082 inet_ntop (AF_INET, &sockunion2ip(qgate), qgate_buf, INET_ADDRSTRLEN);
1083 zlog_debug ("%s: qgate == %s, %s == %s", __func__,
1084 qgate_buf, recursing ? "rgate" : "gate", gate_buf);
1085 }
dc95824a 1086 }
fa713d9e
CF
1087
1088 if (nexthops_active)
1089 return ZEBRA_RIB_FOUND_NOGATE;
dc95824a
DO
1090
1091 return ZEBRA_RIB_NOTFOUND;
1092}
1093
718e3744 1094#ifdef HAVE_IPV6
1095struct rib *
1096rib_match_ipv6 (struct in6_addr *addr)
1097{
1098 struct prefix_ipv6 p;
1099 struct route_table *table;
1100 struct route_node *rn;
1101 struct rib *match;
fa713d9e
CF
1102 struct nexthop *newhop, *tnewhop;
1103 int recursing;
718e3744 1104
1105 /* Lookup table. */
1106 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1107 if (! table)
1108 return 0;
1109
1110 memset (&p, 0, sizeof (struct prefix_ipv6));
1111 p.family = AF_INET6;
1112 p.prefixlen = IPV6_MAX_PREFIXLEN;
1113 IPV6_ADDR_COPY (&p.prefix, addr);
1114
1115 rn = route_node_match (table, (struct prefix *) &p);
1116
1117 while (rn)
1118 {
1119 route_unlock_node (rn);
1120
1121 /* Pick up selected route. */
9fd92e3c 1122 RNODE_FOREACH_RIB (rn, match)
16814f96
SH
1123 {
1124 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
1125 continue;
1126 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
1127 break;
1128 }
718e3744 1129
1130 /* If there is no selected route or matched route is EGP, go up
1131 tree. */
6e26278c 1132 if (! match)
718e3744 1133 {
1134 do {
1135 rn = rn->parent;
1136 } while (rn && rn->info == NULL);
1137 if (rn)
1138 route_lock_node (rn);
1139 }
1140 else
1141 {
1142 if (match->type == ZEBRA_ROUTE_CONNECT)
1143 /* Directly point connected route. */
1144 return match;
1145 else
1146 {
fa713d9e 1147 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
718e3744 1148 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
1149 return match;
1150 return NULL;
1151 }
1152 }
1153 }
1154 return NULL;
1155}
1156#endif /* HAVE_IPV6 */
1157
7514fb77
PJ
1158#define RIB_SYSTEM_ROUTE(R) \
1159 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
1160
dc95824a
DO
1161/* This function verifies reachability of one given nexthop, which can be
1162 * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
1163 * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
1164 * nexthop->ifindex will be updated appropriately as well.
1165 * An existing route map can turn (otherwise active) nexthop into inactive, but
1166 * not vice versa.
1167 *
1168 * The return value is the final value of 'ACTIVE' flag.
1169 */
1170
d02c56cd 1171static unsigned
718e3744 1172nexthop_active_check (struct route_node *rn, struct rib *rib,
1173 struct nexthop *nexthop, int set)
1174{
f3a1732e 1175 rib_table_info_t *info = rn->table->info;
718e3744 1176 struct interface *ifp;
7514fb77 1177 route_map_result_t ret = RMAP_MATCH;
7514fb77 1178 int family;
518f0eb1 1179 char buf[INET6_ADDRSTRLEN+1];
718e3744 1180
7a4bb9c5
DS
1181 if (rn->p.family == AF_INET)
1182 family = AFI_IP;
1183 else if (rn->p.family == AF_INET6)
1184 family = AFI_IP6;
1185 else
1186 family = 0;
718e3744 1187 switch (nexthop->type)
1188 {
1189 case NEXTHOP_TYPE_IFINDEX:
1190 ifp = if_lookup_by_index (nexthop->ifindex);
3f087670 1191 if (ifp && if_is_operative(ifp))
718e3744 1192 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1193 else
1194 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1195 break;
718e3744 1196 case NEXTHOP_TYPE_IPV6_IFNAME:
7514fb77
PJ
1197 family = AFI_IP6;
1198 case NEXTHOP_TYPE_IFNAME:
718e3744 1199 ifp = if_lookup_by_name (nexthop->ifname);
3f087670 1200 if (ifp && if_is_operative(ifp))
718e3744 1201 {
1202 if (set)
1203 nexthop->ifindex = ifp->ifindex;
1204 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1205 }
1206 else
1207 {
1208 if (set)
1209 nexthop->ifindex = 0;
1210 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1211 }
1212 break;
1213 case NEXTHOP_TYPE_IPV4:
1214 case NEXTHOP_TYPE_IPV4_IFINDEX:
7514fb77 1215 family = AFI_IP;
718e3744 1216 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
1217 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1218 else
1219 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1220 break;
1221#ifdef HAVE_IPV6
1222 case NEXTHOP_TYPE_IPV6:
7514fb77 1223 family = AFI_IP6;
718e3744 1224 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
1225 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1226 else
1227 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1228 break;
1229 case NEXTHOP_TYPE_IPV6_IFINDEX:
7514fb77 1230 family = AFI_IP6;
718e3744 1231 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
1232 {
1233 ifp = if_lookup_by_index (nexthop->ifindex);
3f087670 1234 if (ifp && if_is_operative(ifp))
718e3744 1235 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1236 else
1237 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1238 }
1239 else
1240 {
1241 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
1242 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1243 else
1244 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1245 }
1246 break;
1247#endif /* HAVE_IPV6 */
595db7f1 1248 case NEXTHOP_TYPE_BLACKHOLE:
1249 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1250 break;
718e3744 1251 default:
1252 break;
1253 }
7514fb77
PJ
1254 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1255 return 0;
1256
f3a1732e
CF
1257 /* XXX: What exactly do those checks do? Do we support
1258 * e.g. IPv4 routes with IPv6 nexthops or vice versa? */
7514fb77
PJ
1259 if (RIB_SYSTEM_ROUTE(rib) ||
1260 (family == AFI_IP && rn->p.family != AF_INET) ||
1261 (family == AFI_IP6 && rn->p.family != AF_INET6))
1262 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1263
f3a1732e
CF
1264 /* The original code didn't determine the family correctly
1265 * e.g. for NEXTHOP_TYPE_IFINDEX. Retrieve the correct afi
1266 * from the rib_table_info in those cases.
1267 * Possibly it may be better to use only the rib_table_info
1268 * in every case.
1269 */
1270 if (!family)
1271 family = info->afi;
1272
c52ef59f 1273 memset(&nexthop->rmap_src.ipv6, 0, sizeof(union g_addr));
c52ef59f 1274
ca84c8ef
DS
1275 /* It'll get set if required inside */
1276 ret = zebra_route_map_check(family, rib->type, &rn->p, nexthop, rib->tag);
7514fb77 1277 if (ret == RMAP_DENYMATCH)
518f0eb1
DS
1278 {
1279 if (IS_ZEBRA_DEBUG_RIB)
1280 {
1281 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, sizeof (buf));
1282 zlog_debug("%s: Filtering out %s with NH out %s due to route map",
1283 __FUNCTION__, buf, nexthop->ifname);
1284 }
1285 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1286 }
c52ef59f 1287
718e3744 1288 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1289}
1290
03e232a4
DO
1291/* Iterate over all nexthops of the given RIB entry and refresh their
1292 * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
1293 * nexthop is found to toggle the ACTIVE flag, the whole rib structure
1294 * is flagged with ZEBRA_FLAG_CHANGED. The 4th 'set' argument is
1295 * transparently passed to nexthop_active_check().
1296 *
1297 * Return value is the new number of active nexthops.
1298 */
1299
a1ac18c4 1300static int
718e3744 1301nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
1302{
1303 struct nexthop *nexthop;
c52ef59f 1304 union g_addr prev_src;
6e26278c
DS
1305 unsigned int prev_active, prev_index, new_active, old_num_nh;
1306
1307 old_num_nh = rib->nexthop_active_num;
718e3744 1308
1309 rib->nexthop_active_num = 0;
1310 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1311
1312 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
03e232a4 1313 {
c52ef59f
DS
1314 /* No protocol daemon provides src and so we're skipping tracking it */
1315 prev_src = nexthop->rmap_src;
03e232a4 1316 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
c3a56063 1317 prev_index = nexthop->ifindex;
03e232a4
DO
1318 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
1319 rib->nexthop_active_num++;
c52ef59f 1320 /* Don't allow src setting on IPv6 addr for now */
c3a56063 1321 if (prev_active != new_active ||
c52ef59f
DS
1322 prev_index != nexthop->ifindex ||
1323 ((nexthop->type >= NEXTHOP_TYPE_IFINDEX &&
1324 nexthop->type < NEXTHOP_TYPE_IPV6) &&
1325 prev_src.ipv4.s_addr != nexthop->rmap_src.ipv4.s_addr))
6e26278c
DS
1326 {
1327 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1328 SET_FLAG (rib->status, RIB_ENTRY_NEXTHOPS_CHANGED);
1329 }
03e232a4 1330 }
6e26278c
DS
1331
1332 if (old_num_nh != rib->nexthop_active_num)
1333 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1334
1335 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_CHANGED))
1336 {
1337 SET_FLAG (rib->status, RIB_ENTRY_NEXTHOPS_CHANGED);
1338 }
1339
718e3744 1340 return rib->nexthop_active_num;
1341}
6baeb988 1342
6b0655a2 1343
718e3744 1344
a1ac18c4 1345static void
718e3744 1346rib_install_kernel (struct route_node *rn, struct rib *rib)
1347{
1348 int ret = 0;
fa713d9e
CF
1349 struct nexthop *nexthop, *tnexthop;
1350 int recursing;
718e3744 1351
5adc2528
AS
1352 /*
1353 * Make sure we update the FPM any time we send new information to
1354 * the kernel.
1355 */
1356 zfpm_trigger_update (rn, "installing in kernel");
718e3744 1357 switch (PREFIX_FAMILY (&rn->p))
1358 {
1359 case AF_INET:
1360 ret = kernel_add_ipv4 (&rn->p, rib);
1361 break;
1362#ifdef HAVE_IPV6
1363 case AF_INET6:
1364 ret = kernel_add_ipv6 (&rn->p, rib);
1365 break;
1366#endif /* HAVE_IPV6 */
1367 }
1368
dc95824a 1369 /* This condition is never met, if we are using rt_socket.c */
718e3744 1370 if (ret < 0)
1371 {
fa713d9e 1372 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
718e3744 1373 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1374 }
1375}
1376
1377/* Uninstall the route from kernel. */
a1ac18c4 1378static int
718e3744 1379rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
1380{
1381 int ret = 0;
fa713d9e
CF
1382 struct nexthop *nexthop, *tnexthop;
1383 int recursing;
718e3744 1384
5adc2528
AS
1385 /*
1386 * Make sure we update the FPM any time we send new information to
1387 * the kernel.
1388 */
1389 zfpm_trigger_update (rn, "uninstalling from kernel");
1390
718e3744 1391 switch (PREFIX_FAMILY (&rn->p))
1392 {
1393 case AF_INET:
1394 ret = kernel_delete_ipv4 (&rn->p, rib);
1395 break;
1396#ifdef HAVE_IPV6
1397 case AF_INET6:
1398 ret = kernel_delete_ipv6 (&rn->p, rib);
1399 break;
1400#endif /* HAVE_IPV6 */
1401 }
1402
fa713d9e 1403 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
718e3744 1404 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1405
1406 return ret;
1407}
1408
1409/* Uninstall the route from kernel. */
a1ac18c4 1410static void
718e3744 1411rib_uninstall (struct route_node *rn, struct rib *rib)
1412{
1413 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1414 {
5adc2528
AS
1415 zfpm_trigger_update (rn, "rib_uninstall");
1416
718e3744 1417 redistribute_delete (&rn->p, rib);
1418 if (! RIB_SYSTEM_ROUTE (rib))
1419 rib_uninstall_kernel (rn, rib);
1420 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
1421 }
1422}
1423
6d691129
PJ
1424static void rib_unlink (struct route_node *, struct rib *);
1425
9fd92e3c
AS
1426/*
1427 * rib_can_delete_dest
1428 *
1429 * Returns TRUE if the given dest can be deleted from the table.
1430 */
1431static int
1432rib_can_delete_dest (rib_dest_t *dest)
1433{
1434 if (dest->routes)
1435 {
1436 return 0;
1437 }
1438
5adc2528
AS
1439 /*
1440 * Don't delete the dest if we have to update the FPM about this
1441 * prefix.
1442 */
1443 if (CHECK_FLAG (dest->flags, RIB_DEST_UPDATE_FPM) ||
1444 CHECK_FLAG (dest->flags, RIB_DEST_SENT_TO_FPM))
1445 return 0;
1446
9fd92e3c
AS
1447 return 1;
1448}
1449
1450/*
1451 * rib_gc_dest
1452 *
1453 * Garbage collect the rib dest corresponding to the given route node
1454 * if appropriate.
1455 *
1456 * Returns TRUE if the dest was deleted, FALSE otherwise.
1457 */
1458int
1459rib_gc_dest (struct route_node *rn)
1460{
1461 rib_dest_t *dest;
1462 char buf[INET6_ADDRSTRLEN];
1463
1464 dest = rib_dest_from_rnode (rn);
1465 if (!dest)
1466 return 0;
1467
1468 if (!rib_can_delete_dest (dest))
1469 return 0;
1470
1471 if (IS_ZEBRA_DEBUG_RIB)
1472 {
1473 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, sizeof (buf));
1474 zlog_debug ("%s: %s/%d: removing dest from table", __func__,
1475 buf, rn->p.prefixlen);
1476 }
1477
1478 dest->rnode = NULL;
1479 XFREE (MTYPE_RIB_DEST, dest);
1480 rn->info = NULL;
1481
1482 /*
1483 * Release the one reference that we keep on the route node.
1484 */
1485 route_unlock_node (rn);
1486 return 1;
1487}
1488
718e3744 1489/* Core function for processing routing information base. */
e96f9203
DO
1490static void
1491rib_process (struct route_node *rn)
718e3744 1492{
1493 struct rib *rib;
1494 struct rib *next;
1495 struct rib *fib = NULL;
1496 struct rib *select = NULL;
6d691129 1497 struct rib *del = NULL;
d753e9ee 1498 int installed = 0;
fa713d9e
CF
1499 struct nexthop *nexthop = NULL, *tnexthop;
1500 int recursing;
f304cb48 1501 char buf[INET6_ADDRSTRLEN];
4d38fdb4 1502
1503 assert (rn);
1504
93bdadae 1505 if (IS_ZEBRA_DEBUG_RIB || IS_ZEBRA_DEBUG_RIB_Q)
f304cb48 1506 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
93bdadae 1507
9fd92e3c 1508 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
718e3744 1509 {
6e26278c
DS
1510 UNSET_FLAG(rib->status, RIB_ENTRY_NEXTHOPS_CHANGED);
1511
718e3744 1512 /* Currently installed rib. */
1513 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
6d691129
PJ
1514 {
1515 assert (fib == NULL);
1516 fib = rib;
1517 }
ca657c65 1518
6d691129
PJ
1519 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1520 * which we need to do do further work with below.
1521 */
1522 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1523 {
1524 if (rib != fib)
1525 {
1526 if (IS_ZEBRA_DEBUG_RIB)
93bdadae
PJ
1527 zlog_debug ("%s: %s/%d: rn %p, removing rib %p", __func__,
1528 buf, rn->p.prefixlen, rn, rib);
9fd92e3c 1529 rib_unlink (rn, rib);
6d691129
PJ
1530 }
1531 else
1532 del = rib;
1533
1534 continue;
1535 }
4d38fdb4 1536
718e3744 1537 /* Skip unreachable nexthop. */
ca657c65
DS
1538 /* This first call to nexthop_active_update is merely to determine if
1539 * there's any change to nexthops associated with this RIB entry. Now,
1540 * rib_process() can be invoked due to an external event such as link
1541 * down or due to next-hop-tracking evaluation. In the latter case,
1542 * a decision has already been made that the NHs have changed. So, no
1543 * need to invoke a potentially expensive call again. Further, since
1544 * the change might be in a recursive NH which is not caught in
1545 * the nexthop_active_update() code. Thus, we might miss changes to
1546 * recursive NHs.
6e26278c 1547 */
ca657c65 1548 if (!CHECK_FLAG(rib->flags, ZEBRA_FLAG_CHANGED) &&
6e26278c 1549 ! nexthop_active_update (rn, rib, 0))
7021c425 1550 continue;
718e3744 1551
1552 /* Infinit distance. */
1553 if (rib->distance == DISTANCE_INFINITY)
7021c425 1554 continue;
718e3744 1555
af887b51 1556 /* Newly selected rib, the common case. */
1557 if (!select)
1558 {
1559 select = rib;
1560 continue;
1561 }
1562
1563 /* filter route selection in following order:
af887b51 1564 * - connected beats other types
a8d9c1f9 1565 * - lower distance beats higher
af887b51 1566 * - lower metric beats higher for equal distance
1567 * - last, hence oldest, route wins tie break.
1568 */
a1038a15 1569
1570 /* Connected routes. Pick the last connected
1571 * route of the set of lowest metric connected routes.
1572 */
a8d9c1f9 1573 if (rib->type == ZEBRA_ROUTE_CONNECT)
1574 {
a1038a15 1575 if (select->type != ZEBRA_ROUTE_CONNECT
a8d9c1f9 1576 || rib->metric <= select->metric)
a1038a15 1577 select = rib;
1578 continue;
a8d9c1f9 1579 }
1580 else if (select->type == ZEBRA_ROUTE_CONNECT)
1581 continue;
1582
1583 /* higher distance loses */
1584 if (rib->distance > select->distance)
1585 continue;
1586
1587 /* lower wins */
1588 if (rib->distance < select->distance)
1589 {
af887b51 1590 select = rib;
a8d9c1f9 1591 continue;
1592 }
1593
1594 /* metric tie-breaks equal distance */
1595 if (rib->metric <= select->metric)
1596 select = rib;
9fd92e3c 1597 } /* RNODE_FOREACH_RIB_SAFE */
dc95824a
DO
1598
1599 /* After the cycle is finished, the following pointers will be set:
1600 * select --- the winner RIB entry, if any was found, otherwise NULL
1601 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1602 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1603 * rib --- NULL
1604 */
1605
1606 /* Same RIB entry is selected. Update FIB and finish. */
718e3744 1607 if (select && select == fib)
1608 {
6d691129 1609 if (IS_ZEBRA_DEBUG_RIB)
93bdadae
PJ
1610 zlog_debug ("%s: %s/%d: Updating existing route, select %p, fib %p",
1611 __func__, buf, rn->p.prefixlen, select, fib);
718e3744 1612 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
4d38fdb4 1613 {
5adc2528
AS
1614 zfpm_trigger_update (rn, "updating existing route");
1615
4d38fdb4 1616 redistribute_delete (&rn->p, select);
1617 if (! RIB_SYSTEM_ROUTE (select))
1618 rib_uninstall_kernel (rn, select);
718e3744 1619
4d38fdb4 1620 /* Set real nexthop. */
6e26278c
DS
1621 /* Need to check if any NHs are active to clear the
1622 * the selected flag
1623 */
1624 if (nexthop_active_update (rn, select, 1))
1625 {
1626 if (! RIB_SYSTEM_ROUTE (select))
1627 rib_install_kernel (rn, select);
1628 redistribute_add (&rn->p, select);
1629 }
1630 else
1631 {
1632 UNSET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1633 }
ca657c65 1634 UNSET_FLAG (select->flags, ZEBRA_FLAG_CHANGED);
6e26278c 1635 }
d753e9ee 1636 else if (! RIB_SYSTEM_ROUTE (select))
4d38fdb4 1637 {
1638 /* Housekeeping code to deal with
1639 race conditions in kernel with linux
1640 netlink reporting interface up before IPv4 or IPv6 protocol
1641 is ready to add routes.
1642 This makes sure the routes are IN the kernel.
1643 */
1644
fa713d9e 1645 for (ALL_NEXTHOPS_RO(select->nexthop, nexthop, tnexthop, recursing))
a3aaf5b0 1646 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
4d38fdb4 1647 {
a3aaf5b0
DO
1648 installed = 1;
1649 break;
4d38fdb4 1650 }
1651 if (! installed)
1652 rib_install_kernel (rn, select);
1653 }
6d691129 1654 goto end;
718e3744 1655 }
1656
dc95824a
DO
1657 /* At this point we either haven't found the best RIB entry or it is
1658 * different from what we currently intend to flag with SELECTED. In both
1659 * cases, if a RIB block is present in FIB, it should be withdrawn.
1660 */
718e3744 1661 if (fib)
1662 {
6d691129 1663 if (IS_ZEBRA_DEBUG_RIB)
93bdadae
PJ
1664 zlog_debug ("%s: %s/%d: Removing existing route, fib %p", __func__,
1665 buf, rn->p.prefixlen, fib);
5adc2528
AS
1666
1667 zfpm_trigger_update (rn, "removing existing route");
1668
718e3744 1669 redistribute_delete (&rn->p, fib);
1670 if (! RIB_SYSTEM_ROUTE (fib))
1671 rib_uninstall_kernel (rn, fib);
1672 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1673
1674 /* Set real nexthop. */
1675 nexthop_active_update (rn, fib, 1);
ca657c65 1676 UNSET_FLAG(fib->flags, ZEBRA_FLAG_CHANGED);
718e3744 1677 }
1678
dc95824a
DO
1679 /* Regardless of some RIB entry being SELECTED or not before, now we can
1680 * tell, that if a new winner exists, FIB is still not updated with this
1681 * data, but ready to be.
1682 */
718e3744 1683 if (select)
1684 {
6d691129 1685 if (IS_ZEBRA_DEBUG_RIB)
93bdadae
PJ
1686 zlog_debug ("%s: %s/%d: Adding route, select %p", __func__, buf,
1687 rn->p.prefixlen, select);
5adc2528
AS
1688
1689 zfpm_trigger_update (rn, "new route selected");
1690
718e3744 1691 /* Set real nexthop. */
6e26278c
DS
1692 if (nexthop_active_update (rn, select, 1))
1693 {
1694 if (! RIB_SYSTEM_ROUTE (select))
1695 rib_install_kernel (rn, select);
1696 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1697 redistribute_add (&rn->p, select);
1698 }
ca657c65 1699 UNSET_FLAG(select->flags, ZEBRA_FLAG_CHANGED);
718e3744 1700 }
4d38fdb4 1701
6d691129
PJ
1702 /* FIB route was removed, should be deleted */
1703 if (del)
1704 {
1705 if (IS_ZEBRA_DEBUG_RIB)
93bdadae
PJ
1706 zlog_debug ("%s: %s/%d: Deleting fib %p, rn %p", __func__, buf,
1707 rn->p.prefixlen, del, rn);
6d691129
PJ
1708 rib_unlink (rn, del);
1709 }
4d38fdb4 1710
6d691129
PJ
1711end:
1712 if (IS_ZEBRA_DEBUG_RIB_Q)
93bdadae 1713 zlog_debug ("%s: %s/%d: rn %p dequeued", __func__, buf, rn->p.prefixlen, rn);
9fd92e3c
AS
1714
1715 /*
1716 * Check if the dest can be deleted now.
1717 */
1718 rib_gc_dest (rn);
e96f9203
DO
1719}
1720
5110a0c6
SH
1721/* Take a list of route_node structs and return 1, if there was a record
1722 * picked from it and processed by rib_process(). Don't process more,
1723 * than one RN record; operate only in the specified sub-queue.
e96f9203 1724 */
ef9b113e 1725static unsigned int
e96f9203
DO
1726process_subq (struct list * subq, u_char qindex)
1727{
5110a0c6 1728 struct listnode *lnode = listhead (subq);
e96f9203 1729 struct route_node *rnode;
5110a0c6
SH
1730
1731 if (!lnode)
e96f9203 1732 return 0;
5110a0c6 1733
e96f9203
DO
1734 rnode = listgetdata (lnode);
1735 rib_process (rnode);
5110a0c6 1736
9fd92e3c
AS
1737 if (rnode->info)
1738 UNSET_FLAG (rib_dest_from_rnode (rnode)->flags, RIB_ROUTE_QUEUED (qindex));
1739
67b9467f 1740#if 0
5110a0c6
SH
1741 else
1742 {
1743 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1744 __func__, rnode, rnode->lock);
1745 zlog_backtrace(LOG_DEBUG);
1746 }
67b9467f 1747#endif
e96f9203
DO
1748 route_unlock_node (rnode);
1749 list_delete_node (subq, lnode);
1750 return 1;
1751}
1752
fb018d25
DS
1753/*
1754 * All meta queues have been processed. Trigger next-hop evaluation.
1755 */
1756static void
1757meta_queue_process_complete (struct work_queue *dummy)
1758{
078430f6
DS
1759 zebra_evaluate_rnh(0, AF_INET, 0, RNH_NEXTHOP_TYPE, NULL);
1760 zebra_evaluate_rnh(0, AF_INET, 0, RNH_IMPORT_CHECK_TYPE, NULL);
fb018d25 1761#ifdef HAVE_IPV6
078430f6
DS
1762 zebra_evaluate_rnh(0, AF_INET6, 0, RNH_NEXTHOP_TYPE, NULL);
1763 zebra_evaluate_rnh(0, AF_INET6, 0, RNH_IMPORT_CHECK_TYPE, NULL);
fb018d25
DS
1764#endif /* HAVE_IPV6 */
1765}
1766
e96f9203
DO
1767/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1768 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1769 * is pointed to the meta queue structure.
1770 */
1771static wq_item_status
1772meta_queue_process (struct work_queue *dummy, void *data)
1773{
1774 struct meta_queue * mq = data;
5110a0c6
SH
1775 unsigned i;
1776
e96f9203
DO
1777 for (i = 0; i < MQ_SIZE; i++)
1778 if (process_subq (mq->subq[i], i))
5110a0c6
SH
1779 {
1780 mq->size--;
1781 break;
1782 }
e96f9203
DO
1783 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1784}
1785
9fd92e3c
AS
1786/*
1787 * Map from rib types to queue type (priority) in meta queue
1788 */
5110a0c6
SH
1789static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
1790 [ZEBRA_ROUTE_SYSTEM] = 4,
1791 [ZEBRA_ROUTE_KERNEL] = 0,
1792 [ZEBRA_ROUTE_CONNECT] = 0,
1793 [ZEBRA_ROUTE_STATIC] = 1,
1794 [ZEBRA_ROUTE_RIP] = 2,
1795 [ZEBRA_ROUTE_RIPNG] = 2,
1796 [ZEBRA_ROUTE_OSPF] = 2,
1797 [ZEBRA_ROUTE_OSPF6] = 2,
1798 [ZEBRA_ROUTE_ISIS] = 2,
1799 [ZEBRA_ROUTE_BGP] = 3,
1800 [ZEBRA_ROUTE_HSLS] = 4,
5734509c 1801 [ZEBRA_ROUTE_BABEL] = 2,
7a4bb9c5 1802 [ZEBRA_ROUTE_TABLE] = 1,
5110a0c6
SH
1803};
1804
1805/* Look into the RN and queue it into one or more priority queues,
1806 * increasing the size for each data push done.
e96f9203 1807 */
ef9b113e
SH
1808static void
1809rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
e96f9203 1810{
e96f9203
DO
1811 struct rib *rib;
1812 char buf[INET6_ADDRSTRLEN];
5110a0c6 1813
e96f9203
DO
1814 if (IS_ZEBRA_DEBUG_RIB_Q)
1815 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
5110a0c6 1816
9fd92e3c 1817 RNODE_FOREACH_RIB (rn, rib)
e96f9203 1818 {
5110a0c6
SH
1819 u_char qindex = meta_queue_map[rib->type];
1820
1821 /* Invariant: at this point we always have rn->info set. */
9fd92e3c
AS
1822 if (CHECK_FLAG (rib_dest_from_rnode (rn)->flags,
1823 RIB_ROUTE_QUEUED (qindex)))
5110a0c6
SH
1824 {
1825 if (IS_ZEBRA_DEBUG_RIB_Q)
1826 zlog_debug ("%s: %s/%d: rn %p is already queued in sub-queue %u",
1827 __func__, buf, rn->p.prefixlen, rn, qindex);
1828 continue;
1829 }
1830
9fd92e3c 1831 SET_FLAG (rib_dest_from_rnode (rn)->flags, RIB_ROUTE_QUEUED (qindex));
5110a0c6
SH
1832 listnode_add (mq->subq[qindex], rn);
1833 route_lock_node (rn);
1834 mq->size++;
1835
e96f9203 1836 if (IS_ZEBRA_DEBUG_RIB_Q)
5110a0c6
SH
1837 zlog_debug ("%s: %s/%d: queued rn %p into sub-queue %u",
1838 __func__, buf, rn->p.prefixlen, rn, qindex);
e96f9203 1839 }
4d38fdb4 1840}
1841
6d691129 1842/* Add route_node to work queue and schedule processing */
6e26278c 1843void
6d691129 1844rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
4d38fdb4 1845{
fc328ac9
SV
1846 char buf[INET_ADDRSTRLEN];
1847 assert (zebra && rn);
4d38fdb4 1848
93bdadae 1849 if (IS_ZEBRA_DEBUG_RIB_Q)
fc328ac9
SV
1850 inet_ntop (AF_INET, &rn->p.u.prefix, buf, INET_ADDRSTRLEN);
1851
1852 /* Pointless to queue a route_node with no RIB entries to add or remove */
9fd92e3c 1853 if (!rnode_to_ribs (rn))
6d691129 1854 {
fc328ac9
SV
1855 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1856 __func__, rn, rn->lock);
1857 zlog_backtrace(LOG_DEBUG);
1858 return;
1859 }
1860
1861 if (IS_ZEBRA_DEBUG_RIB_Q)
1862 zlog_info ("%s: %s/%d: work queue added", __func__, buf, rn->p.prefixlen);
1863
1864 assert (zebra);
4d38fdb4 1865
fc328ac9
SV
1866 if (zebra->ribq == NULL)
1867 {
1868 zlog_err ("%s: work_queue does not exist!", __func__);
1869 return;
4d38fdb4 1870 }
4d38fdb4 1871
cc2dd928
SH
1872 /*
1873 * The RIB queue should normally be either empty or holding the only
1874 * work_queue_item element. In the latter case this element would
1875 * hold a pointer to the meta queue structure, which must be used to
1876 * actually queue the route nodes to process. So create the MQ
1877 * holder, if necessary, then push the work into it in any case.
e96f9203
DO
1878 * This semantics was introduced after 0.99.9 release.
1879 */
e96f9203
DO
1880 if (!zebra->ribq->items->count)
1881 work_queue_add (zebra->ribq, zebra->mq);
1882
1883 rib_meta_queue_add (zebra->mq, rn);
fc328ac9
SV
1884
1885 if (IS_ZEBRA_DEBUG_RIB_Q)
1886 zlog_debug ("%s: %s/%d: rn %p queued", __func__, buf, rn->p.prefixlen, rn);
1887
1888 return;
4d38fdb4 1889}
1890
5110a0c6
SH
1891/* Create new meta queue.
1892 A destructor function doesn't seem to be necessary here.
1893 */
ef9b113e
SH
1894static struct meta_queue *
1895meta_queue_new (void)
e96f9203
DO
1896{
1897 struct meta_queue *new;
5110a0c6
SH
1898 unsigned i;
1899
1900 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1901 assert(new);
e96f9203 1902
e96f9203 1903 for (i = 0; i < MQ_SIZE; i++)
5110a0c6
SH
1904 {
1905 new->subq[i] = list_new ();
1906 assert(new->subq[i]);
1907 }
1908
e96f9203
DO
1909 return new;
1910}
1911
4d38fdb4 1912/* initialise zebra rib work queue */
a1ac18c4 1913static void
4d38fdb4 1914rib_queue_init (struct zebra_t *zebra)
1915{
fc328ac9
SV
1916 assert (zebra);
1917
4d38fdb4 1918 if (! (zebra->ribq = work_queue_new (zebra->master,
6d691129 1919 "route_node processing")))
4d38fdb4 1920 {
6d691129 1921 zlog_err ("%s: could not initialise work queue!", __func__);
4d38fdb4 1922 return;
1923 }
1924
1925 /* fill in the work queue spec */
e96f9203 1926 zebra->ribq->spec.workfunc = &meta_queue_process;
4d38fdb4 1927 zebra->ribq->spec.errorfunc = NULL;
fb018d25 1928 zebra->ribq->spec.completion_func = &meta_queue_process_complete;
4d38fdb4 1929 /* XXX: TODO: These should be runtime configurable via vty */
1930 zebra->ribq->spec.max_retries = 3;
457eb9af 1931 zebra->ribq->spec.hold = rib_process_hold_time;
4d38fdb4 1932
e96f9203 1933 if (!(zebra->mq = meta_queue_new ()))
fc328ac9 1934 {
e96f9203 1935 zlog_err ("%s: could not initialise meta queue!", __func__);
fc328ac9
SV
1936 return;
1937 }
1938 return;
718e3744 1939}
1940
6d691129
PJ
1941/* RIB updates are processed via a queue of pointers to route_nodes.
1942 *
1943 * The queue length is bounded by the maximal size of the routing table,
1944 * as a route_node will not be requeued, if already queued.
1945 *
3c0755dc
PJ
1946 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1947 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1948 * and then submit route_node to queue for best-path selection later.
1949 * Order of add/delete state changes are preserved for any given RIB.
6d691129
PJ
1950 *
1951 * Deleted RIBs are reaped during best-path selection.
1952 *
1953 * rib_addnode
1954 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
3c0755dc
PJ
1955 * |-------->| | best RIB, if required
1956 * | |
1957 * static_install->|->rib_addqueue...... -> rib_process
1958 * | |
1959 * |-------->| |-> rib_unlink
6d691129
PJ
1960 * |-> set RIB_ENTRY_REMOVE |
1961 * rib_delnode (RIB freed)
1962 *
9fd92e3c
AS
1963 * The 'info' pointer of a route_node points to a rib_dest_t
1964 * ('dest'). Queueing state for a route_node is kept on the dest. The
1965 * dest is created on-demand by rib_link() and is kept around at least
1966 * as long as there are ribs hanging off it (@see rib_gc_dest()).
6d691129
PJ
1967 *
1968 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1969 *
1970 * - route_nodes: refcounted by:
9fd92e3c
AS
1971 * - dest attached to route_node:
1972 * - managed by: rib_link/rib_gc_dest
6d691129
PJ
1973 * - route_node processing queue
1974 * - managed by: rib_addqueue, rib_process.
1975 *
1976 */
1977
718e3744 1978/* Add RIB to head of the route node. */
a1ac18c4 1979static void
6d691129 1980rib_link (struct route_node *rn, struct rib *rib)
718e3744 1981{
1982 struct rib *head;
9fd92e3c 1983 rib_dest_t *dest;
f304cb48 1984 char buf[INET6_ADDRSTRLEN];
7a4bb9c5 1985 afi_t afi;
9fd92e3c 1986
4d38fdb4 1987 assert (rib && rn);
1988
6d691129 1989 if (IS_ZEBRA_DEBUG_RIB)
93bdadae 1990 {
f304cb48 1991 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
93bdadae
PJ
1992 zlog_debug ("%s: %s/%d: rn %p, rib %p", __func__,
1993 buf, rn->p.prefixlen, rn, rib);
1994 }
6d691129 1995
9fd92e3c
AS
1996 dest = rib_dest_from_rnode (rn);
1997 if (!dest)
6d691129
PJ
1998 {
1999 if (IS_ZEBRA_DEBUG_RIB)
9fd92e3c
AS
2000 {
2001 zlog_debug ("%s: %s/%d: adding dest to table", __func__,
2002 buf, rn->p.prefixlen);
2003 }
2004
2005 dest = XCALLOC (MTYPE_RIB_DEST, sizeof (rib_dest_t));
2006 route_lock_node (rn); /* rn route table reference */
2007 rn->info = dest;
2008 dest->rnode = rn;
2009 }
2010
2011 head = dest->routes;
2012 if (head)
2013 {
6d691129 2014 head->prev = rib;
6d691129 2015 }
718e3744 2016 rib->next = head;
9fd92e3c 2017 dest->routes = rib;
7a4bb9c5
DS
2018
2019 /* Further processing only if entry is in main table */
2020 if ((rib->table == RT_TABLE_MAIN) || (rib->table == zebrad.rtm_table_default))
2021 rib_queue_add (&zebrad, rn);
2022 else
2023 {
2024 if (IS_ZEBRA_DEBUG_RIB)
2025 {
2026 zlog_debug ("%s: %s/%d: Skipping further RIB processing of non-main table",
2027 __func__, buf, rn->p.prefixlen);
2028 }
2029 afi = (rn->p.family == AF_INET) ? AFI_IP :
2030 (rn->p.family == AF_INET6) ? AFI_IP6 : AFI_MAX;
2031 if (is_zebra_import_table_enabled (afi, rib->table))
2032 zebra_add_import_table_entry(rn, rib);
2033 }
718e3744 2034}
2035
a1ac18c4 2036static void
6d691129 2037rib_addnode (struct route_node *rn, struct rib *rib)
718e3744 2038{
6d691129
PJ
2039 /* RIB node has been un-removed before route-node is processed.
2040 * route_node must hence already be on the queue for processing..
2041 */
2042 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2043 {
2044 if (IS_ZEBRA_DEBUG_RIB)
93bdadae 2045 {
f304cb48
DO
2046 char buf[INET6_ADDRSTRLEN];
2047 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
93bdadae
PJ
2048 zlog_debug ("%s: %s/%d: rn %p, un-removed rib %p",
2049 __func__, buf, rn->p.prefixlen, rn, rib);
2050 }
6d691129
PJ
2051 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
2052 return;
2053 }
2054 rib_link (rn, rib);
2055}
2056
9fd92e3c
AS
2057/*
2058 * rib_unlink
2059 *
2060 * Detach a rib structure from a route_node.
2061 *
2062 * Note that a call to rib_unlink() should be followed by a call to
2063 * rib_gc_dest() at some point. This allows a rib_dest_t that is no
2064 * longer required to be deleted.
2065 */
6d691129
PJ
2066static void
2067rib_unlink (struct route_node *rn, struct rib *rib)
2068{
f304cb48 2069 char buf[INET6_ADDRSTRLEN];
9fd92e3c 2070 rib_dest_t *dest;
6d691129 2071
4d38fdb4 2072 assert (rn && rib);
6d691129
PJ
2073
2074 if (IS_ZEBRA_DEBUG_RIB)
93bdadae 2075 {
f304cb48 2076 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
93bdadae
PJ
2077 zlog_debug ("%s: %s/%d: rn %p, rib %p",
2078 __func__, buf, rn->p.prefixlen, rn, rib);
2079 }
6d691129 2080
9fd92e3c
AS
2081 dest = rib_dest_from_rnode (rn);
2082
718e3744 2083 if (rib->next)
2084 rib->next->prev = rib->prev;
6d691129 2085
718e3744 2086 if (rib->prev)
2087 rib->prev->next = rib->next;
2088 else
6d691129 2089 {
9fd92e3c 2090 dest->routes = rib->next;
6d691129
PJ
2091 }
2092
2093 /* free RIB and nexthops */
6e26278c 2094 nexthops_free(rib->nexthop, rn);
6d691129
PJ
2095 XFREE (MTYPE_RIB, rib);
2096
6d691129
PJ
2097}
2098
2099static void
2100rib_delnode (struct route_node *rn, struct rib *rib)
2101{
7a4bb9c5
DS
2102 afi_t afi;
2103
6d691129 2104 if (IS_ZEBRA_DEBUG_RIB)
93bdadae 2105 {
f304cb48
DO
2106 char buf[INET6_ADDRSTRLEN];
2107 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
93bdadae
PJ
2108 zlog_debug ("%s: %s/%d: rn %p, rib %p, removing", __func__,
2109 buf, rn->p.prefixlen, rn, rib);
2110 }
6d691129 2111 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
7a4bb9c5
DS
2112
2113 if ((rib->table == RT_TABLE_MAIN) || (rib->table == zebrad.rtm_table_default))
2114 rib_queue_add (&zebrad, rn);
2115 else
2116 {
2117 afi = (rn->p.family == AF_INET) ? AFI_IP :
2118 (rn->p.family == AF_INET6) ? AFI_IP6 : AFI_MAX;
2119 if (is_zebra_import_table_enabled (afi, rib->table))
2120 zebra_del_import_table_entry(rn, rib);
2121 /* Just clean up if non main table */
2122 rib_unlink(rn, rib);
2123 }
718e3744 2124}
2125
2126int
7c8ff89e 2127rib_add_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
7514fb77 2128 struct in_addr *gate, struct in_addr *src,
7a4bb9c5 2129 unsigned int ifindex, u_int32_t table_id,
cddf391b 2130 u_int32_t metric, u_char distance, safi_t safi)
718e3744 2131{
2132 struct rib *rib;
2133 struct rib *same = NULL;
2134 struct route_table *table;
2135 struct route_node *rn;
2136 struct nexthop *nexthop;
2137
2138 /* Lookup table. */
7a4bb9c5
DS
2139 if ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default))
2140 {
2141 table = vrf_table (AFI_IP, safi, 0);
2142 }
2143 else
2144 {
2145 table = vrf_other_route_table (AFI_IP, table_id, 0);
2146 }
718e3744 2147 if (! table)
2148 return 0;
2149
2150 /* Make it sure prefixlen is applied to the prefix. */
2151 apply_mask_ipv4 (p);
2152
2153 /* Set default distance by route type. */
2154 if (distance == 0)
2155 {
837d16cc 2156 if ((unsigned)type >= array_size(route_info))
7052f228
DL
2157 distance = 150;
2158 else
2159 distance = route_info[type].distance;
718e3744 2160
2161 /* iBGP distance is 200. */
2162 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2163 distance = 200;
2164 }
2165
2166 /* Lookup route node.*/
2167 rn = route_node_get (table, (struct prefix *) p);
2168
2169 /* If same type of route are installed, treat it as a implicit
2170 withdraw. */
9fd92e3c 2171 RNODE_FOREACH_RIB (rn, rib)
718e3744 2172 {
6d691129
PJ
2173 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2174 continue;
2175
ebf1ead0 2176 if (rib->type != type)
2177 continue;
7c8ff89e
DS
2178 if (rib->instance != instance)
2179 continue;
7a4bb9c5 2180
ebf1ead0 2181 if (rib->type != ZEBRA_ROUTE_CONNECT)
4d38fdb4 2182 {
2183 same = rib;
2184 break;
2185 }
ebf1ead0 2186 /* Duplicate connected route comes in. */
2187 else if ((nexthop = rib->nexthop) &&
2188 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
6d691129
PJ
2189 nexthop->ifindex == ifindex &&
2190 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
ebf1ead0 2191 {
2192 rib->refcnt++;
2193 return 0 ;
2194 }
718e3744 2195 }
2196
2197 /* Allocate new rib structure. */
4d38fdb4 2198 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
718e3744 2199 rib->type = type;
7c8ff89e 2200 rib->instance = instance;
718e3744 2201 rib->distance = distance;
2202 rib->flags = flags;
2203 rib->metric = metric;
7a4bb9c5 2204 rib->table = table_id;
718e3744 2205 rib->nexthop_num = 0;
2206 rib->uptime = time (NULL);
2207
2208 /* Nexthop settings. */
2209 if (gate)
2210 {
2211 if (ifindex)
7514fb77 2212 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
718e3744 2213 else
7514fb77 2214 nexthop_ipv4_add (rib, gate, src);
718e3744 2215 }
2216 else
2217 nexthop_ifindex_add (rib, ifindex);
2218
2219 /* If this route is kernel route, set FIB flag to the route. */
2220 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2221 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2222 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2223
2224 /* Link new rib to node.*/
dc95824a 2225 if (IS_ZEBRA_DEBUG_RIB)
7a4bb9c5
DS
2226 {
2227 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
2228 __func__, rn, rib);
2229 rib_dump ((struct prefix *)p, rib);
2230 }
718e3744 2231 rib_addnode (rn, rib);
4d38fdb4 2232
718e3744 2233 /* Free implicit route.*/
2234 if (same)
dc95824a
DO
2235 {
2236 if (IS_ZEBRA_DEBUG_RIB)
2237 zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
4d38fdb4 2238 rib_delnode (rn, same);
dc95824a 2239 }
4d38fdb4 2240
2241 route_unlock_node (rn);
718e3744 2242 return 0;
2243}
2244
dc95824a
DO
2245/* This function dumps the contents of a given RIB entry into
2246 * standard debug log. Calling function name and IP prefix in
2247 * question are passed as 1st and 2nd arguments.
2248 */
2249
f7bf4153
DL
2250void _rib_dump (const char * func,
2251 union prefix46constptr pp, const struct rib * rib)
dc95824a 2252{
f7bf4153 2253 const struct prefix *p = pp.p;
fed643f4 2254 char straddr[INET6_ADDRSTRLEN];
fa713d9e
CF
2255 struct nexthop *nexthop, *tnexthop;
2256 int recursing;
dc95824a 2257
fed643f4 2258 inet_ntop (p->family, &p->u.prefix, straddr, INET6_ADDRSTRLEN);
fa713d9e 2259 zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr, p->prefixlen);
dc95824a
DO
2260 zlog_debug
2261 (
7c8ff89e 2262 "%s: refcnt == %lu, uptime == %lu, type == %u, instance == %d, table == %d",
dc95824a
DO
2263 func,
2264 rib->refcnt,
d02c56cd 2265 (unsigned long) rib->uptime,
dc95824a 2266 rib->type,
7c8ff89e 2267 rib->instance,
dc95824a
DO
2268 rib->table
2269 );
2270 zlog_debug
2271 (
2272 "%s: metric == %u, distance == %u, flags == %u, status == %u",
2273 func,
2274 rib->metric,
2275 rib->distance,
2276 rib->flags,
2277 rib->status
2278 );
2279 zlog_debug
2280 (
2281 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
2282 func,
2283 rib->nexthop_num,
2284 rib->nexthop_active_num,
2285 rib->nexthop_fib_num
2286 );
fed643f4 2287
fa713d9e
CF
2288 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2289 {
fed643f4 2290 inet_ntop (p->family, &nexthop->gate, straddr, INET6_ADDRSTRLEN);
fa713d9e
CF
2291 zlog_debug
2292 (
2293 "%s: %s %s with flags %s%s%s",
2294 func,
2295 (recursing ? " NH" : "NH"),
2296 straddr,
2297 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
2298 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
2299 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
2300 );
2301 }
dc95824a
DO
2302 zlog_debug ("%s: dump complete", func);
2303}
2304
2305/* This is an exported helper to rtm_read() to dump the strange
2306 * RIB entry found by rib_lookup_ipv4_route()
2307 */
2308
2309void rib_lookup_and_dump (struct prefix_ipv4 * p)
2310{
2311 struct route_table *table;
2312 struct route_node *rn;
2313 struct rib *rib;
2314 char prefix_buf[INET_ADDRSTRLEN];
2315
2316 /* Lookup table. */
2317 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2318 if (! table)
2319 {
2320 zlog_err ("%s: vrf_table() returned NULL", __func__);
2321 return;
2322 }
2323
2324 inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
2325 /* Scan the RIB table for exactly matching RIB entry. */
2326 rn = route_node_lookup (table, (struct prefix *) p);
2327
2328 /* No route for this prefix. */
2329 if (! rn)
2330 {
2331 zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
2332 return;
2333 }
2334
2335 /* Unlock node. */
2336 route_unlock_node (rn);
2337
2338 /* let's go */
9fd92e3c 2339 RNODE_FOREACH_RIB (rn, rib)
dc95824a
DO
2340 {
2341 zlog_debug
2342 (
2343 "%s: rn %p, rib %p: %s, %s",
2344 __func__,
2345 rn,
2346 rib,
2347 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
2348 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
2349 );
f7bf4153 2350 rib_dump (p, rib);
dc95824a
DO
2351 }
2352}
2353
20e5ff0a
DO
2354/* Check if requested address assignment will fail due to another
2355 * route being installed by zebra in FIB already. Take necessary
2356 * actions, if needed: remove such a route from FIB and deSELECT
2357 * corresponding RIB entry. Then put affected RN into RIBQ head.
2358 */
2359void rib_lookup_and_pushup (struct prefix_ipv4 * p)
2360{
2361 struct route_table *table;
2362 struct route_node *rn;
2363 struct rib *rib;
2364 unsigned changed = 0;
2365
2366 if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
2367 {
2368 zlog_err ("%s: vrf_table() returned NULL", __func__);
2369 return;
2370 }
2371
2372 /* No matches would be the simplest case. */
2373 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
2374 return;
2375
2376 /* Unlock node. */
2377 route_unlock_node (rn);
2378
2379 /* Check all RIB entries. In case any changes have to be done, requeue
2380 * the RN into RIBQ head. If the routing message about the new connected
2381 * route (generated by the IP address we are going to assign very soon)
2382 * comes before the RIBQ is processed, the new RIB entry will join
2383 * RIBQ record already on head. This is necessary for proper revalidation
2384 * of the rest of the RIB.
2385 */
9fd92e3c 2386 RNODE_FOREACH_RIB (rn, rib)
20e5ff0a
DO
2387 {
2388 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
2389 ! RIB_SYSTEM_ROUTE (rib))
2390 {
2391 changed = 1;
2392 if (IS_ZEBRA_DEBUG_RIB)
2393 {
2394 char buf[INET_ADDRSTRLEN];
2395 inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
2396 zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
f7bf4153 2397 rib_dump (&rn->p, rib);
20e5ff0a
DO
2398 }
2399 rib_uninstall (rn, rib);
2400 }
2401 }
2402 if (changed)
20e5ff0a 2403 rib_queue_add (&zebrad, rn);
20e5ff0a
DO
2404}
2405
718e3744 2406int
cddf391b 2407rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
718e3744 2408{
2409 struct route_table *table;
2410 struct route_node *rn;
2411 struct rib *same;
2412 struct nexthop *nexthop;
04b02fda 2413 int ret = 0;
4d38fdb4 2414
718e3744 2415 /* Lookup table. */
7a4bb9c5
DS
2416 if ((rib->table == zebrad.rtm_table_default) || (rib->table == RT_TABLE_MAIN))
2417 {
2418 table = vrf_table (AFI_IP, safi, 0);
2419 }
2420 else
2421 {
2422 table = vrf_other_route_table (AFI_IP, rib->table, 0);
2423 }
718e3744 2424 if (! table)
2425 return 0;
cddf391b 2426
718e3744 2427 /* Make it sure prefixlen is applied to the prefix. */
2428 apply_mask_ipv4 (p);
2429
2430 /* Set default distance by route type. */
2431 if (rib->distance == 0)
2432 {
2433 rib->distance = route_info[rib->type].distance;
2434
2435 /* iBGP distance is 200. */
2436 if (rib->type == ZEBRA_ROUTE_BGP
2437 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
2438 rib->distance = 200;
2439 }
2440
2441 /* Lookup route node.*/
2442 rn = route_node_get (table, (struct prefix *) p);
2443
2444 /* If same type of route are installed, treat it as a implicit
2445 withdraw. */
9fd92e3c 2446 RNODE_FOREACH_RIB (rn, same)
718e3744 2447 {
0b8c4f1d 2448 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
6d691129
PJ
2449 continue;
2450
7c8ff89e
DS
2451 if (same->type == rib->type && same->instance == rib->instance
2452 && same->table == rib->table
718e3744 2453 && same->type != ZEBRA_ROUTE_CONNECT)
4d38fdb4 2454 break;
718e3744 2455 }
4d38fdb4 2456
718e3744 2457 /* If this route is kernel route, set FIB flag to the route. */
2458 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
2459 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2460 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2461
2462 /* Link new rib to node.*/
2463 rib_addnode (rn, rib);
04b02fda 2464 ret = 1;
dc95824a
DO
2465 if (IS_ZEBRA_DEBUG_RIB)
2466 {
2467 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
2468 __func__, rn, rib);
f7bf4153 2469 rib_dump (p, rib);
dc95824a 2470 }
718e3744 2471
718e3744 2472 /* Free implicit route.*/
2473 if (same)
dc95824a
DO
2474 {
2475 if (IS_ZEBRA_DEBUG_RIB)
2476 {
2477 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
2478 __func__, rn, same);
f7bf4153 2479 rib_dump (p, same);
dc95824a 2480 }
4d38fdb4 2481 rib_delnode (rn, same);
04b02fda 2482 ret = -1;
dc95824a 2483 }
4d38fdb4 2484
2485 route_unlock_node (rn);
04b02fda 2486 return ret;
718e3744 2487}
2488
ebf1ead0 2489/* XXX factor with rib_delete_ipv6 */
718e3744 2490int
7c8ff89e 2491rib_delete_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
7a4bb9c5
DS
2492 struct in_addr *gate, unsigned int ifindex,
2493 u_int32_t table_id, safi_t safi)
718e3744 2494{
2495 struct route_table *table;
2496 struct route_node *rn;
2497 struct rib *rib;
2498 struct rib *fib = NULL;
2499 struct rib *same = NULL;
fa713d9e
CF
2500 struct nexthop *nexthop, *tnexthop;
2501 int recursing;
81cce018
SH
2502 char buf1[INET_ADDRSTRLEN];
2503 char buf2[INET_ADDRSTRLEN];
718e3744 2504
2505 /* Lookup table. */
7a4bb9c5
DS
2506 if ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default))
2507 {
2508 table = vrf_table (AFI_IP, safi, 0);
2509 }
2510 else
2511 {
2512 table = vrf_other_route_table(AFI_IP, table_id, 0);
2513 }
718e3744 2514 if (! table)
2515 return 0;
2516
2517 /* Apply mask. */
2518 apply_mask_ipv4 (p);
2519
b52aef18
CF
2520 if (IS_ZEBRA_DEBUG_KERNEL)
2521 {
2522 if (gate)
2523 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
2524 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
2525 p->prefixlen,
2526 inet_ntoa (*gate),
2527 ifindex);
2528 else
2529 zlog_debug ("rib_delete_ipv4(): route delete %s/%d ifindex %d",
2530 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
2531 p->prefixlen,
2532 ifindex);
2533 }
5ec90d28 2534
718e3744 2535 /* Lookup route node. */
2536 rn = route_node_lookup (table, (struct prefix *) p);
2537 if (! rn)
2538 {
2539 if (IS_ZEBRA_DEBUG_KERNEL)
2540 {
2541 if (gate)
b6178002 2542 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
81cce018 2543 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
718e3744 2544 p->prefixlen,
81cce018 2545 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
718e3744 2546 ifindex);
2547 else
b6178002 2548 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
81cce018 2549 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
718e3744 2550 p->prefixlen,
2551 ifindex);
2552 }
2553 return ZEBRA_ERR_RTNOEXIST;
2554 }
2555
2556 /* Lookup same type route. */
9fd92e3c 2557 RNODE_FOREACH_RIB (rn, rib)
718e3744 2558 {
6d691129
PJ
2559 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2560 continue;
2561
718e3744 2562 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2563 fib = rib;
2564
ebf1ead0 2565 if (rib->type != type)
2566 continue;
7c8ff89e
DS
2567 if (rib->instance != instance)
2568 continue;
ebf1ead0 2569 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
4f1735fd 2570 nexthop->type == NEXTHOP_TYPE_IFINDEX)
718e3744 2571 {
4f1735fd
MF
2572 if (nexthop->ifindex != ifindex)
2573 continue;
ebf1ead0 2574 if (rib->refcnt)
718e3744 2575 {
ebf1ead0 2576 rib->refcnt--;
2577 route_unlock_node (rn);
2578 route_unlock_node (rn);
2579 return 0;
718e3744 2580 }
ebf1ead0 2581 same = rib;
2582 break;
718e3744 2583 }
ebf1ead0 2584 /* Make sure that the route found has the same gateway. */
fa713d9e 2585 else
5ec90d28 2586 {
fa713d9e
CF
2587 if (gate == NULL)
2588 {
2589 same = rib;
2590 break;
2591 }
2592 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2593 if (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate))
2594 {
2595 same = rib;
2596 break;
2597 }
2598 if (same)
2599 break;
2600 }
718e3744 2601 }
718e3744 2602 /* If same type of route can't be found and this message is from
2603 kernel. */
2604 if (! same)
2605 {
2037f143
DS
2606 if (fib && type == ZEBRA_ROUTE_KERNEL &&
2607 CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE))
2608 {
2609 if (IS_ZEBRA_DEBUG_KERNEL)
2610 {
2611 zlog_debug ("Zebra route %s/%d was deleted by others from kernel",
2612 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
2613 p->prefixlen);
2614 }
2615 /* This means someone else, other than Zebra, has deleted
2616 * a Zebra router from the kernel. We will add it back */
2617 rib_install_kernel(rn, fib);
2618 }
718e3744 2619 else
2620 {
2621 if (IS_ZEBRA_DEBUG_KERNEL)
2622 {
2623 if (gate)
b6178002 2624 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
81cce018 2625 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
718e3744 2626 p->prefixlen,
81cce018 2627 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
718e3744 2628 ifindex,
2629 type);
2630 else
b6178002 2631 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
81cce018 2632 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
718e3744 2633 p->prefixlen,
2634 ifindex,
2635 type);
2636 }
2637 route_unlock_node (rn);
2638 return ZEBRA_ERR_RTNOEXIST;
2639 }
2640 }
4d38fdb4 2641
718e3744 2642 if (same)
4d38fdb4 2643 rib_delnode (rn, same);
2644
718e3744 2645 route_unlock_node (rn);
718e3744 2646 return 0;
2647}
6b0655a2 2648
718e3744 2649/* Install static route into rib. */
a1ac18c4 2650static void
718e3744 2651static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
2652{
2653 struct rib *rib;
2654 struct route_node *rn;
2655 struct route_table *table;
6e26278c 2656 struct prefix nh_p;
718e3744 2657
2658 /* Lookup table. */
2659 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2660 if (! table)
2661 return;
2662
2663 /* Lookup existing route */
2664 rn = route_node_get (table, p);
9fd92e3c 2665 RNODE_FOREACH_RIB (rn, rib)
6d691129
PJ
2666 {
2667 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2668 continue;
2669
2670 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2671 break;
2672 }
718e3744 2673
2674 if (rib)
2675 {
0d9551dc
DS
2676 /* if tag value changed , update old value in RIB */
2677 if (rib->tag != si->tag)
2678 rib->tag = si->tag;
2679
718e3744 2680 /* Same distance static route is there. Update it with new
2681 nexthop. */
718e3744 2682 route_unlock_node (rn);
718e3744 2683 switch (si->type)
7021c425 2684 {
2685 case STATIC_IPV4_GATEWAY:
7514fb77 2686 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
6e26278c
DS
2687 nh_p.family = AF_INET;
2688 nh_p.prefixlen = IPV4_MAX_BITLEN;
2689 nh_p.u.prefix4 = si->gate.ipv4;
2690 zebra_register_rnh_static_nh(&nh_p, rn);
7021c425 2691 break;
2692 case STATIC_IPV4_IFNAME:
2693 nexthop_ifname_add (rib, si->gate.ifname);
2694 break;
2695 case STATIC_IPV4_BLACKHOLE:
2696 nexthop_blackhole_add (rib);
2697 break;
4d38fdb4 2698 }
3c0755dc 2699 rib_queue_add (&zebrad, rn);
718e3744 2700 }
2701 else
2702 {
2703 /* This is new static route. */
4d38fdb4 2704 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2705
718e3744 2706 rib->type = ZEBRA_ROUTE_STATIC;
7c8ff89e 2707 rib->instance = 0;
718e3744 2708 rib->distance = si->distance;
2709 rib->metric = 0;
b0145ddb 2710 rib->table = zebrad.rtm_table_default;
718e3744 2711 rib->nexthop_num = 0;
0d9551dc 2712 rib->tag = si->tag;
718e3744 2713
2714 switch (si->type)
7021c425 2715 {
2716 case STATIC_IPV4_GATEWAY:
7514fb77 2717 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
6e26278c
DS
2718 nh_p.family = AF_INET;
2719 nh_p.prefixlen = IPV4_MAX_BITLEN;
2720 nh_p.u.prefix4 = si->gate.ipv4;
2721 zebra_register_rnh_static_nh(&nh_p, rn);
7021c425 2722 break;
2723 case STATIC_IPV4_IFNAME:
2724 nexthop_ifname_add (rib, si->gate.ifname);
2725 break;
2726 case STATIC_IPV4_BLACKHOLE:
2727 nexthop_blackhole_add (rib);
2728 break;
2729 }
718e3744 2730
81dfcaa2 2731 /* Save the flags of this static routes (reject, blackhole) */
2732 rib->flags = si->flags;
2733
718e3744 2734 /* Link this rib to the tree. */
2735 rib_addnode (rn, rib);
718e3744 2736 }
2737}
2738
a1ac18c4 2739static int
718e3744 2740static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2741{
2742 if (nexthop->type == NEXTHOP_TYPE_IPV4
2743 && si->type == STATIC_IPV4_GATEWAY
2744 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2745 return 1;
2746 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2747 && si->type == STATIC_IPV4_IFNAME
2748 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2749 return 1;
595db7f1 2750 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2751 && si->type == STATIC_IPV4_BLACKHOLE)
2752 return 1;
e8e1946e 2753 return 0;
718e3744 2754}
2755
2756/* Uninstall static route from RIB. */
a1ac18c4 2757static void
718e3744 2758static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
2759{
2760 struct route_node *rn;
2761 struct rib *rib;
2762 struct nexthop *nexthop;
2763 struct route_table *table;
6e26278c 2764 struct prefix nh_p;
718e3744 2765
2766 /* Lookup table. */
2767 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2768 if (! table)
2769 return;
4d38fdb4 2770
718e3744 2771 /* Lookup existing route with type and distance. */
2772 rn = route_node_lookup (table, p);
2773 if (! rn)
2774 return;
2775
9fd92e3c 2776 RNODE_FOREACH_RIB (rn, rib)
6d691129
PJ
2777 {
2778 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2779 continue;
2780
0d9551dc
DS
2781 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance &&
2782 rib->tag == si->tag)
6d691129
PJ
2783 break;
2784 }
718e3744 2785
2786 if (! rib)
2787 {
2788 route_unlock_node (rn);
2789 return;
2790 }
2791
2792 /* Lookup nexthop. */
2793 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2794 if (static_ipv4_nexthop_same (nexthop, si))
2795 break;
2796
2797 /* Can't find nexthop. */
2798 if (! nexthop)
2799 {
2800 route_unlock_node (rn);
2801 return;
2802 }
2803
2804 /* Check nexthop. */
2805 if (rib->nexthop_num == 1)
6d691129 2806 rib_delnode (rn, rib);
718e3744 2807 else
2808 {
6baeb988 2809 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2810 rib_uninstall (rn, rib);
6e26278c
DS
2811
2812 nh_p.family = AF_INET;
2813 nh_p.prefixlen = IPV4_MAX_BITLEN;
2814 nh_p.u.prefix4 = nexthop->gate.ipv4;
319572cc 2815 nexthop_delete (rib, nexthop);
6e26278c
DS
2816 zebra_deregister_rnh_static_nh(&nh_p, rn);
2817 nexthop_free (nexthop, rn);
6d691129 2818 rib_queue_add (&zebrad, rn);
718e3744 2819 }
718e3744 2820 /* Unlock node. */
2821 route_unlock_node (rn);
2822}
2823
2824/* Add static route into static route configuration. */
2825int
39db97e4 2826static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
0d9551dc 2827 u_char flags, u_short tag, u_char distance, u_int32_t vrf_id)
718e3744 2828{
2829 u_char type = 0;
2830 struct route_node *rn;
2831 struct static_ipv4 *si;
2832 struct static_ipv4 *pp;
2833 struct static_ipv4 *cp;
2834 struct static_ipv4 *update = NULL;
2835 struct route_table *stable;
2836
2837 /* Lookup table. */
2838 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2839 if (! stable)
2840 return -1;
2841
2842 /* Lookup static route prefix. */
2843 rn = route_node_get (stable, p);
2844
2845 /* Make flags. */
2846 if (gate)
2847 type = STATIC_IPV4_GATEWAY;
368aa3f0 2848 else if (ifname)
718e3744 2849 type = STATIC_IPV4_IFNAME;
595db7f1 2850 else
2851 type = STATIC_IPV4_BLACKHOLE;
718e3744 2852
2853 /* Do nothing if there is a same static route. */
2854 for (si = rn->info; si; si = si->next)
2855 {
2856 if (type == si->type
2857 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2858 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2859 {
0d9551dc 2860 if ((distance == si->distance) && (tag == si->tag))
718e3744 2861 {
2862 route_unlock_node (rn);
2863 return 0;
2864 }
2865 else
2866 update = si;
2867 }
2868 }
2869
0d9551dc 2870 /* Distance or tag changed. */
718e3744 2871 if (update)
0d9551dc 2872 static_delete_ipv4 (p, gate, ifname, update->tag, update->distance, vrf_id);
718e3744 2873
2874 /* Make new static route structure. */
393deb9b 2875 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
718e3744 2876
2877 si->type = type;
2878 si->distance = distance;
81dfcaa2 2879 si->flags = flags;
0d9551dc 2880 si->tag = tag;
718e3744 2881
2882 if (gate)
2883 si->gate.ipv4 = *gate;
2884 if (ifname)
2885 si->gate.ifname = XSTRDUP (0, ifname);
2886
2887 /* Add new static route information to the tree with sort by
2888 distance value and gateway address. */
2889 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2890 {
2891 if (si->distance < cp->distance)
2892 break;
2893 if (si->distance > cp->distance)
2894 continue;
2895 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2896 {
2897 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2898 break;
2899 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2900 continue;
2901 }
2902 }
2903
2904 /* Make linked list. */
2905 if (pp)
2906 pp->next = si;
2907 else
2908 rn->info = si;
2909 if (cp)
2910 cp->prev = si;
2911 si->prev = pp;
2912 si->next = cp;
2913
2914 /* Install into rib. */
2915 static_install_ipv4 (p, si);
2916
2917 return 1;
2918}
2919
2920/* Delete static route from static route configuration. */
2921int
39db97e4 2922static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
0d9551dc 2923 u_short tag, u_char distance, u_int32_t vrf_id)
718e3744 2924{
2925 u_char type = 0;
2926 struct route_node *rn;
2927 struct static_ipv4 *si;
2928 struct route_table *stable;
2929
2930 /* Lookup table. */
2931 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2932 if (! stable)
2933 return -1;
2934
2935 /* Lookup static route prefix. */
2936 rn = route_node_lookup (stable, p);
2937 if (! rn)
2938 return 0;
2939
2940 /* Make flags. */
2941 if (gate)
2942 type = STATIC_IPV4_GATEWAY;
2943 else if (ifname)
2944 type = STATIC_IPV4_IFNAME;
595db7f1 2945 else
2946 type = STATIC_IPV4_BLACKHOLE;
718e3744 2947
2948 /* Find same static route is the tree */
2949 for (si = rn->info; si; si = si->next)
2950 if (type == si->type
2951 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
0d9551dc
DS
2952 && (! ifname || strcmp (ifname, si->gate.ifname) == 0)
2953 && (! tag || (tag == si->tag)))
718e3744 2954 break;
2955
2956 /* Can't find static route. */
2957 if (! si)
2958 {
2959 route_unlock_node (rn);
2960 return 0;
2961 }
2962
2963 /* Install into rib. */
2964 static_uninstall_ipv4 (p, si);
2965
2966 /* Unlink static route from linked list. */
2967 if (si->prev)
2968 si->prev->next = si->next;
2969 else
2970 rn->info = si->next;
2971 if (si->next)
2972 si->next->prev = si->prev;
143a385f 2973 route_unlock_node (rn);
718e3744 2974
2975 /* Free static route configuration. */
a0f6acd8 2976 if (ifname)
2977 XFREE (0, si->gate.ifname);
718e3744 2978 XFREE (MTYPE_STATIC_IPV4, si);
2979
143a385f 2980 route_unlock_node (rn);
2981
718e3744 2982 return 1;
2983}
2984
6b0655a2 2985
718e3744 2986#ifdef HAVE_IPV6
41fc2714 2987int
718e3744 2988rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2989 struct in6_addr *gate, unsigned int ifindex, int table)
2990{
726f9b2b 2991 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2992#if defined (MUSICA) || defined (LINUX)
2993 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2994 if (p->prefixlen == 96)
2995 return 0;
2996#endif /* MUSICA */
718e3744 2997 return 1;
726f9b2b 2998 }
718e3744 2999 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
3000 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
3001 {
3002 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
3003 return 1;
3004 }
3005 return 0;
3006}
3007
3008int
7c8ff89e 3009rib_add_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
7a4bb9c5 3010 struct in6_addr *gate, unsigned int ifindex, u_int32_t table_id,
f768f367 3011 u_int32_t metric, u_char distance, safi_t safi)
718e3744 3012{
3013 struct rib *rib;
3014 struct rib *same = NULL;
3015 struct route_table *table;
3016 struct route_node *rn;
3017 struct nexthop *nexthop;
3018
718e3744 3019 /* Lookup table. */
7a4bb9c5
DS
3020 if ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default))
3021 {
3022 table = vrf_table (AFI_IP6, safi, 0);
3023 }
3024 else
3025 {
3026 table = vrf_other_route_table(AFI_IP6, table_id, 0);
3027 }
718e3744 3028 if (! table)
3029 return 0;
3030
3031 /* Make sure mask is applied. */
3032 apply_mask_ipv6 (p);
3033
3034 /* Set default distance by route type. */
be61c4eb 3035 if (!distance)
3036 distance = route_info[type].distance;
718e3744 3037
3038 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
3039 distance = 200;
3040
3041 /* Filter bogus route. */
3042 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
3043 return 0;
3044
3045 /* Lookup route node.*/
3046 rn = route_node_get (table, (struct prefix *) p);
3047
3048 /* If same type of route are installed, treat it as a implicit
3049 withdraw. */
9fd92e3c 3050 RNODE_FOREACH_RIB (rn, rib)
718e3744 3051 {
6d691129
PJ
3052 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3053 continue;
3054
ebf1ead0 3055 if (rib->type != type)
3056 continue;
7c8ff89e
DS
3057 if (rib->instance != instance)
3058 continue;
ebf1ead0 3059 if (rib->type != ZEBRA_ROUTE_CONNECT)
718e3744 3060 {
3061 same = rib;
718e3744 3062 break;
3063 }
ebf1ead0 3064 else if ((nexthop = rib->nexthop) &&
3065 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
3066 nexthop->ifindex == ifindex)
3067 {
3068 rib->refcnt++;
3069 return 0;
3070 }
718e3744 3071 }
3072
3073 /* Allocate new rib structure. */
4d38fdb4 3074 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
3075
718e3744 3076 rib->type = type;
7c8ff89e 3077 rib->instance = instance;
718e3744 3078 rib->distance = distance;
3079 rib->flags = flags;
3080 rib->metric = metric;
7a4bb9c5 3081 rib->table = table_id;
718e3744 3082 rib->nexthop_num = 0;
3083 rib->uptime = time (NULL);
3084
3085 /* Nexthop settings. */
3086 if (gate)
3087 {
3088 if (ifindex)
3089 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
3090 else
3091 nexthop_ipv6_add (rib, gate);
3092 }
3093 else
3094 nexthop_ifindex_add (rib, ifindex);
3095
3096 /* If this route is kernel route, set FIB flag to the route. */
3097 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
3098 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
3099 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
3100
3101 /* Link new rib to node.*/
3102 rib_addnode (rn, rib);
fed643f4
VB
3103 if (IS_ZEBRA_DEBUG_RIB)
3104 {
3105 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
3106 __func__, rn, rib);
f7bf4153 3107 rib_dump (p, rib);
fed643f4 3108 }
718e3744 3109
718e3744 3110 /* Free implicit route.*/
3111 if (same)
fed643f4
VB
3112 {
3113 if (IS_ZEBRA_DEBUG_RIB)
3114 {
3115 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
3116 __func__, rn, same);
f7bf4153 3117 rib_dump (p, same);
fed643f4 3118 }
4d38fdb4 3119 rib_delnode (rn, same);
fed643f4 3120 }
4d38fdb4 3121
3122 route_unlock_node (rn);
718e3744 3123 return 0;
3124}
3125
41fc2714
DS
3126int
3127rib_add_ipv6_multipath (struct prefix_ipv6 *p, struct rib *rib, safi_t safi,
3128 unsigned long ifindex)
3129{
3130 struct route_table *table;
3131 struct route_node *rn;
3132 struct rib *same = NULL;
3133 struct nexthop *nexthop;
3134 int ret = 0;
7a4bb9c5 3135 int table_id = 0;
41fc2714 3136
7a4bb9c5
DS
3137 if (rib)
3138 table_id = rib->table;
3139 else
41fc2714
DS
3140 return 0; /* why are we getting called with NULL rib */
3141
3142 /* Lookup table. */
7a4bb9c5
DS
3143 if ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default))
3144 {
3145 table = vrf_table (AFI_IP6, safi, 0);
3146 }
3147 else
3148 {
3149 table = vrf_other_route_table(AFI_IP6, table_id, 0);
3150 }
41fc2714
DS
3151
3152 if (! table)
3153 return 0;
3154
3155 /* Make sure mask is applied. */
3156 apply_mask_ipv6 (p);
3157
3158 /* Set default distance by route type. */
3159 if (rib->distance == 0)
3160 {
3161 rib->distance = route_info[rib->type].distance;
3162
3163 /* iBGP distance is 200. */
3164 if (rib->type == ZEBRA_ROUTE_BGP
3165 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
3166 rib->distance = 200;
3167 }
3168
3169 /* Lookup route node.*/
3170 rn = route_node_get (table, (struct prefix *) p);
3171
3172 /* If same type of route are installed, treat it as a implicit
3173 withdraw. */
3174 RNODE_FOREACH_RIB (rn, same) {
3175 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED)) {
3176 continue;
3177 }
3178 if (same->type != rib->type) {
3179 continue;
3180 }
3181
7c8ff89e
DS
3182 if (same->instance != rib->instance) {
3183 continue;
3184 }
3185
41fc2714
DS
3186 if (same->table != rib->table) {
3187 continue;
3188 }
3189 if (same->type != ZEBRA_ROUTE_CONNECT) {
3190 break;
3191 }
3192 else if ((nexthop = same->nexthop) &&
3193 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
3194 nexthop->ifindex == ifindex) {
3195 same->refcnt++;
3196 return 0;
3197 }
3198 }
3199
3200 /* If this route is kernel route, set FIB flag to the route. */
3201 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT) {
3202 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) {
3203 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
3204 }
3205 }
3206
3207 /* Link new rib to node.*/
3208 rib_addnode (rn, rib);
3209 ret = 1;
3210 /* Free implicit route.*/
3211 if (same)
3212 {
3213 if (IS_ZEBRA_DEBUG_RIB)
3214 {
3215 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
3216 __func__, rn, same);
3217 rib_dump ((struct prefix *)p, same);
3218 }
3219 rib_delnode (rn, same);
3220 ret = -1;
3221 }
3222
3223 route_unlock_node (rn);
3224 return ret;
3225}
3226
ebf1ead0 3227/* XXX factor with rib_delete_ipv6 */
718e3744 3228int
7c8ff89e 3229rib_delete_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
7a4bb9c5 3230 struct in6_addr *gate, unsigned int ifindex, u_int32_t table_id, safi_t safi)
718e3744 3231{
3232 struct route_table *table;
3233 struct route_node *rn;
3234 struct rib *rib;
3235 struct rib *fib = NULL;
3236 struct rib *same = NULL;
fa713d9e
CF
3237 struct nexthop *nexthop, *tnexthop;
3238 int recursing;
81cce018
SH
3239 char buf1[INET6_ADDRSTRLEN];
3240 char buf2[INET6_ADDRSTRLEN];
718e3744 3241
3242 /* Apply mask. */
3243 apply_mask_ipv6 (p);
3244
3245 /* Lookup table. */
7a4bb9c5
DS
3246 if ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default))
3247 {
3248 table = vrf_table (AFI_IP6, safi, 0);
3249 }
3250 else
3251 {
3252 table = vrf_other_route_table(AFI_IP6, table_id, 0);
3253 }
718e3744 3254 if (! table)
3255 return 0;
4d38fdb4 3256
718e3744 3257 /* Lookup route node. */
3258 rn = route_node_lookup (table, (struct prefix *) p);
3259 if (! rn)
3260 {
3261 if (IS_ZEBRA_DEBUG_KERNEL)
3262 {
3263 if (gate)
b6178002 3264 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
81cce018 3265 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
718e3744 3266 p->prefixlen,
81cce018 3267 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
718e3744 3268 ifindex);
3269 else
b6178002 3270 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
81cce018 3271 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
718e3744 3272 p->prefixlen,
3273 ifindex);
3274 }
3275 return ZEBRA_ERR_RTNOEXIST;
3276 }
3277
3278 /* Lookup same type route. */
9fd92e3c 3279 RNODE_FOREACH_RIB (rn, rib)
718e3744 3280 {
6d691129
PJ
3281 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
3282 continue;
3283
718e3744 3284 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
3285 fib = rib;
3286
ebf1ead0 3287 if (rib->type != type)
3288 continue;
7c8ff89e
DS
3289 if (rib->instance != instance)
3290 continue;
ebf1ead0 3291 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
4f1735fd 3292 nexthop->type == NEXTHOP_TYPE_IFINDEX)
718e3744 3293 {
4f1735fd
MF
3294 if (nexthop->ifindex != ifindex)
3295 continue;
ebf1ead0 3296 if (rib->refcnt)
718e3744 3297 {
ebf1ead0 3298 rib->refcnt--;
3299 route_unlock_node (rn);
3300 route_unlock_node (rn);
3301 return 0;
718e3744 3302 }
ebf1ead0 3303 same = rib;
3304 break;
718e3744 3305 }
ebf1ead0 3306 /* Make sure that the route found has the same gateway. */
fa713d9e
CF
3307 else
3308 {
3309 if (gate == NULL)
3310 {
3311 same = rib;
3312 break;
3313 }
3314 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
3315 if (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate))
3316 {
3317 same = rib;
3318 break;
3319 }
3320 if (same)
3321 break;
3322 }
718e3744 3323 }
3324
3325 /* If same type of route can't be found and this message is from
3326 kernel. */
3327 if (! same)
3328 {
2037f143
DS
3329 if (fib && type == ZEBRA_ROUTE_KERNEL &&
3330 CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE))
3331 {
3332 if (IS_ZEBRA_DEBUG_KERNEL)
3333 {
3334 zlog_debug ("Zebra route %s/%d was deleted by others from kernel",
3335 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
3336 p->prefixlen);
3337 }
3338 /* This means someone else, other than Zebra, has deleted a Zebra
3339 * route from the kernel. We will add it back */
3340 rib_install_kernel(rn, fib);
3341 }
718e3744 3342 else
3343 {
3344 if (IS_ZEBRA_DEBUG_KERNEL)
3345 {
3346 if (gate)
b6178002 3347 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
81cce018 3348 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
718e3744 3349 p->prefixlen,
81cce018 3350 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
718e3744 3351 ifindex,
3352 type);
3353 else
b6178002 3354 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
81cce018 3355 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
718e3744 3356 p->prefixlen,
3357 ifindex,
3358 type);
3359 }
3360 route_unlock_node (rn);
3361 return ZEBRA_ERR_RTNOEXIST;
3362 }
3363 }
3364
718e3744 3365 if (same)
4d38fdb4 3366 rib_delnode (rn, same);
3367
718e3744 3368 route_unlock_node (rn);
718e3744 3369 return 0;
3370}
6b0655a2 3371
718e3744 3372/* Install static route into rib. */
a1ac18c4 3373static void
718e3744 3374static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
3375{
3376 struct rib *rib;
3377 struct route_table *table;
3378 struct route_node *rn;
6e26278c 3379 struct prefix nh_p;
718e3744 3380
3381 /* Lookup table. */
3382 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
3383 if (! table)
3384 return;
3385
3386 /* Lookup existing route */
3387 rn = route_node_get (table, p);
9fd92e3c 3388 RNODE_FOREACH_RIB (rn, rib)
6d691129
PJ
3389 {
3390 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
3391 continue;
3392
3393 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
3394 break;
3395 }
718e3744 3396
3397 if (rib)
3398 {
0d9551dc
DS
3399 /* if tag value changed , update old value in RIB */
3400 if (rib->tag != si->tag)
3401 rib->tag = si->tag;
3402
718e3744 3403 /* Same distance static route is there. Update it with new
3404 nexthop. */
718e3744 3405 route_unlock_node (rn);
3406
3407 switch (si->type)
3408 {
3409 case STATIC_IPV6_GATEWAY:
3410 nexthop_ipv6_add (rib, &si->ipv6);
6e26278c
DS
3411 nh_p.family = AF_INET6;
3412 nh_p.prefixlen = IPV6_MAX_BITLEN;
3413 nh_p.u.prefix6 = si->ipv6;
3414 zebra_register_rnh_static_nh(&nh_p, rn);
718e3744 3415 break;
3416 case STATIC_IPV6_IFNAME:
3417 nexthop_ifname_add (rib, si->ifname);
3418 break;
3419 case STATIC_IPV6_GATEWAY_IFNAME:
3420 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
3421 break;
3422 }
3c0755dc 3423 rib_queue_add (&zebrad, rn);
718e3744 3424 }
3425 else
3426 {
3427 /* This is new static route. */
4d38fdb4 3428 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
3429
718e3744 3430 rib->type = ZEBRA_ROUTE_STATIC;
7c8ff89e 3431 rib->instance = 0;
718e3744 3432 rib->distance = si->distance;
3433 rib->metric = 0;
4595531e 3434 rib->table = zebrad.rtm_table_default;
718e3744 3435 rib->nexthop_num = 0;
0d9551dc 3436 rib->tag = si->tag;
718e3744 3437
3438 switch (si->type)
3439 {
3440 case STATIC_IPV6_GATEWAY:
3441 nexthop_ipv6_add (rib, &si->ipv6);
6e26278c
DS
3442 nh_p.family = AF_INET6;
3443 nh_p.prefixlen = IPV6_MAX_BITLEN;
3444 nh_p.u.prefix6 = si->ipv6;
3445 zebra_register_rnh_static_nh(&nh_p, rn);
718e3744 3446 break;
3447 case STATIC_IPV6_IFNAME:
3448 nexthop_ifname_add (rib, si->ifname);
3449 break;
3450 case STATIC_IPV6_GATEWAY_IFNAME:
3451 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
3452 break;
3453 }
3454
81dfcaa2 3455 /* Save the flags of this static routes (reject, blackhole) */
3456 rib->flags = si->flags;
3457
718e3744 3458 /* Link this rib to the tree. */
3459 rib_addnode (rn, rib);
718e3744 3460 }
3461}
3462
a1ac18c4 3463static int
718e3744 3464static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
3465{
3466 if (nexthop->type == NEXTHOP_TYPE_IPV6
3467 && si->type == STATIC_IPV6_GATEWAY
3468 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
3469 return 1;
3470 if (nexthop->type == NEXTHOP_TYPE_IFNAME
3471 && si->type == STATIC_IPV6_IFNAME
3472 && strcmp (nexthop->ifname, si->ifname) == 0)
3473 return 1;
3474 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
3475 && si->type == STATIC_IPV6_GATEWAY_IFNAME
3476 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
3477 && strcmp (nexthop->ifname, si->ifname) == 0)
3478 return 1;
e8e1946e 3479 return 0;
718e3744 3480}
3481
a1ac18c4 3482static void
718e3744 3483static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
3484{
3485 struct route_table *table;
3486 struct route_node *rn;
3487 struct rib *rib;
3488 struct nexthop *nexthop;
6e26278c 3489 struct prefix nh_p;
718e3744 3490
3491 /* Lookup table. */
3492 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
3493 if (! table)
3494 return;
3495
3496 /* Lookup existing route with type and distance. */
3497 rn = route_node_lookup (table, (struct prefix *) p);
3498 if (! rn)
3499 return;
3500
9fd92e3c 3501 RNODE_FOREACH_RIB (rn, rib)
6d691129
PJ
3502 {
3503 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3504 continue;
3505
0d9551dc
DS
3506 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance &&
3507 rib->tag == si->tag)
6d691129
PJ
3508 break;
3509 }
3510
718e3744 3511 if (! rib)
3512 {
3513 route_unlock_node (rn);
3514 return;
3515 }
3516
3517 /* Lookup nexthop. */
3518 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
3519 if (static_ipv6_nexthop_same (nexthop, si))
3520 break;
3521
3522 /* Can't find nexthop. */
3523 if (! nexthop)
3524 {
3525 route_unlock_node (rn);
3526 return;
3527 }
3528
3529 /* Check nexthop. */
3530 if (rib->nexthop_num == 1)
3531 {
3532 rib_delnode (rn, rib);
718e3744 3533 }
3534 else
3535 {
6baeb988 3536 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
3537 rib_uninstall (rn, rib);
6e26278c
DS
3538
3539 nh_p.family = AF_INET6;
3540 nh_p.prefixlen = IPV6_MAX_BITLEN;
3541 nh_p.u.prefix6 = nexthop->gate.ipv6;
319572cc 3542 nexthop_delete (rib, nexthop);
6e26278c
DS
3543 zebra_deregister_rnh_static_nh(&nh_p, rn);
3544 nexthop_free (nexthop, rn);
6d691129 3545 rib_queue_add (&zebrad, rn);
718e3744 3546 }
718e3744 3547 /* Unlock node. */
3548 route_unlock_node (rn);
3549}
3550
3551/* Add static route into static route configuration. */
3552int
3553static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
0d9551dc
DS
3554 const char *ifname, u_char flags, u_short tag,
3555 u_char distance, u_int32_t vrf_id)
718e3744 3556{
3557 struct route_node *rn;
3558 struct static_ipv6 *si;
3559 struct static_ipv6 *pp;
3560 struct static_ipv6 *cp;
3561 struct route_table *stable;
3562
3563 /* Lookup table. */
3564 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
3565 if (! stable)
3566 return -1;
27b47253
PJ
3567
3568 if (!gate &&
3569 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
3570 return -1;
3571
3572 if (!ifname &&
3573 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
3574 return -1;
718e3744 3575
3576 /* Lookup static route prefix. */
3577 rn = route_node_get (stable, p);
3578
3579 /* Do nothing if there is a same static route. */
3580 for (si = rn->info; si; si = si->next)
3581 {
3582 if (distance == si->distance
3583 && type == si->type
0d9551dc 3584 && tag == si->tag
718e3744 3585 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
3586 && (! ifname || strcmp (ifname, si->ifname) == 0))
3587 {
3588 route_unlock_node (rn);
3589 return 0;
3590 }
3591 }
3592
3593 /* Make new static route structure. */
393deb9b 3594 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
718e3744 3595
3596 si->type = type;
3597 si->distance = distance;
81dfcaa2 3598 si->flags = flags;
0d9551dc 3599 si->tag = tag;
718e3744 3600
3601 switch (type)
3602 {
3603 case STATIC_IPV6_GATEWAY:
3604 si->ipv6 = *gate;
3605 break;
3606 case STATIC_IPV6_IFNAME:
3607 si->ifname = XSTRDUP (0, ifname);
3608 break;
3609 case STATIC_IPV6_GATEWAY_IFNAME:
3610 si->ipv6 = *gate;
3611 si->ifname = XSTRDUP (0, ifname);
3612 break;
3613 }
3614
3615 /* Add new static route information to the tree with sort by
3616 distance value and gateway address. */
3617 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
3618 {
3619 if (si->distance < cp->distance)
3620 break;
3621 if (si->distance > cp->distance)
3622 continue;
3623 }
3624
3625 /* Make linked list. */
3626 if (pp)
3627 pp->next = si;
3628 else
3629 rn->info = si;
3630 if (cp)
3631 cp->prev = si;
3632 si->prev = pp;
3633 si->next = cp;
3634
3635 /* Install into rib. */
3636 static_install_ipv6 (p, si);
3637
3638 return 1;
3639}
3640
3641/* Delete static route from static route configuration. */
3642int
3643static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
0d9551dc
DS
3644 const char *ifname, u_short tag, u_char distance,
3645 u_int32_t vrf_id)
718e3744 3646{
3647 struct route_node *rn;
3648 struct static_ipv6 *si;
3649 struct route_table *stable;
3650
3651 /* Lookup table. */
3652 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
3653 if (! stable)
3654 return -1;
3655
3656 /* Lookup static route prefix. */
3657 rn = route_node_lookup (stable, p);
3658 if (! rn)
3659 return 0;
3660
3661 /* Find same static route is the tree */
3662 for (si = rn->info; si; si = si->next)
3663 if (distance == si->distance
3664 && type == si->type
3665 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
0d9551dc
DS
3666 && (! ifname || strcmp (ifname, si->ifname) == 0)
3667 && (! tag || (tag == si->tag)))
718e3744 3668 break;
3669
3670 /* Can't find static route. */
3671 if (! si)
3672 {
3673 route_unlock_node (rn);
3674 return 0;
3675 }
3676
3677 /* Install into rib. */
3678 static_uninstall_ipv6 (p, si);
3679
3680 /* Unlink static route from linked list. */
3681 if (si->prev)
3682 si->prev->next = si->next;
3683 else
3684 rn->info = si->next;
3685 if (si->next)
3686 si->next->prev = si->prev;
3687
3688 /* Free static route configuration. */
a0f6acd8 3689 if (ifname)
3690 XFREE (0, si->ifname);
718e3744 3691 XFREE (MTYPE_STATIC_IPV6, si);
3692
3693 return 1;
3694}
3695#endif /* HAVE_IPV6 */
6b0655a2 3696
718e3744 3697/* RIB update function. */
3698void
a1ac18c4 3699rib_update (void)
718e3744 3700{
3701 struct route_node *rn;
3702 struct route_table *table;
4d38fdb4 3703
718e3744 3704 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
3705 if (table)
3706 for (rn = route_top (table); rn; rn = route_next (rn))
9fd92e3c 3707 if (rnode_to_ribs (rn))
6d691129 3708 rib_queue_add (&zebrad, rn);
718e3744 3709
3710 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
3711 if (table)
3712 for (rn = route_top (table); rn; rn = route_next (rn))
9fd92e3c 3713 if (rnode_to_ribs (rn))
6d691129 3714 rib_queue_add (&zebrad, rn);
718e3744 3715}
3716
6b0655a2 3717
718e3744 3718/* Remove all routes which comes from non main table. */
a1ac18c4 3719static void
718e3744 3720rib_weed_table (struct route_table *table)
3721{
3722 struct route_node *rn;
3723 struct rib *rib;
3724 struct rib *next;
3725
3726 if (table)
3727 for (rn = route_top (table); rn; rn = route_next (rn))
9fd92e3c 3728 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
718e3744 3729 {
6d691129
PJ
3730 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3731 continue;
3732
b21b19c5 3733 if (rib->table != zebrad.rtm_table_default &&
718e3744 3734 rib->table != RT_TABLE_MAIN)
4d38fdb4 3735 rib_delnode (rn, rib);
718e3744 3736 }
3737}
3738
3739/* Delete all routes from non main table. */
3740void
a1ac18c4 3741rib_weed_tables (void)
718e3744 3742{
3743 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3744 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3745}
6b0655a2 3746
718e3744 3747/* Delete self installed routes after zebra is relaunched. */
a1ac18c4 3748static void
718e3744 3749rib_sweep_table (struct route_table *table)
3750{
3751 struct route_node *rn;
3752 struct rib *rib;
3753 struct rib *next;
3754 int ret = 0;
3755
3756 if (table)
3757 for (rn = route_top (table); rn; rn = route_next (rn))
9fd92e3c 3758 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
718e3744 3759 {
6d691129
PJ
3760 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3761 continue;
3762
718e3744 3763 if (rib->type == ZEBRA_ROUTE_KERNEL &&
3764 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
3765 {
3766 ret = rib_uninstall_kernel (rn, rib);
3767 if (! ret)
4d38fdb4 3768 rib_delnode (rn, rib);
718e3744 3769 }
3770 }
3771}
3772
3773/* Sweep all RIB tables. */
3774void
a1ac18c4 3775rib_sweep_route (void)
718e3744 3776{
3777 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3778 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3779}
2ea1ab1c
VT
3780
3781/* Remove specific by protocol routes from 'table'. */
3782static unsigned long
7c8ff89e 3783rib_score_proto_table (u_char proto, u_short instance, struct route_table *table)
2ea1ab1c
VT
3784{
3785 struct route_node *rn;
3786 struct rib *rib;
3787 struct rib *next;
3788 unsigned long n = 0;
3789
3790 if (table)
3791 for (rn = route_top (table); rn; rn = route_next (rn))
9fd92e3c 3792 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
2ea1ab1c 3793 {
2ea1ab1c
VT
3794 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3795 continue;
7c8ff89e 3796 if (rib->type == proto && rib->instance == instance)
2ea1ab1c
VT
3797 {
3798 rib_delnode (rn, rib);
3799 n++;
3800 }
3801 }
3802
3803 return n;
3804}
3805
3806/* Remove specific by protocol routes. */
3807unsigned long
7c8ff89e 3808rib_score_proto (u_char proto, u_short instance)
2ea1ab1c 3809{
7c8ff89e
DS
3810 return rib_score_proto_table (proto, instance, vrf_table (AFI_IP, SAFI_UNICAST, 0))
3811 +rib_score_proto_table (proto, instance, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2ea1ab1c
VT
3812}
3813
718e3744 3814/* Close RIB and clean up kernel routes. */
a1ac18c4 3815static void
718e3744 3816rib_close_table (struct route_table *table)
3817{
3818 struct route_node *rn;
3819 struct rib *rib;
3820
3821 if (table)
3822 for (rn = route_top (table); rn; rn = route_next (rn))
9fd92e3c 3823 RNODE_FOREACH_RIB (rn, rib)
6d691129 3824 {
9fd92e3c
AS
3825 if (!CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
3826 continue;
3827
5adc2528
AS
3828 zfpm_trigger_update (rn, NULL);
3829
9fd92e3c
AS
3830 if (! RIB_SYSTEM_ROUTE (rib))
3831 rib_uninstall_kernel (rn, rib);
6d691129 3832 }
718e3744 3833}
3834
3835/* Close all RIB tables. */
3836void
a1ac18c4 3837rib_close (void)
718e3744 3838{
3839 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3840 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3841}
6b0655a2 3842
718e3744 3843/* Routing information base initialize. */
3844void
a1ac18c4 3845rib_init (void)
718e3744 3846{
4d38fdb4 3847 rib_queue_init (&zebrad);
718e3744 3848 /* VRF initialization. */
3849 vrf_init ();
3850}
0915bb0c
AS
3851
3852/*
3853 * vrf_id_get_next
3854 *
3855 * Get the first vrf id that is greater than the given vrf id if any.
3856 *
3857 * Returns TRUE if a vrf id was found, FALSE otherwise.
3858 */
3859static inline int
3860vrf_id_get_next (uint32_t id, uint32_t *next_id_p)
3861{
3862 while (++id < vector_active (vrf_vector))
3863 {
3864 if (vrf_lookup (id))
3865 {
3866 *next_id_p = id;
3867 return 1;
3868 }
3869 }
3870
3871 return 0;
3872}
3873
3874/*
3875 * rib_tables_iter_next
3876 *
3877 * Returns the next table in the iteration.
3878 */
3879struct route_table *
3880rib_tables_iter_next (rib_tables_iter_t *iter)
3881{
3882 struct route_table *table;
3883
3884 /*
3885 * Array that helps us go over all AFI/SAFI combinations via one
3886 * index.
3887 */
3888 static struct {
3889 afi_t afi;
3890 safi_t safi;
3891 } afi_safis[] = {
3892 { AFI_IP, SAFI_UNICAST },
3893 { AFI_IP, SAFI_MULTICAST },
3894 { AFI_IP6, SAFI_UNICAST },
3895 { AFI_IP6, SAFI_MULTICAST },
3896 };
3897
3898 table = NULL;
3899
3900 switch (iter->state)
3901 {
3902
3903 case RIB_TABLES_ITER_S_INIT:
3904 iter->vrf_id = 0;
3905 iter->afi_safi_ix = -1;
3906
3907 /* Fall through */
3908
3909 case RIB_TABLES_ITER_S_ITERATING:
3910 iter->afi_safi_ix++;
3911 while (1)
3912 {
3913
3914 while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
3915 {
3916 table = vrf_table (afi_safis[iter->afi_safi_ix].afi,
3917 afi_safis[iter->afi_safi_ix].safi,
3918 iter->vrf_id);
3919 if (table)
3920 break;
3921
3922 iter->afi_safi_ix++;
3923 }
3924
3925 /*
3926 * Found another table in this vrf.
3927 */
3928 if (table)
3929 break;
3930
3931 /*
3932 * Done with all tables in the current vrf, go to the next
3933 * one.
3934 */
3935 if (!vrf_id_get_next (iter->vrf_id, &iter->vrf_id))
3936 break;
3937
3938 iter->afi_safi_ix = 0;
3939 }
3940
3941 break;
3942
3943 case RIB_TABLES_ITER_S_DONE:
3944 return NULL;
3945 }
3946
3947 if (table)
3948 iter->state = RIB_TABLES_ITER_S_ITERATING;
3949 else
3950 iter->state = RIB_TABLES_ITER_S_DONE;
3951
3952 return table;
3953}