blob: b4ea2424cee2be2eb2c7100e4e7c8e0d344934c9 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* Routing Information Base.
2 * Copyright (C) 1997, 98, 99, 2001 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "prefix.h"
25#include "table.h"
26#include "memory.h"
27#include "str.h"
28#include "command.h"
29#include "if.h"
30#include "log.h"
31#include "sockunion.h"
paul4d38fdb2005-04-28 17:35:14 +000032#include "linklist.h"
33#include "thread.h"
34#include "workqueue.h"
Paul Jakma7514fb72007-05-02 16:05:35 +000035#include "prefix.h"
36#include "routemap.h"
paul718e3742002-12-13 20:15:29 +000037
38#include "zebra/rib.h"
39#include "zebra/rt.h"
40#include "zebra/zserv.h"
41#include "zebra/redistribute.h"
42#include "zebra/debug.h"
Avneesh Sachdev5adc2522012-11-13 22:48:59 +000043#include "zebra/zebra_fpm.h"
paul718e3742002-12-13 20:15:29 +000044
45/* Default rtm_table for all clients */
paulb21b19c2003-06-15 01:28:29 +000046extern struct zebra_t zebrad;
paul718e3742002-12-13 20:15:29 +000047
Paul Jakma457eb9a2006-07-27 19:59:58 +000048/* Hold time for RIB process, should be very minimal.
49 * it is useful to able to set it otherwise for testing, hence exported
50 * as global here for test-rig code.
51 */
52int rib_process_hold_time = 10;
53
paul718e3742002-12-13 20:15:29 +000054/* Each route type's string and default distance value. */
Stephen Hemmingerd145bc02008-08-17 17:41:37 +010055static const struct
paul718e3742002-12-13 20:15:29 +000056{
57 int key;
58 int distance;
Paul Jakma57345092011-12-25 17:52:09 +010059} route_info[ZEBRA_ROUTE_MAX] =
paul718e3742002-12-13 20:15:29 +000060{
Paul Jakma57345092011-12-25 17:52:09 +010061 [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0},
62 [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0},
63 [ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0},
64 [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1},
65 [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120},
66 [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120},
67 [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110},
68 [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110},
69 [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115},
70 [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */},
71 [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 95},
David Lamparter7052f222009-08-27 00:28:28 +020072 /* no entry/default: 150 */
paul718e3742002-12-13 20:15:29 +000073};
David Lamparter6b0655a2014-06-04 06:53:35 +020074
paul718e3742002-12-13 20:15:29 +000075/* Vector for routing table. */
Stephen Hemmingerd145bc02008-08-17 17:41:37 +010076static vector vrf_vector;
paul718e3742002-12-13 20:15:29 +000077
David Lampartere0b0ac82014-04-24 20:22:53 +020078static void
79_rnode_zlog(const char *_func, struct route_node *rn, int priority,
80 const char *msgfmt, ...)
81{
82 char buf[INET6_ADDRSTRLEN + 4], *bptr;
83 char msgbuf[512];
84 va_list ap;
85
86 va_start(ap, msgfmt);
87 vsnprintf(msgbuf, sizeof(msgbuf), msgfmt, ap);
88 va_end(ap);
89
90 if (rn)
91 {
David Lamparterf7b3d1e2015-01-22 19:02:13 +010092 rib_table_info_t *info = rn->table->info;
93
David Lampartere0b0ac82014-04-24 20:22:53 +020094 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
95 bptr = buf + strlen(buf);
David Lamparterf7b3d1e2015-01-22 19:02:13 +010096 snprintf(bptr, buf + sizeof(buf) - bptr, "/%d%s", rn->p.prefixlen,
97 info->safi == SAFI_MULTICAST ? " (MRIB)" : "");
David Lampartere0b0ac82014-04-24 20:22:53 +020098 }
99 else
100 {
101 snprintf(buf, sizeof(buf), "{(route_node *) NULL}");
102 }
103
104 zlog (NULL, priority, "%s: %s: %s", _func, buf, msgbuf);
105}
106
107#define rnode_debug(node, ...) \
108 _rnode_zlog(__func__, node, LOG_DEBUG, __VA_ARGS__)
109#define rnode_info(node, ...) \
110 _rnode_zlog(__func__, node, LOG_INFO, __VA_ARGS__)
111
Avneesh Sachdev1b5ed1b2012-11-13 22:48:54 +0000112/*
113 * vrf_table_create
114 */
115static void
116vrf_table_create (struct vrf *vrf, afi_t afi, safi_t safi)
117{
118 rib_table_info_t *info;
119 struct route_table *table;
120
121 assert (!vrf->table[afi][safi]);
122
123 table = route_table_init ();
124 vrf->table[afi][safi] = table;
125
126 info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
127 info->vrf = vrf;
128 info->afi = afi;
129 info->safi = safi;
130 table->info = info;
131}
132
paul718e3742002-12-13 20:15:29 +0000133/* Allocate new VRF. */
paula1ac18c2005-06-28 17:17:12 +0000134static struct vrf *
hassofce954f2004-10-07 20:29:24 +0000135vrf_alloc (const char *name)
paul718e3742002-12-13 20:15:29 +0000136{
137 struct vrf *vrf;
138
139 vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
140
141 /* Put name. */
142 if (name)
143 vrf->name = XSTRDUP (MTYPE_VRF_NAME, name);
144
145 /* Allocate routing table and static table. */
Avneesh Sachdev1b5ed1b2012-11-13 22:48:54 +0000146 vrf_table_create (vrf, AFI_IP, SAFI_UNICAST);
147 vrf_table_create (vrf, AFI_IP6, SAFI_UNICAST);
paul718e3742002-12-13 20:15:29 +0000148 vrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
149 vrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
Avneesh Sachdev1b5ed1b2012-11-13 22:48:54 +0000150 vrf_table_create (vrf, AFI_IP, SAFI_MULTICAST);
151 vrf_table_create (vrf, AFI_IP6, SAFI_MULTICAST);
G.Balajicddf3912011-11-26 21:59:32 +0400152 vrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
153 vrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
154
paul718e3742002-12-13 20:15:29 +0000155
156 return vrf;
157}
158
paul718e3742002-12-13 20:15:29 +0000159/* Lookup VRF by identifier. */
160struct vrf *
161vrf_lookup (u_int32_t id)
162{
163 return vector_lookup (vrf_vector, id);
164}
165
paul718e3742002-12-13 20:15:29 +0000166/* Initialize VRF. */
paula1ac18c2005-06-28 17:17:12 +0000167static void
168vrf_init (void)
paul718e3742002-12-13 20:15:29 +0000169{
170 struct vrf *default_table;
171
172 /* Allocate VRF vector. */
173 vrf_vector = vector_init (1);
174
175 /* Allocate default main table. */
176 default_table = vrf_alloc ("Default-IP-Routing-Table");
177
178 /* Default table index must be 0. */
179 vector_set_index (vrf_vector, 0, default_table);
180}
181
182/* Lookup route table. */
183struct route_table *
184vrf_table (afi_t afi, safi_t safi, u_int32_t id)
185{
186 struct vrf *vrf;
187
188 vrf = vrf_lookup (id);
189 if (! vrf)
190 return NULL;
191
Leonid Rosenboim9499bf22012-12-06 20:17:41 +0000192 if( afi >= AFI_MAX || safi >= SAFI_MAX )
193 return NULL;
194
paul718e3742002-12-13 20:15:29 +0000195 return vrf->table[afi][safi];
196}
197
198/* Lookup static route table. */
199struct route_table *
200vrf_static_table (afi_t afi, safi_t safi, u_int32_t id)
201{
202 struct vrf *vrf;
203
204 vrf = vrf_lookup (id);
205 if (! vrf)
206 return NULL;
207
Leonid Rosenboim9499bf22012-12-06 20:17:41 +0000208 if( afi >= AFI_MAX || safi >= SAFI_MAX )
209 return NULL;
210
paul718e3742002-12-13 20:15:29 +0000211 return vrf->stable[afi][safi];
212}
David Lamparter6b0655a2014-06-04 06:53:35 +0200213
Avneesh Sachdev78deec42012-11-13 22:48:56 +0000214/*
215 * nexthop_type_to_str
216 */
217const char *
218nexthop_type_to_str (enum nexthop_types_t nh_type)
219{
220 static const char *desc[] = {
221 "none",
222 "Directly connected",
223 "Interface route",
224 "IPv4 nexthop",
225 "IPv4 nexthop with ifindex",
226 "IPv4 nexthop with ifname",
227 "IPv6 nexthop",
228 "IPv6 nexthop with ifindex",
229 "IPv6 nexthop with ifname",
230 "Null0 nexthop",
231 };
232
233 if (nh_type >= ZEBRA_NUM_OF (desc))
234 return "<Invalid nh type>";
235
236 return desc[nh_type];
237}
238
Christian Frankefa713d92013-07-05 15:35:37 +0000239/* Add nexthop to the end of a nexthop list. */
paula1ac18c2005-06-28 17:17:12 +0000240static void
Christian Frankefa713d92013-07-05 15:35:37 +0000241_nexthop_add (struct nexthop **target, struct nexthop *nexthop)
paul718e3742002-12-13 20:15:29 +0000242{
243 struct nexthop *last;
244
Christian Frankefa713d92013-07-05 15:35:37 +0000245 for (last = *target; last && last->next; last = last->next)
paul718e3742002-12-13 20:15:29 +0000246 ;
247 if (last)
248 last->next = nexthop;
249 else
Christian Frankefa713d92013-07-05 15:35:37 +0000250 *target = nexthop;
paul718e3742002-12-13 20:15:29 +0000251 nexthop->prev = last;
Christian Frankefa713d92013-07-05 15:35:37 +0000252}
paul718e3742002-12-13 20:15:29 +0000253
Christian Frankefa713d92013-07-05 15:35:37 +0000254/* Add nexthop to the end of a rib node's nexthop list */
255static void
256nexthop_add (struct rib *rib, struct nexthop *nexthop)
257{
258 _nexthop_add(&rib->nexthop, nexthop);
paul718e3742002-12-13 20:15:29 +0000259 rib->nexthop_num++;
260}
261
262/* Delete specified nexthop from the list. */
paula1ac18c2005-06-28 17:17:12 +0000263static void
paul718e3742002-12-13 20:15:29 +0000264nexthop_delete (struct rib *rib, struct nexthop *nexthop)
265{
266 if (nexthop->next)
267 nexthop->next->prev = nexthop->prev;
268 if (nexthop->prev)
269 nexthop->prev->next = nexthop->next;
270 else
271 rib->nexthop = nexthop->next;
272 rib->nexthop_num--;
273}
274
Christian Frankefa713d92013-07-05 15:35:37 +0000275static void nexthops_free(struct nexthop *nexthop);
276
paul718e3742002-12-13 20:15:29 +0000277/* Free nexthop. */
paula1ac18c2005-06-28 17:17:12 +0000278static void
paul718e3742002-12-13 20:15:29 +0000279nexthop_free (struct nexthop *nexthop)
280{
paula4b70762003-05-16 17:19:48 +0000281 if (nexthop->ifname)
282 XFREE (0, nexthop->ifname);
Christian Frankefa713d92013-07-05 15:35:37 +0000283 if (nexthop->resolved)
284 nexthops_free(nexthop->resolved);
paul718e3742002-12-13 20:15:29 +0000285 XFREE (MTYPE_NEXTHOP, nexthop);
286}
287
Christian Frankefa713d92013-07-05 15:35:37 +0000288/* Frees a list of nexthops */
289static void
290nexthops_free (struct nexthop *nexthop)
291{
292 struct nexthop *nh, *next;
293
294 for (nh = nexthop; nh; nh = next)
295 {
296 next = nh->next;
297 nexthop_free (nh);
298 }
299}
300
paul718e3742002-12-13 20:15:29 +0000301struct nexthop *
302nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
303{
304 struct nexthop *nexthop;
305
Stephen Hemminger393deb92008-08-18 14:13:29 -0700306 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000307 nexthop->type = NEXTHOP_TYPE_IFINDEX;
308 nexthop->ifindex = ifindex;
309
310 nexthop_add (rib, nexthop);
311
312 return nexthop;
313}
314
315struct nexthop *
316nexthop_ifname_add (struct rib *rib, char *ifname)
317{
318 struct nexthop *nexthop;
319
Stephen Hemminger393deb92008-08-18 14:13:29 -0700320 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000321 nexthop->type = NEXTHOP_TYPE_IFNAME;
paula4b70762003-05-16 17:19:48 +0000322 nexthop->ifname = XSTRDUP (0, ifname);
paul718e3742002-12-13 20:15:29 +0000323
324 nexthop_add (rib, nexthop);
325
326 return nexthop;
327}
328
329struct nexthop *
Paul Jakma7514fb72007-05-02 16:05:35 +0000330nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src)
paul718e3742002-12-13 20:15:29 +0000331{
332 struct nexthop *nexthop;
333
Stephen Hemminger393deb92008-08-18 14:13:29 -0700334 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000335 nexthop->type = NEXTHOP_TYPE_IPV4;
336 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000337 if (src)
338 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000339
340 nexthop_add (rib, nexthop);
341
342 return nexthop;
343}
344
Josh Bailey26e2ae32012-03-22 01:09:21 -0700345struct nexthop *
paul718e3742002-12-13 20:15:29 +0000346nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
Paul Jakma7514fb72007-05-02 16:05:35 +0000347 struct in_addr *src, unsigned int ifindex)
paul718e3742002-12-13 20:15:29 +0000348{
349 struct nexthop *nexthop;
350
Stephen Hemminger393deb92008-08-18 14:13:29 -0700351 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000352 nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
353 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000354 if (src)
355 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000356 nexthop->ifindex = ifindex;
357
358 nexthop_add (rib, nexthop);
359
360 return nexthop;
361}
362
363#ifdef HAVE_IPV6
364struct nexthop *
365nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
366{
367 struct nexthop *nexthop;
368
Stephen Hemminger393deb92008-08-18 14:13:29 -0700369 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000370 nexthop->type = NEXTHOP_TYPE_IPV6;
371 nexthop->gate.ipv6 = *ipv6;
372
373 nexthop_add (rib, nexthop);
374
375 return nexthop;
376}
377
paula1ac18c2005-06-28 17:17:12 +0000378static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000379nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
380 char *ifname)
381{
382 struct nexthop *nexthop;
383
Stephen Hemminger393deb92008-08-18 14:13:29 -0700384 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000385 nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
386 nexthop->gate.ipv6 = *ipv6;
387 nexthop->ifname = XSTRDUP (0, ifname);
388
389 nexthop_add (rib, nexthop);
390
391 return nexthop;
392}
393
paula1ac18c2005-06-28 17:17:12 +0000394static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000395nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
396 unsigned int ifindex)
397{
398 struct nexthop *nexthop;
399
Stephen Hemminger393deb92008-08-18 14:13:29 -0700400 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000401 nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
402 nexthop->gate.ipv6 = *ipv6;
403 nexthop->ifindex = ifindex;
404
405 nexthop_add (rib, nexthop);
406
407 return nexthop;
408}
409#endif /* HAVE_IPV6 */
410
paul595db7f2003-05-25 21:35:06 +0000411struct nexthop *
412nexthop_blackhole_add (struct rib *rib)
413{
414 struct nexthop *nexthop;
415
Stephen Hemminger393deb92008-08-18 14:13:29 -0700416 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul595db7f2003-05-25 21:35:06 +0000417 nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
418 SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
419
420 nexthop_add (rib, nexthop);
421
422 return nexthop;
423}
424
Christian Frankefa713d92013-07-05 15:35:37 +0000425/* This method checks whether a recursive nexthop has at
426 * least one resolved nexthop in the fib.
427 */
428int
429nexthop_has_fib_child(struct nexthop *nexthop)
430{
431 struct nexthop *nh;
432
433 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
434 return 0;
435
436 for (nh = nexthop->resolved; nh; nh = nh->next)
437 if (CHECK_FLAG (nh->flags, NEXTHOP_FLAG_FIB))
438 return 1;
439
440 return 0;
441}
442
paul718e3742002-12-13 20:15:29 +0000443/* If force flag is not set, do not modify falgs at all for uninstall
444 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000445static int
paul718e3742002-12-13 20:15:29 +0000446nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
447 struct route_node *top)
448{
449 struct prefix_ipv4 p;
450 struct route_table *table;
451 struct route_node *rn;
452 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000453 int resolved;
paul718e3742002-12-13 20:15:29 +0000454 struct nexthop *newhop;
Christian Frankefa713d92013-07-05 15:35:37 +0000455 struct nexthop *resolved_hop;
paul718e3742002-12-13 20:15:29 +0000456
457 if (nexthop->type == NEXTHOP_TYPE_IPV4)
458 nexthop->ifindex = 0;
459
460 if (set)
Christian Frankefa713d92013-07-05 15:35:37 +0000461 {
462 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
463 nexthops_free(nexthop->resolved);
464 nexthop->resolved = NULL;
465 }
paul718e3742002-12-13 20:15:29 +0000466
467 /* Make lookup prefix. */
468 memset (&p, 0, sizeof (struct prefix_ipv4));
469 p.family = AF_INET;
470 p.prefixlen = IPV4_MAX_PREFIXLEN;
471 p.prefix = nexthop->gate.ipv4;
472
473 /* Lookup table. */
474 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
475 if (! table)
476 return 0;
477
478 rn = route_node_match (table, (struct prefix *) &p);
479 while (rn)
480 {
481 route_unlock_node (rn);
482
David Warda50c1072009-12-03 15:34:39 +0300483 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000484 if (rn == top)
485 return 0;
486
487 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000488 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100489 {
490 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
491 continue;
492 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
493 break;
494 }
paul718e3742002-12-13 20:15:29 +0000495
496 /* If there is no selected route or matched route is EGP, go up
497 tree. */
498 if (! match
499 || match->type == ZEBRA_ROUTE_BGP)
500 {
501 do {
502 rn = rn->parent;
503 } while (rn && rn->info == NULL);
504 if (rn)
505 route_lock_node (rn);
506 }
507 else
508 {
Christian Franke48a53dc2013-07-05 15:35:38 +0000509 /* If the longest prefix match for the nexthop yields
510 * a blackhole, mark it as inactive. */
511 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE)
512 || CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT))
513 return 0;
514
paul718e3742002-12-13 20:15:29 +0000515 if (match->type == ZEBRA_ROUTE_CONNECT)
516 {
517 /* Directly point connected route. */
518 newhop = match->nexthop;
519 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
520 nexthop->ifindex = newhop->ifindex;
521
522 return 1;
523 }
524 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
525 {
Christian Frankefa713d92013-07-05 15:35:37 +0000526 resolved = 0;
paul718e3742002-12-13 20:15:29 +0000527 for (newhop = match->nexthop; newhop; newhop = newhop->next)
528 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
529 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
530 {
531 if (set)
532 {
533 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
Christian Frankefa713d92013-07-05 15:35:37 +0000534
535 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
536 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
Christian Frankec3e6b592013-07-05 15:35:40 +0000537 /* If the resolving route specifies a gateway, use it */
538 if (newhop->type == NEXTHOP_TYPE_IPV4
539 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX
540 || newhop->type == NEXTHOP_TYPE_IPV4_IFNAME)
541 {
542 resolved_hop->type = newhop->type;
543 resolved_hop->gate.ipv4 = newhop->gate.ipv4;
Christian Frankefa713d92013-07-05 15:35:37 +0000544
Christian Frankec3e6b592013-07-05 15:35:40 +0000545 if (newhop->ifindex)
546 {
547 resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
548 resolved_hop->ifindex = newhop->ifindex;
549 }
550 }
Christian Frankefa713d92013-07-05 15:35:37 +0000551
Christian Frankec3e6b592013-07-05 15:35:40 +0000552 /* If the resolving route is an interface route,
553 * it means the gateway we are looking up is connected
554 * to that interface. (The actual network is _not_ onlink).
555 * Therefore, the resolved route should have the original
556 * gateway as nexthop as it is directly connected.
557 *
558 * On Linux, we have to set the onlink netlink flag because
559 * otherwise, the kernel won't accept the route. */
paul718e3742002-12-13 20:15:29 +0000560 if (newhop->type == NEXTHOP_TYPE_IFINDEX
Christian Frankec3e6b592013-07-05 15:35:40 +0000561 || newhop->type == NEXTHOP_TYPE_IFNAME)
562 {
563 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
564 resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
565 resolved_hop->gate.ipv4 = nexthop->gate.ipv4;
566 resolved_hop->ifindex = newhop->ifindex;
567 }
Christian Frankefa713d92013-07-05 15:35:37 +0000568
569 _nexthop_add(&nexthop->resolved, resolved_hop);
paul718e3742002-12-13 20:15:29 +0000570 }
Christian Frankefa713d92013-07-05 15:35:37 +0000571 resolved = 1;
paul718e3742002-12-13 20:15:29 +0000572 }
Christian Frankefa713d92013-07-05 15:35:37 +0000573 return resolved;
paul718e3742002-12-13 20:15:29 +0000574 }
575 else
576 {
577 return 0;
578 }
579 }
580 }
581 return 0;
582}
583
584#ifdef HAVE_IPV6
585/* If force flag is not set, do not modify falgs at all for uninstall
586 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000587static int
paul718e3742002-12-13 20:15:29 +0000588nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
589 struct route_node *top)
590{
591 struct prefix_ipv6 p;
592 struct route_table *table;
593 struct route_node *rn;
594 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000595 int resolved;
paul718e3742002-12-13 20:15:29 +0000596 struct nexthop *newhop;
Christian Frankefa713d92013-07-05 15:35:37 +0000597 struct nexthop *resolved_hop;
paul718e3742002-12-13 20:15:29 +0000598
599 if (nexthop->type == NEXTHOP_TYPE_IPV6)
600 nexthop->ifindex = 0;
601
602 if (set)
Christian Frankefa713d92013-07-05 15:35:37 +0000603 {
604 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
605 nexthops_free(nexthop->resolved);
606 nexthop->resolved = NULL;
607 }
paul718e3742002-12-13 20:15:29 +0000608
609 /* Make lookup prefix. */
610 memset (&p, 0, sizeof (struct prefix_ipv6));
611 p.family = AF_INET6;
612 p.prefixlen = IPV6_MAX_PREFIXLEN;
613 p.prefix = nexthop->gate.ipv6;
614
615 /* Lookup table. */
616 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
617 if (! table)
618 return 0;
619
620 rn = route_node_match (table, (struct prefix *) &p);
621 while (rn)
622 {
623 route_unlock_node (rn);
624
David Warda50c1072009-12-03 15:34:39 +0300625 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000626 if (rn == top)
627 return 0;
628
629 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000630 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100631 {
632 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
633 continue;
634 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
635 break;
636 }
paul718e3742002-12-13 20:15:29 +0000637
638 /* If there is no selected route or matched route is EGP, go up
639 tree. */
640 if (! match
641 || match->type == ZEBRA_ROUTE_BGP)
642 {
643 do {
644 rn = rn->parent;
645 } while (rn && rn->info == NULL);
646 if (rn)
647 route_lock_node (rn);
648 }
649 else
650 {
Christian Franke48a53dc2013-07-05 15:35:38 +0000651 /* If the longest prefix match for the nexthop yields
652 * a blackhole, mark it as inactive. */
653 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE)
654 || CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT))
655 return 0;
656
paul718e3742002-12-13 20:15:29 +0000657 if (match->type == ZEBRA_ROUTE_CONNECT)
658 {
659 /* Directly point connected route. */
660 newhop = match->nexthop;
661
662 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
663 nexthop->ifindex = newhop->ifindex;
664
665 return 1;
666 }
667 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
668 {
Christian Frankefa713d92013-07-05 15:35:37 +0000669 resolved = 0;
paul718e3742002-12-13 20:15:29 +0000670 for (newhop = match->nexthop; newhop; newhop = newhop->next)
671 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
672 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
673 {
674 if (set)
675 {
676 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
Christian Frankefa713d92013-07-05 15:35:37 +0000677
678 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
679 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
Christian Frankec3e6b592013-07-05 15:35:40 +0000680 /* See nexthop_active_ipv4 for a description how the
681 * resolved nexthop is constructed. */
paul718e3742002-12-13 20:15:29 +0000682 if (newhop->type == NEXTHOP_TYPE_IPV6
683 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
684 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
Christian Frankec3e6b592013-07-05 15:35:40 +0000685 {
686 resolved_hop->type = newhop->type;
687 resolved_hop->gate.ipv6 = newhop->gate.ipv6;
688
689 if (newhop->ifindex)
690 {
691 resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
692 resolved_hop->ifindex = newhop->ifindex;
693 }
694 }
Christian Frankefa713d92013-07-05 15:35:37 +0000695
paul718e3742002-12-13 20:15:29 +0000696 if (newhop->type == NEXTHOP_TYPE_IFINDEX
Christian Frankec3e6b592013-07-05 15:35:40 +0000697 || newhop->type == NEXTHOP_TYPE_IFNAME)
698 {
699 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
700 resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
701 resolved_hop->gate.ipv6 = nexthop->gate.ipv6;
702 resolved_hop->ifindex = newhop->ifindex;
703 }
Christian Frankefa713d92013-07-05 15:35:37 +0000704
705 _nexthop_add(&nexthop->resolved, resolved_hop);
paul718e3742002-12-13 20:15:29 +0000706 }
Christian Frankefa713d92013-07-05 15:35:37 +0000707 resolved = 1;
paul718e3742002-12-13 20:15:29 +0000708 }
Christian Frankefa713d92013-07-05 15:35:37 +0000709 return resolved;
paul718e3742002-12-13 20:15:29 +0000710 }
711 else
712 {
713 return 0;
714 }
715 }
716 }
717 return 0;
718}
719#endif /* HAVE_IPV6 */
720
721struct rib *
Everton Marques12150f02014-09-19 16:39:34 -0300722rib_match_ipv4_safi (struct in_addr addr, safi_t safi, int skip_bgp)
Everton Marques346a8b52014-09-22 19:35:51 -0300723{
724 struct route_table *table;
725 struct route_node *rn;
726 struct rib *match;
727 struct nexthop *newhop, *tnewhop;
728 int recursing;
729
730 /* Lookup table. */
731 table = vrf_table (AFI_IP, safi, 0);
732 if (! table)
733 return 0;
734
735 rn = route_node_match_ipv4 (table, &addr);
736
737 while (rn)
738 {
739 route_unlock_node (rn);
740
741 /* Pick up selected route. */
742 RNODE_FOREACH_RIB (rn, match)
743 {
744 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
745 continue;
746 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
747 break;
748 }
749
750 /* If there is no selected route or matched route is EGP, go up
751 tree. */
Everton Marques12150f02014-09-19 16:39:34 -0300752 if (!match || (skip_bgp && (match->type == ZEBRA_ROUTE_BGP)))
Everton Marques346a8b52014-09-22 19:35:51 -0300753 {
754 do {
755 rn = rn->parent;
756 } while (rn && rn->info == NULL);
757 if (rn)
758 route_lock_node (rn);
759 }
760 else
761 {
762 if (match->type == ZEBRA_ROUTE_CONNECT)
763 /* Directly point connected route. */
764 return match;
765 else
766 {
767 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
768 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
769 return match;
770 return NULL;
771 }
772 }
773 }
774 return NULL;
775}
776
777struct rib *
paul718e3742002-12-13 20:15:29 +0000778rib_lookup_ipv4 (struct prefix_ipv4 *p)
779{
780 struct route_table *table;
781 struct route_node *rn;
782 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000783 struct nexthop *nexthop, *tnexthop;
784 int recursing;
paul718e3742002-12-13 20:15:29 +0000785
786 /* Lookup table. */
787 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
788 if (! table)
789 return 0;
790
791 rn = route_node_lookup (table, (struct prefix *) p);
792
793 /* No route for this prefix. */
794 if (! rn)
795 return NULL;
796
797 /* Unlock node. */
798 route_unlock_node (rn);
799
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000800 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100801 {
802 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
803 continue;
804 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
805 break;
806 }
paul718e3742002-12-13 20:15:29 +0000807
808 if (! match || match->type == ZEBRA_ROUTE_BGP)
809 return NULL;
810
811 if (match->type == ZEBRA_ROUTE_CONNECT)
812 return match;
813
Christian Frankefa713d92013-07-05 15:35:37 +0000814 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +0000815 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
816 return match;
817
818 return NULL;
819}
820
Denis Ovsienkodc958242007-08-13 16:03:06 +0000821/*
822 * This clone function, unlike its original rib_lookup_ipv4(), checks
823 * if specified IPv4 route record (prefix/mask -> gate) exists in
824 * the whole RIB and has ZEBRA_FLAG_SELECTED set.
825 *
826 * Return values:
827 * -1: error
828 * 0: exact match found
829 * 1: a match was found with a different gate
830 * 2: connected route found
831 * 3: no matches found
832 */
833int
834rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
835{
836 struct route_table *table;
837 struct route_node *rn;
838 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000839 struct nexthop *nexthop, *tnexthop;
840 int recursing;
841 int nexthops_active;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000842
843 /* Lookup table. */
844 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
845 if (! table)
846 return ZEBRA_RIB_LOOKUP_ERROR;
847
848 /* Scan the RIB table for exactly matching RIB entry. */
849 rn = route_node_lookup (table, (struct prefix *) p);
850
851 /* No route for this prefix. */
852 if (! rn)
853 return ZEBRA_RIB_NOTFOUND;
854
855 /* Unlock node. */
856 route_unlock_node (rn);
857
858 /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000859 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100860 {
861 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
862 continue;
863 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
864 break;
865 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000866
867 /* None such found :( */
868 if (!match)
869 return ZEBRA_RIB_NOTFOUND;
870
871 if (match->type == ZEBRA_ROUTE_CONNECT)
872 return ZEBRA_RIB_FOUND_CONNECTED;
873
874 /* Ok, we have a cood candidate, let's check it's nexthop list... */
Christian Frankefa713d92013-07-05 15:35:37 +0000875 nexthops_active = 0;
876 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000877 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000878 {
Christian Frankefa713d92013-07-05 15:35:37 +0000879 nexthops_active = 1;
880 if (nexthop->gate.ipv4.s_addr == sockunion2ip (qgate))
881 return ZEBRA_RIB_FOUND_EXACT;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000882 if (IS_ZEBRA_DEBUG_RIB)
Christian Frankefa713d92013-07-05 15:35:37 +0000883 {
884 char gate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
885 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
886 inet_ntop (AF_INET, &sockunion2ip(qgate), qgate_buf, INET_ADDRSTRLEN);
887 zlog_debug ("%s: qgate == %s, %s == %s", __func__,
888 qgate_buf, recursing ? "rgate" : "gate", gate_buf);
889 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000890 }
Christian Frankefa713d92013-07-05 15:35:37 +0000891
892 if (nexthops_active)
893 return ZEBRA_RIB_FOUND_NOGATE;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000894
895 return ZEBRA_RIB_NOTFOUND;
896}
897
paul718e3742002-12-13 20:15:29 +0000898#ifdef HAVE_IPV6
899struct rib *
900rib_match_ipv6 (struct in6_addr *addr)
901{
902 struct prefix_ipv6 p;
903 struct route_table *table;
904 struct route_node *rn;
905 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000906 struct nexthop *newhop, *tnewhop;
907 int recursing;
paul718e3742002-12-13 20:15:29 +0000908
909 /* Lookup table. */
910 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
911 if (! table)
912 return 0;
913
914 memset (&p, 0, sizeof (struct prefix_ipv6));
915 p.family = AF_INET6;
916 p.prefixlen = IPV6_MAX_PREFIXLEN;
917 IPV6_ADDR_COPY (&p.prefix, addr);
918
919 rn = route_node_match (table, (struct prefix *) &p);
920
921 while (rn)
922 {
923 route_unlock_node (rn);
924
925 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000926 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100927 {
928 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
929 continue;
930 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
931 break;
932 }
paul718e3742002-12-13 20:15:29 +0000933
934 /* If there is no selected route or matched route is EGP, go up
935 tree. */
936 if (! match
937 || match->type == ZEBRA_ROUTE_BGP)
938 {
939 do {
940 rn = rn->parent;
941 } while (rn && rn->info == NULL);
942 if (rn)
943 route_lock_node (rn);
944 }
945 else
946 {
947 if (match->type == ZEBRA_ROUTE_CONNECT)
948 /* Directly point connected route. */
949 return match;
950 else
951 {
Christian Frankefa713d92013-07-05 15:35:37 +0000952 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
paul718e3742002-12-13 20:15:29 +0000953 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
954 return match;
955 return NULL;
956 }
957 }
958 }
959 return NULL;
960}
961#endif /* HAVE_IPV6 */
962
Paul Jakma7514fb72007-05-02 16:05:35 +0000963#define RIB_SYSTEM_ROUTE(R) \
964 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
965
Denis Ovsienkodc958242007-08-13 16:03:06 +0000966/* This function verifies reachability of one given nexthop, which can be
967 * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
968 * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
969 * nexthop->ifindex will be updated appropriately as well.
970 * An existing route map can turn (otherwise active) nexthop into inactive, but
971 * not vice versa.
972 *
973 * The return value is the final value of 'ACTIVE' flag.
974 */
975
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300976static unsigned
paul718e3742002-12-13 20:15:29 +0000977nexthop_active_check (struct route_node *rn, struct rib *rib,
978 struct nexthop *nexthop, int set)
979{
Christian Frankef3a17322013-07-05 15:35:41 +0000980 rib_table_info_t *info = rn->table->info;
paul718e3742002-12-13 20:15:29 +0000981 struct interface *ifp;
Paul Jakma7514fb72007-05-02 16:05:35 +0000982 route_map_result_t ret = RMAP_MATCH;
983 extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
984 struct route_map *rmap;
985 int family;
paul718e3742002-12-13 20:15:29 +0000986
Paul Jakma7514fb72007-05-02 16:05:35 +0000987 family = 0;
paul718e3742002-12-13 20:15:29 +0000988 switch (nexthop->type)
989 {
990 case NEXTHOP_TYPE_IFINDEX:
991 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000992 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000993 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
994 else
995 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
996 break;
paul718e3742002-12-13 20:15:29 +0000997 case NEXTHOP_TYPE_IPV6_IFNAME:
Paul Jakma7514fb72007-05-02 16:05:35 +0000998 family = AFI_IP6;
999 case NEXTHOP_TYPE_IFNAME:
paul718e3742002-12-13 20:15:29 +00001000 ifp = if_lookup_by_name (nexthop->ifname);
Andrew J. Schorr3f087672008-01-08 20:12:46 +00001001 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001002 {
1003 if (set)
1004 nexthop->ifindex = ifp->ifindex;
1005 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1006 }
1007 else
1008 {
1009 if (set)
1010 nexthop->ifindex = 0;
1011 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1012 }
1013 break;
1014 case NEXTHOP_TYPE_IPV4:
1015 case NEXTHOP_TYPE_IPV4_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +00001016 family = AFI_IP;
paul718e3742002-12-13 20:15:29 +00001017 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
1018 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1019 else
1020 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1021 break;
1022#ifdef HAVE_IPV6
1023 case NEXTHOP_TYPE_IPV6:
Paul Jakma7514fb72007-05-02 16:05:35 +00001024 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +00001025 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
1026 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1027 else
1028 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1029 break;
1030 case NEXTHOP_TYPE_IPV6_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +00001031 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +00001032 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
1033 {
1034 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +00001035 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001036 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1037 else
1038 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1039 }
1040 else
1041 {
1042 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
1043 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1044 else
1045 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1046 }
1047 break;
1048#endif /* HAVE_IPV6 */
paul595db7f2003-05-25 21:35:06 +00001049 case NEXTHOP_TYPE_BLACKHOLE:
1050 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1051 break;
paul718e3742002-12-13 20:15:29 +00001052 default:
1053 break;
1054 }
Paul Jakma7514fb72007-05-02 16:05:35 +00001055 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1056 return 0;
1057
Christian Frankef3a17322013-07-05 15:35:41 +00001058 /* XXX: What exactly do those checks do? Do we support
1059 * e.g. IPv4 routes with IPv6 nexthops or vice versa? */
Paul Jakma7514fb72007-05-02 16:05:35 +00001060 if (RIB_SYSTEM_ROUTE(rib) ||
1061 (family == AFI_IP && rn->p.family != AF_INET) ||
1062 (family == AFI_IP6 && rn->p.family != AF_INET6))
1063 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1064
Christian Frankef3a17322013-07-05 15:35:41 +00001065 /* The original code didn't determine the family correctly
1066 * e.g. for NEXTHOP_TYPE_IFINDEX. Retrieve the correct afi
1067 * from the rib_table_info in those cases.
1068 * Possibly it may be better to use only the rib_table_info
1069 * in every case.
1070 */
1071 if (!family)
1072 family = info->afi;
1073
Paul Jakma7514fb72007-05-02 16:05:35 +00001074 rmap = 0;
1075 if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
1076 proto_rm[family][rib->type])
1077 rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
1078 if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
1079 rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
1080 if (rmap) {
1081 ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, nexthop);
1082 }
1083
1084 if (ret == RMAP_DENYMATCH)
1085 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
paul718e3742002-12-13 20:15:29 +00001086 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1087}
1088
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001089/* Iterate over all nexthops of the given RIB entry and refresh their
1090 * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
1091 * nexthop is found to toggle the ACTIVE flag, the whole rib structure
1092 * is flagged with ZEBRA_FLAG_CHANGED. The 4th 'set' argument is
1093 * transparently passed to nexthop_active_check().
1094 *
1095 * Return value is the new number of active nexthops.
1096 */
1097
paula1ac18c2005-06-28 17:17:12 +00001098static int
paul718e3742002-12-13 20:15:29 +00001099nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
1100{
1101 struct nexthop *nexthop;
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001102 unsigned int prev_active, prev_index, new_active;
paul718e3742002-12-13 20:15:29 +00001103
1104 rib->nexthop_active_num = 0;
1105 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1106
1107 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001108 {
1109 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001110 prev_index = nexthop->ifindex;
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001111 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
1112 rib->nexthop_active_num++;
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001113 if (prev_active != new_active ||
1114 prev_index != nexthop->ifindex)
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001115 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1116 }
paul718e3742002-12-13 20:15:29 +00001117 return rib->nexthop_active_num;
1118}
paul6baeb982003-10-28 03:47:15 +00001119
David Lamparter6b0655a2014-06-04 06:53:35 +02001120
paul718e3742002-12-13 20:15:29 +00001121
paula1ac18c2005-06-28 17:17:12 +00001122static void
paul718e3742002-12-13 20:15:29 +00001123rib_install_kernel (struct route_node *rn, struct rib *rib)
1124{
1125 int ret = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001126 struct nexthop *nexthop, *tnexthop;
David Lamparterc048dcc2015-01-12 07:05:06 +01001127 rib_table_info_t *info = rn->table->info;
Christian Frankefa713d92013-07-05 15:35:37 +00001128 int recursing;
paul718e3742002-12-13 20:15:29 +00001129
David Lamparterc048dcc2015-01-12 07:05:06 +01001130 if (info->safi != SAFI_UNICAST)
1131 {
1132 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1133 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1134 return;
1135 }
1136
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001137 /*
1138 * Make sure we update the FPM any time we send new information to
1139 * the kernel.
1140 */
1141 zfpm_trigger_update (rn, "installing in kernel");
paul718e3742002-12-13 20:15:29 +00001142 switch (PREFIX_FAMILY (&rn->p))
1143 {
1144 case AF_INET:
1145 ret = kernel_add_ipv4 (&rn->p, rib);
1146 break;
1147#ifdef HAVE_IPV6
1148 case AF_INET6:
1149 ret = kernel_add_ipv6 (&rn->p, rib);
1150 break;
1151#endif /* HAVE_IPV6 */
1152 }
1153
Denis Ovsienkodc958242007-08-13 16:03:06 +00001154 /* This condition is never met, if we are using rt_socket.c */
paul718e3742002-12-13 20:15:29 +00001155 if (ret < 0)
1156 {
Christian Frankefa713d92013-07-05 15:35:37 +00001157 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +00001158 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1159 }
1160}
1161
1162/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001163static int
paul718e3742002-12-13 20:15:29 +00001164rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
1165{
1166 int ret = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001167 struct nexthop *nexthop, *tnexthop;
David Lamparterc048dcc2015-01-12 07:05:06 +01001168 rib_table_info_t *info = rn->table->info;
Christian Frankefa713d92013-07-05 15:35:37 +00001169 int recursing;
paul718e3742002-12-13 20:15:29 +00001170
David Lamparterc048dcc2015-01-12 07:05:06 +01001171 if (info->safi != SAFI_UNICAST)
1172 {
1173 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1174 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1175 return ret;
1176 }
1177
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001178 /*
1179 * Make sure we update the FPM any time we send new information to
1180 * the kernel.
1181 */
1182 zfpm_trigger_update (rn, "uninstalling from kernel");
1183
paul718e3742002-12-13 20:15:29 +00001184 switch (PREFIX_FAMILY (&rn->p))
1185 {
1186 case AF_INET:
1187 ret = kernel_delete_ipv4 (&rn->p, rib);
1188 break;
1189#ifdef HAVE_IPV6
1190 case AF_INET6:
1191 ret = kernel_delete_ipv6 (&rn->p, rib);
1192 break;
1193#endif /* HAVE_IPV6 */
1194 }
1195
Christian Frankefa713d92013-07-05 15:35:37 +00001196 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +00001197 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1198
1199 return ret;
1200}
1201
1202/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001203static void
paul718e3742002-12-13 20:15:29 +00001204rib_uninstall (struct route_node *rn, struct rib *rib)
1205{
David Lamparterc048dcc2015-01-12 07:05:06 +01001206 rib_table_info_t *info = rn->table->info;
1207
paul718e3742002-12-13 20:15:29 +00001208 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1209 {
David Lamparterc048dcc2015-01-12 07:05:06 +01001210 if (info->safi == SAFI_UNICAST)
1211 zfpm_trigger_update (rn, "rib_uninstall");
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001212
paul718e3742002-12-13 20:15:29 +00001213 redistribute_delete (&rn->p, rib);
1214 if (! RIB_SYSTEM_ROUTE (rib))
1215 rib_uninstall_kernel (rn, rib);
1216 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
1217 }
1218}
1219
Paul Jakma6d691122006-07-27 21:49:00 +00001220static void rib_unlink (struct route_node *, struct rib *);
1221
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001222/*
1223 * rib_can_delete_dest
1224 *
1225 * Returns TRUE if the given dest can be deleted from the table.
1226 */
1227static int
1228rib_can_delete_dest (rib_dest_t *dest)
1229{
1230 if (dest->routes)
1231 {
1232 return 0;
1233 }
1234
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001235 /*
1236 * Don't delete the dest if we have to update the FPM about this
1237 * prefix.
1238 */
1239 if (CHECK_FLAG (dest->flags, RIB_DEST_UPDATE_FPM) ||
1240 CHECK_FLAG (dest->flags, RIB_DEST_SENT_TO_FPM))
1241 return 0;
1242
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001243 return 1;
1244}
1245
1246/*
1247 * rib_gc_dest
1248 *
1249 * Garbage collect the rib dest corresponding to the given route node
1250 * if appropriate.
1251 *
1252 * Returns TRUE if the dest was deleted, FALSE otherwise.
1253 */
1254int
1255rib_gc_dest (struct route_node *rn)
1256{
1257 rib_dest_t *dest;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001258
1259 dest = rib_dest_from_rnode (rn);
1260 if (!dest)
1261 return 0;
1262
1263 if (!rib_can_delete_dest (dest))
1264 return 0;
1265
1266 if (IS_ZEBRA_DEBUG_RIB)
David Lampartere0b0ac82014-04-24 20:22:53 +02001267 rnode_debug (rn, "removing dest from table");
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001268
1269 dest->rnode = NULL;
1270 XFREE (MTYPE_RIB_DEST, dest);
1271 rn->info = NULL;
1272
1273 /*
1274 * Release the one reference that we keep on the route node.
1275 */
1276 route_unlock_node (rn);
1277 return 1;
1278}
1279
paul718e3742002-12-13 20:15:29 +00001280/* Core function for processing routing information base. */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001281static void
1282rib_process (struct route_node *rn)
paul718e3742002-12-13 20:15:29 +00001283{
1284 struct rib *rib;
1285 struct rib *next;
1286 struct rib *fib = NULL;
1287 struct rib *select = NULL;
Paul Jakma6d691122006-07-27 21:49:00 +00001288 struct rib *del = NULL;
pauld753e9e2003-01-22 19:45:50 +00001289 int installed = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001290 struct nexthop *nexthop = NULL, *tnexthop;
1291 int recursing;
Balaji95116332014-10-23 15:25:25 +00001292 rib_table_info_t *info;
1293
paul4d38fdb2005-04-28 17:35:14 +00001294 assert (rn);
Balaji95116332014-10-23 15:25:25 +00001295
1296 info = rn->table->info;
1297
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001298 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00001299 {
paul718e3742002-12-13 20:15:29 +00001300 /* Currently installed rib. */
1301 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Paul Jakma6d691122006-07-27 21:49:00 +00001302 {
1303 assert (fib == NULL);
1304 fib = rib;
1305 }
1306
1307 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1308 * which we need to do do further work with below.
1309 */
1310 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1311 {
1312 if (rib != fib)
1313 {
1314 if (IS_ZEBRA_DEBUG_RIB)
David Lampartere0b0ac82014-04-24 20:22:53 +02001315 rnode_debug (rn, "rn %p, removing rib %p", rn, rib);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001316 rib_unlink (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001317 }
1318 else
1319 del = rib;
1320
1321 continue;
1322 }
paul4d38fdb2005-04-28 17:35:14 +00001323
paul718e3742002-12-13 20:15:29 +00001324 /* Skip unreachable nexthop. */
1325 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +00001326 continue;
paul718e3742002-12-13 20:15:29 +00001327
1328 /* Infinit distance. */
1329 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +00001330 continue;
paul718e3742002-12-13 20:15:29 +00001331
paulaf887b52006-01-18 14:52:52 +00001332 /* Newly selected rib, the common case. */
1333 if (!select)
1334 {
1335 select = rib;
1336 continue;
1337 }
1338
1339 /* filter route selection in following order:
paulaf887b52006-01-18 14:52:52 +00001340 * - connected beats other types
paula8d9c1f2006-01-25 06:31:04 +00001341 * - lower distance beats higher
paulaf887b52006-01-18 14:52:52 +00001342 * - lower metric beats higher for equal distance
1343 * - last, hence oldest, route wins tie break.
1344 */
paula1038a12006-01-30 14:08:51 +00001345
1346 /* Connected routes. Pick the last connected
1347 * route of the set of lowest metric connected routes.
1348 */
paula8d9c1f2006-01-25 06:31:04 +00001349 if (rib->type == ZEBRA_ROUTE_CONNECT)
1350 {
paula1038a12006-01-30 14:08:51 +00001351 if (select->type != ZEBRA_ROUTE_CONNECT
paula8d9c1f2006-01-25 06:31:04 +00001352 || rib->metric <= select->metric)
paula1038a12006-01-30 14:08:51 +00001353 select = rib;
1354 continue;
paula8d9c1f2006-01-25 06:31:04 +00001355 }
1356 else if (select->type == ZEBRA_ROUTE_CONNECT)
1357 continue;
1358
1359 /* higher distance loses */
1360 if (rib->distance > select->distance)
1361 continue;
1362
1363 /* lower wins */
1364 if (rib->distance < select->distance)
1365 {
paulaf887b52006-01-18 14:52:52 +00001366 select = rib;
paula8d9c1f2006-01-25 06:31:04 +00001367 continue;
1368 }
1369
1370 /* metric tie-breaks equal distance */
1371 if (rib->metric <= select->metric)
1372 select = rib;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001373 } /* RNODE_FOREACH_RIB_SAFE */
Denis Ovsienkodc958242007-08-13 16:03:06 +00001374
1375 /* After the cycle is finished, the following pointers will be set:
1376 * select --- the winner RIB entry, if any was found, otherwise NULL
1377 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1378 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1379 * rib --- NULL
1380 */
1381
1382 /* Same RIB entry is selected. Update FIB and finish. */
paul718e3742002-12-13 20:15:29 +00001383 if (select && select == fib)
1384 {
Paul Jakma6d691122006-07-27 21:49:00 +00001385 if (IS_ZEBRA_DEBUG_RIB)
David Lampartere0b0ac82014-04-24 20:22:53 +02001386 rnode_debug (rn, "Updating existing route, select %p, fib %p",
1387 select, fib);
paul718e3742002-12-13 20:15:29 +00001388 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +00001389 {
David Lamparterc048dcc2015-01-12 07:05:06 +01001390 if (info->safi == SAFI_UNICAST)
1391 zfpm_trigger_update (rn, "updating existing route");
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001392
paul4d38fdb2005-04-28 17:35:14 +00001393 redistribute_delete (&rn->p, select);
1394 if (! RIB_SYSTEM_ROUTE (select))
1395 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001396
paul4d38fdb2005-04-28 17:35:14 +00001397 /* Set real nexthop. */
1398 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +00001399
paul4d38fdb2005-04-28 17:35:14 +00001400 if (! RIB_SYSTEM_ROUTE (select))
1401 rib_install_kernel (rn, select);
1402 redistribute_add (&rn->p, select);
1403 }
pauld753e9e2003-01-22 19:45:50 +00001404 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001405 {
1406 /* Housekeeping code to deal with
1407 race conditions in kernel with linux
1408 netlink reporting interface up before IPv4 or IPv6 protocol
1409 is ready to add routes.
1410 This makes sure the routes are IN the kernel.
1411 */
pauld753e9e2003-01-22 19:45:50 +00001412
Christian Frankefa713d92013-07-05 15:35:37 +00001413 for (ALL_NEXTHOPS_RO(select->nexthop, nexthop, tnexthop, recursing))
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001414 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
paul4d38fdb2005-04-28 17:35:14 +00001415 {
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001416 installed = 1;
1417 break;
paul4d38fdb2005-04-28 17:35:14 +00001418 }
1419 if (! installed)
1420 rib_install_kernel (rn, select);
1421 }
Paul Jakma6d691122006-07-27 21:49:00 +00001422 goto end;
paul718e3742002-12-13 20:15:29 +00001423 }
1424
Denis Ovsienkodc958242007-08-13 16:03:06 +00001425 /* At this point we either haven't found the best RIB entry or it is
1426 * different from what we currently intend to flag with SELECTED. In both
1427 * cases, if a RIB block is present in FIB, it should be withdrawn.
1428 */
paul718e3742002-12-13 20:15:29 +00001429 if (fib)
1430 {
Paul Jakma6d691122006-07-27 21:49:00 +00001431 if (IS_ZEBRA_DEBUG_RIB)
David Lampartere0b0ac82014-04-24 20:22:53 +02001432 rnode_debug (rn, "Removing existing route, fib %p", fib);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001433
David Lamparterc048dcc2015-01-12 07:05:06 +01001434 if (info->safi == SAFI_UNICAST)
1435 zfpm_trigger_update (rn, "removing existing route");
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001436
paul718e3742002-12-13 20:15:29 +00001437 redistribute_delete (&rn->p, fib);
1438 if (! RIB_SYSTEM_ROUTE (fib))
1439 rib_uninstall_kernel (rn, fib);
1440 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1441
1442 /* Set real nexthop. */
1443 nexthop_active_update (rn, fib, 1);
1444 }
1445
Denis Ovsienkodc958242007-08-13 16:03:06 +00001446 /* Regardless of some RIB entry being SELECTED or not before, now we can
1447 * tell, that if a new winner exists, FIB is still not updated with this
1448 * data, but ready to be.
1449 */
paul718e3742002-12-13 20:15:29 +00001450 if (select)
1451 {
Paul Jakma6d691122006-07-27 21:49:00 +00001452 if (IS_ZEBRA_DEBUG_RIB)
David Lampartere0b0ac82014-04-24 20:22:53 +02001453 rnode_debug (rn, "Adding route, select %p", select);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001454
David Lamparterc048dcc2015-01-12 07:05:06 +01001455 if (info->safi == SAFI_UNICAST)
1456 zfpm_trigger_update (rn, "new route selected");
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001457
paul718e3742002-12-13 20:15:29 +00001458 /* Set real nexthop. */
1459 nexthop_active_update (rn, select, 1);
1460
1461 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001462 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001463 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1464 redistribute_add (&rn->p, select);
1465 }
paul4d38fdb2005-04-28 17:35:14 +00001466
Paul Jakma6d691122006-07-27 21:49:00 +00001467 /* FIB route was removed, should be deleted */
1468 if (del)
1469 {
1470 if (IS_ZEBRA_DEBUG_RIB)
David Lampartere0b0ac82014-04-24 20:22:53 +02001471 rnode_debug (rn, "Deleting fib %p, rn %p", del, rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001472 rib_unlink (rn, del);
1473 }
paul4d38fdb2005-04-28 17:35:14 +00001474
Paul Jakma6d691122006-07-27 21:49:00 +00001475end:
1476 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lampartere0b0ac82014-04-24 20:22:53 +02001477 rnode_debug (rn, "rn %p dequeued", rn);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001478
1479 /*
1480 * Check if the dest can be deleted now.
1481 */
1482 rib_gc_dest (rn);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001483}
1484
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001485/* Take a list of route_node structs and return 1, if there was a record
1486 * picked from it and processed by rib_process(). Don't process more,
1487 * than one RN record; operate only in the specified sub-queue.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001488 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001489static unsigned int
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001490process_subq (struct list * subq, u_char qindex)
1491{
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001492 struct listnode *lnode = listhead (subq);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001493 struct route_node *rnode;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001494
1495 if (!lnode)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001496 return 0;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001497
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001498 rnode = listgetdata (lnode);
1499 rib_process (rnode);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001500
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001501 if (rnode->info)
1502 UNSET_FLAG (rib_dest_from_rnode (rnode)->flags, RIB_ROUTE_QUEUED (qindex));
1503
Chris Caputo67b94672009-07-18 04:02:26 +00001504#if 0
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001505 else
1506 {
1507 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1508 __func__, rnode, rnode->lock);
1509 zlog_backtrace(LOG_DEBUG);
1510 }
Chris Caputo67b94672009-07-18 04:02:26 +00001511#endif
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001512 route_unlock_node (rnode);
1513 list_delete_node (subq, lnode);
1514 return 1;
1515}
1516
1517/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1518 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1519 * is pointed to the meta queue structure.
1520 */
1521static wq_item_status
1522meta_queue_process (struct work_queue *dummy, void *data)
1523{
1524 struct meta_queue * mq = data;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001525 unsigned i;
1526
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001527 for (i = 0; i < MQ_SIZE; i++)
1528 if (process_subq (mq->subq[i], i))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001529 {
1530 mq->size--;
1531 break;
1532 }
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001533 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1534}
1535
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001536/*
1537 * Map from rib types to queue type (priority) in meta queue
1538 */
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001539static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
1540 [ZEBRA_ROUTE_SYSTEM] = 4,
1541 [ZEBRA_ROUTE_KERNEL] = 0,
1542 [ZEBRA_ROUTE_CONNECT] = 0,
1543 [ZEBRA_ROUTE_STATIC] = 1,
1544 [ZEBRA_ROUTE_RIP] = 2,
1545 [ZEBRA_ROUTE_RIPNG] = 2,
1546 [ZEBRA_ROUTE_OSPF] = 2,
1547 [ZEBRA_ROUTE_OSPF6] = 2,
1548 [ZEBRA_ROUTE_ISIS] = 2,
1549 [ZEBRA_ROUTE_BGP] = 3,
1550 [ZEBRA_ROUTE_HSLS] = 4,
Paul Jakma57345092011-12-25 17:52:09 +01001551 [ZEBRA_ROUTE_BABEL] = 2,
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001552};
1553
1554/* Look into the RN and queue it into one or more priority queues,
1555 * increasing the size for each data push done.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001556 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001557static void
1558rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001559{
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001560 struct rib *rib;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001561
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001562 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001563 {
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001564 u_char qindex = meta_queue_map[rib->type];
1565
1566 /* Invariant: at this point we always have rn->info set. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001567 if (CHECK_FLAG (rib_dest_from_rnode (rn)->flags,
1568 RIB_ROUTE_QUEUED (qindex)))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001569 {
1570 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lampartere0b0ac82014-04-24 20:22:53 +02001571 rnode_debug (rn, "rn %p is already queued in sub-queue %u",
1572 rn, qindex);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001573 continue;
1574 }
1575
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001576 SET_FLAG (rib_dest_from_rnode (rn)->flags, RIB_ROUTE_QUEUED (qindex));
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001577 listnode_add (mq->subq[qindex], rn);
1578 route_lock_node (rn);
1579 mq->size++;
1580
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001581 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lampartere0b0ac82014-04-24 20:22:53 +02001582 rnode_debug (rn, "queued rn %p into sub-queue %u",
1583 rn, qindex);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001584 }
paul4d38fdb2005-04-28 17:35:14 +00001585}
1586
Paul Jakma6d691122006-07-27 21:49:00 +00001587/* Add route_node to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001588static void
Paul Jakma6d691122006-07-27 21:49:00 +00001589rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
paul4d38fdb2005-04-28 17:35:14 +00001590{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001591 assert (zebra && rn);
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001592
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001593 /* Pointless to queue a route_node with no RIB entries to add or remove */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001594 if (!rnode_to_ribs (rn))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001595 {
1596 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1597 __func__, rn, rn->lock);
1598 zlog_backtrace(LOG_DEBUG);
1599 return;
1600 }
1601
1602 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lampartere0b0ac82014-04-24 20:22:53 +02001603 rnode_info (rn, "work queue added");
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001604
1605 assert (zebra);
1606
1607 if (zebra->ribq == NULL)
1608 {
1609 zlog_err ("%s: work_queue does not exist!", __func__);
1610 return;
Paul Jakma6d691122006-07-27 21:49:00 +00001611 }
paul4d38fdb2005-04-28 17:35:14 +00001612
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001613 /*
1614 * The RIB queue should normally be either empty or holding the only
1615 * work_queue_item element. In the latter case this element would
1616 * hold a pointer to the meta queue structure, which must be used to
1617 * actually queue the route nodes to process. So create the MQ
1618 * holder, if necessary, then push the work into it in any case.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001619 * This semantics was introduced after 0.99.9 release.
1620 */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001621 if (!zebra->ribq->items->count)
1622 work_queue_add (zebra->ribq, zebra->mq);
1623
1624 rib_meta_queue_add (zebra->mq, rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001625
1626 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lampartere0b0ac82014-04-24 20:22:53 +02001627 rnode_debug (rn, "rn %p queued", rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001628
1629 return;
paul4d38fdb2005-04-28 17:35:14 +00001630}
1631
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001632/* Create new meta queue.
1633 A destructor function doesn't seem to be necessary here.
1634 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001635static struct meta_queue *
1636meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001637{
1638 struct meta_queue *new;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001639 unsigned i;
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001640
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001641 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1642 assert(new);
1643
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001644 for (i = 0; i < MQ_SIZE; i++)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001645 {
1646 new->subq[i] = list_new ();
1647 assert(new->subq[i]);
1648 }
1649
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001650 return new;
1651}
1652
paul4d38fdb2005-04-28 17:35:14 +00001653/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001654static void
paul4d38fdb2005-04-28 17:35:14 +00001655rib_queue_init (struct zebra_t *zebra)
1656{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001657 assert (zebra);
1658
paul4d38fdb2005-04-28 17:35:14 +00001659 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001660 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001661 {
Paul Jakma6d691122006-07-27 21:49:00 +00001662 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001663 return;
1664 }
1665
1666 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001667 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001668 zebra->ribq->spec.errorfunc = NULL;
paul4d38fdb2005-04-28 17:35:14 +00001669 /* XXX: TODO: These should be runtime configurable via vty */
1670 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001671 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001672
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001673 if (!(zebra->mq = meta_queue_new ()))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001674 {
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001675 zlog_err ("%s: could not initialise meta queue!", __func__);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001676 return;
1677 }
1678 return;
paul718e3742002-12-13 20:15:29 +00001679}
1680
Paul Jakma6d691122006-07-27 21:49:00 +00001681/* RIB updates are processed via a queue of pointers to route_nodes.
1682 *
1683 * The queue length is bounded by the maximal size of the routing table,
1684 * as a route_node will not be requeued, if already queued.
1685 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001686 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1687 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1688 * and then submit route_node to queue for best-path selection later.
1689 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001690 *
1691 * Deleted RIBs are reaped during best-path selection.
1692 *
1693 * rib_addnode
1694 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001695 * |-------->| | best RIB, if required
1696 * | |
1697 * static_install->|->rib_addqueue...... -> rib_process
1698 * | |
1699 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001700 * |-> set RIB_ENTRY_REMOVE |
1701 * rib_delnode (RIB freed)
1702 *
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001703 * The 'info' pointer of a route_node points to a rib_dest_t
1704 * ('dest'). Queueing state for a route_node is kept on the dest. The
1705 * dest is created on-demand by rib_link() and is kept around at least
1706 * as long as there are ribs hanging off it (@see rib_gc_dest()).
Paul Jakma6d691122006-07-27 21:49:00 +00001707 *
1708 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1709 *
1710 * - route_nodes: refcounted by:
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001711 * - dest attached to route_node:
1712 * - managed by: rib_link/rib_gc_dest
Paul Jakma6d691122006-07-27 21:49:00 +00001713 * - route_node processing queue
1714 * - managed by: rib_addqueue, rib_process.
1715 *
1716 */
1717
paul718e3742002-12-13 20:15:29 +00001718/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001719static void
Paul Jakma6d691122006-07-27 21:49:00 +00001720rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001721{
1722 struct rib *head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001723 rib_dest_t *dest;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001724
paul4d38fdb2005-04-28 17:35:14 +00001725 assert (rib && rn);
1726
Paul Jakma6d691122006-07-27 21:49:00 +00001727 if (IS_ZEBRA_DEBUG_RIB)
David Lampartere0b0ac82014-04-24 20:22:53 +02001728 rnode_debug (rn, "rn %p, rib %p", rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001729
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001730 dest = rib_dest_from_rnode (rn);
1731 if (!dest)
Paul Jakma6d691122006-07-27 21:49:00 +00001732 {
1733 if (IS_ZEBRA_DEBUG_RIB)
David Lampartere0b0ac82014-04-24 20:22:53 +02001734 rnode_debug (rn, "adding dest to table");
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001735
1736 dest = XCALLOC (MTYPE_RIB_DEST, sizeof (rib_dest_t));
1737 route_lock_node (rn); /* rn route table reference */
1738 rn->info = dest;
1739 dest->rnode = rn;
1740 }
1741
1742 head = dest->routes;
1743 if (head)
1744 {
Paul Jakma6d691122006-07-27 21:49:00 +00001745 head->prev = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001746 }
paul718e3742002-12-13 20:15:29 +00001747 rib->next = head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001748 dest->routes = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001749 rib_queue_add (&zebrad, rn);
1750}
1751
1752static void
1753rib_addnode (struct route_node *rn, struct rib *rib)
1754{
1755 /* RIB node has been un-removed before route-node is processed.
1756 * route_node must hence already be on the queue for processing..
1757 */
1758 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1759 {
1760 if (IS_ZEBRA_DEBUG_RIB)
David Lampartere0b0ac82014-04-24 20:22:53 +02001761 rnode_debug (rn, "rn %p, un-removed rib %p", rn, rib);
1762
Paul Jakma6d691122006-07-27 21:49:00 +00001763 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1764 return;
1765 }
1766 rib_link (rn, rib);
1767}
1768
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001769/*
1770 * rib_unlink
1771 *
1772 * Detach a rib structure from a route_node.
1773 *
1774 * Note that a call to rib_unlink() should be followed by a call to
1775 * rib_gc_dest() at some point. This allows a rib_dest_t that is no
1776 * longer required to be deleted.
1777 */
Paul Jakma6d691122006-07-27 21:49:00 +00001778static void
1779rib_unlink (struct route_node *rn, struct rib *rib)
1780{
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001781 rib_dest_t *dest;
Paul Jakma6d691122006-07-27 21:49:00 +00001782
1783 assert (rn && rib);
1784
1785 if (IS_ZEBRA_DEBUG_RIB)
David Lampartere0b0ac82014-04-24 20:22:53 +02001786 rnode_debug (rn, "rn %p, rib %p", rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001787
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001788 dest = rib_dest_from_rnode (rn);
1789
Paul Jakma6d691122006-07-27 21:49:00 +00001790 if (rib->next)
1791 rib->next->prev = rib->prev;
1792
1793 if (rib->prev)
1794 rib->prev->next = rib->next;
1795 else
1796 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001797 dest->routes = rib->next;
Paul Jakma6d691122006-07-27 21:49:00 +00001798 }
1799
1800 /* free RIB and nexthops */
Christian Frankefa713d92013-07-05 15:35:37 +00001801 nexthops_free(rib->nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00001802 XFREE (MTYPE_RIB, rib);
1803
paul718e3742002-12-13 20:15:29 +00001804}
1805
paula1ac18c2005-06-28 17:17:12 +00001806static void
paul718e3742002-12-13 20:15:29 +00001807rib_delnode (struct route_node *rn, struct rib *rib)
1808{
Paul Jakma6d691122006-07-27 21:49:00 +00001809 if (IS_ZEBRA_DEBUG_RIB)
David Lampartere0b0ac82014-04-24 20:22:53 +02001810 rnode_debug (rn, "rn %p, rib %p, removing", rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001811 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1812 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001813}
1814
1815int
1816rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001817 struct in_addr *gate, struct in_addr *src,
1818 unsigned int ifindex, u_int32_t vrf_id,
G.Balajicddf3912011-11-26 21:59:32 +04001819 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001820{
1821 struct rib *rib;
1822 struct rib *same = NULL;
1823 struct route_table *table;
1824 struct route_node *rn;
1825 struct nexthop *nexthop;
1826
1827 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04001828 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00001829 if (! table)
1830 return 0;
1831
1832 /* Make it sure prefixlen is applied to the prefix. */
1833 apply_mask_ipv4 (p);
1834
1835 /* Set default distance by route type. */
1836 if (distance == 0)
1837 {
Balaji.G837d16c2012-09-26 14:09:10 +05301838 if ((unsigned)type >= array_size(route_info))
David Lamparter7052f222009-08-27 00:28:28 +02001839 distance = 150;
1840 else
1841 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00001842
1843 /* iBGP distance is 200. */
1844 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1845 distance = 200;
1846 }
1847
1848 /* Lookup route node.*/
1849 rn = route_node_get (table, (struct prefix *) p);
1850
1851 /* If same type of route are installed, treat it as a implicit
1852 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001853 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00001854 {
Paul Jakma6d691122006-07-27 21:49:00 +00001855 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1856 continue;
1857
hassoebf1ead2005-09-21 14:58:20 +00001858 if (rib->type != type)
1859 continue;
1860 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001861 {
1862 same = rib;
1863 break;
1864 }
hassoebf1ead2005-09-21 14:58:20 +00001865 /* Duplicate connected route comes in. */
1866 else if ((nexthop = rib->nexthop) &&
1867 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001868 nexthop->ifindex == ifindex &&
1869 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001870 {
1871 rib->refcnt++;
1872 return 0 ;
1873 }
paul718e3742002-12-13 20:15:29 +00001874 }
1875
1876 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001877 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001878 rib->type = type;
1879 rib->distance = distance;
1880 rib->flags = flags;
1881 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001882 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001883 rib->nexthop_num = 0;
1884 rib->uptime = time (NULL);
1885
1886 /* Nexthop settings. */
1887 if (gate)
1888 {
1889 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001890 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001891 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001892 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001893 }
1894 else
1895 nexthop_ifindex_add (rib, ifindex);
1896
1897 /* If this route is kernel route, set FIB flag to the route. */
1898 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1899 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1900 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1901
1902 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001903 if (IS_ZEBRA_DEBUG_RIB)
1904 zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
paul718e3742002-12-13 20:15:29 +00001905 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001906
paul718e3742002-12-13 20:15:29 +00001907 /* Free implicit route.*/
1908 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001909 {
1910 if (IS_ZEBRA_DEBUG_RIB)
1911 zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001912 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001913 }
paul4d38fdb2005-04-28 17:35:14 +00001914
1915 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001916 return 0;
1917}
1918
Denis Ovsienkodc958242007-08-13 16:03:06 +00001919/* This function dumps the contents of a given RIB entry into
1920 * standard debug log. Calling function name and IP prefix in
1921 * question are passed as 1st and 2nd arguments.
1922 */
1923
David Lamparterf7bf4152013-10-22 17:10:21 +00001924void _rib_dump (const char * func,
1925 union prefix46constptr pp, const struct rib * rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001926{
David Lamparterf7bf4152013-10-22 17:10:21 +00001927 const struct prefix *p = pp.p;
Vincent Bernatfed643f2012-10-23 16:00:42 +00001928 char straddr[INET6_ADDRSTRLEN];
Christian Frankefa713d92013-07-05 15:35:37 +00001929 struct nexthop *nexthop, *tnexthop;
1930 int recursing;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001931
Vincent Bernatfed643f2012-10-23 16:00:42 +00001932 inet_ntop (p->family, &p->u.prefix, straddr, INET6_ADDRSTRLEN);
Christian Frankefa713d92013-07-05 15:35:37 +00001933 zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr, p->prefixlen);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001934 zlog_debug
1935 (
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001936 "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
Denis Ovsienkodc958242007-08-13 16:03:06 +00001937 func,
1938 rib->refcnt,
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001939 (unsigned long) rib->uptime,
Denis Ovsienkodc958242007-08-13 16:03:06 +00001940 rib->type,
1941 rib->table
1942 );
1943 zlog_debug
1944 (
1945 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1946 func,
1947 rib->metric,
1948 rib->distance,
1949 rib->flags,
1950 rib->status
1951 );
1952 zlog_debug
1953 (
1954 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1955 func,
1956 rib->nexthop_num,
1957 rib->nexthop_active_num,
1958 rib->nexthop_fib_num
1959 );
Vincent Bernatfed643f2012-10-23 16:00:42 +00001960
Christian Frankefa713d92013-07-05 15:35:37 +00001961 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1962 {
Vincent Bernatfed643f2012-10-23 16:00:42 +00001963 inet_ntop (p->family, &nexthop->gate, straddr, INET6_ADDRSTRLEN);
Christian Frankefa713d92013-07-05 15:35:37 +00001964 zlog_debug
1965 (
1966 "%s: %s %s with flags %s%s%s",
1967 func,
1968 (recursing ? " NH" : "NH"),
1969 straddr,
1970 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1971 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1972 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1973 );
1974 }
Denis Ovsienkodc958242007-08-13 16:03:06 +00001975 zlog_debug ("%s: dump complete", func);
1976}
1977
1978/* This is an exported helper to rtm_read() to dump the strange
1979 * RIB entry found by rib_lookup_ipv4_route()
1980 */
1981
1982void rib_lookup_and_dump (struct prefix_ipv4 * p)
1983{
1984 struct route_table *table;
1985 struct route_node *rn;
1986 struct rib *rib;
1987 char prefix_buf[INET_ADDRSTRLEN];
1988
1989 /* Lookup table. */
1990 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1991 if (! table)
1992 {
1993 zlog_err ("%s: vrf_table() returned NULL", __func__);
1994 return;
1995 }
1996
1997 inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
1998 /* Scan the RIB table for exactly matching RIB entry. */
1999 rn = route_node_lookup (table, (struct prefix *) p);
2000
2001 /* No route for this prefix. */
2002 if (! rn)
2003 {
2004 zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
2005 return;
2006 }
2007
2008 /* Unlock node. */
2009 route_unlock_node (rn);
2010
2011 /* let's go */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002012 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00002013 {
2014 zlog_debug
2015 (
2016 "%s: rn %p, rib %p: %s, %s",
2017 __func__,
2018 rn,
2019 rib,
2020 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
2021 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
2022 );
David Lamparterf7bf4152013-10-22 17:10:21 +00002023 rib_dump (p, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002024 }
2025}
2026
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002027/* Check if requested address assignment will fail due to another
2028 * route being installed by zebra in FIB already. Take necessary
2029 * actions, if needed: remove such a route from FIB and deSELECT
2030 * corresponding RIB entry. Then put affected RN into RIBQ head.
2031 */
2032void rib_lookup_and_pushup (struct prefix_ipv4 * p)
2033{
2034 struct route_table *table;
2035 struct route_node *rn;
2036 struct rib *rib;
2037 unsigned changed = 0;
2038
2039 if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
2040 {
2041 zlog_err ("%s: vrf_table() returned NULL", __func__);
2042 return;
2043 }
2044
2045 /* No matches would be the simplest case. */
2046 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
2047 return;
2048
2049 /* Unlock node. */
2050 route_unlock_node (rn);
2051
2052 /* Check all RIB entries. In case any changes have to be done, requeue
2053 * the RN into RIBQ head. If the routing message about the new connected
2054 * route (generated by the IP address we are going to assign very soon)
2055 * comes before the RIBQ is processed, the new RIB entry will join
2056 * RIBQ record already on head. This is necessary for proper revalidation
2057 * of the rest of the RIB.
2058 */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002059 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002060 {
2061 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
2062 ! RIB_SYSTEM_ROUTE (rib))
2063 {
2064 changed = 1;
2065 if (IS_ZEBRA_DEBUG_RIB)
2066 {
2067 char buf[INET_ADDRSTRLEN];
2068 inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
2069 zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
David Lamparterf7bf4152013-10-22 17:10:21 +00002070 rib_dump (&rn->p, rib);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002071 }
2072 rib_uninstall (rn, rib);
2073 }
2074 }
2075 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002076 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002077}
2078
paul718e3742002-12-13 20:15:29 +00002079int
G.Balajicddf3912011-11-26 21:59:32 +04002080rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002081{
2082 struct route_table *table;
2083 struct route_node *rn;
2084 struct rib *same;
2085 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00002086
paul718e3742002-12-13 20:15:29 +00002087 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04002088 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00002089 if (! table)
2090 return 0;
G.Balajicddf3912011-11-26 21:59:32 +04002091
paul718e3742002-12-13 20:15:29 +00002092 /* Make it sure prefixlen is applied to the prefix. */
2093 apply_mask_ipv4 (p);
2094
2095 /* Set default distance by route type. */
2096 if (rib->distance == 0)
2097 {
2098 rib->distance = route_info[rib->type].distance;
2099
2100 /* iBGP distance is 200. */
2101 if (rib->type == ZEBRA_ROUTE_BGP
2102 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
2103 rib->distance = 200;
2104 }
2105
2106 /* Lookup route node.*/
2107 rn = route_node_get (table, (struct prefix *) p);
2108
2109 /* If same type of route are installed, treat it as a implicit
2110 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002111 RNODE_FOREACH_RIB (rn, same)
paul718e3742002-12-13 20:15:29 +00002112 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00002113 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00002114 continue;
2115
paul718e3742002-12-13 20:15:29 +00002116 if (same->type == rib->type && same->table == rib->table
2117 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00002118 break;
paul718e3742002-12-13 20:15:29 +00002119 }
paul4d38fdb2005-04-28 17:35:14 +00002120
paul718e3742002-12-13 20:15:29 +00002121 /* If this route is kernel route, set FIB flag to the route. */
2122 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
2123 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2124 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2125
2126 /* Link new rib to node.*/
2127 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002128 if (IS_ZEBRA_DEBUG_RIB)
2129 {
2130 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
2131 __func__, rn, rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00002132 rib_dump (p, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002133 }
paul718e3742002-12-13 20:15:29 +00002134
paul718e3742002-12-13 20:15:29 +00002135 /* Free implicit route.*/
2136 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00002137 {
2138 if (IS_ZEBRA_DEBUG_RIB)
2139 {
2140 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
2141 __func__, rn, same);
David Lamparterf7bf4152013-10-22 17:10:21 +00002142 rib_dump (p, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002143 }
paul4d38fdb2005-04-28 17:35:14 +00002144 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002145 }
paul4d38fdb2005-04-28 17:35:14 +00002146
2147 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002148 return 0;
2149}
2150
hassoebf1ead2005-09-21 14:58:20 +00002151/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002152int
2153rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
G.Balajicddf3912011-11-26 21:59:32 +04002154 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002155{
2156 struct route_table *table;
2157 struct route_node *rn;
2158 struct rib *rib;
2159 struct rib *fib = NULL;
2160 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002161 struct nexthop *nexthop, *tnexthop;
2162 int recursing;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002163 char buf1[INET_ADDRSTRLEN];
2164 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002165
2166 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04002167 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00002168 if (! table)
2169 return 0;
2170
2171 /* Apply mask. */
2172 apply_mask_ipv4 (p);
2173
Christian Frankeb52aef12013-11-27 17:06:15 +00002174 if (IS_ZEBRA_DEBUG_KERNEL)
2175 {
2176 if (gate)
2177 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
2178 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
2179 p->prefixlen,
2180 inet_ntoa (*gate),
2181 ifindex);
2182 else
2183 zlog_debug ("rib_delete_ipv4(): route delete %s/%d ifindex %d",
2184 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
2185 p->prefixlen,
2186 ifindex);
2187 }
paul5ec90d22003-06-19 01:41:37 +00002188
paul718e3742002-12-13 20:15:29 +00002189 /* Lookup route node. */
2190 rn = route_node_lookup (table, (struct prefix *) p);
2191 if (! rn)
2192 {
2193 if (IS_ZEBRA_DEBUG_KERNEL)
2194 {
2195 if (gate)
ajsb6178002004-12-07 21:12:56 +00002196 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002197 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002198 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002199 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002200 ifindex);
2201 else
ajsb6178002004-12-07 21:12:56 +00002202 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002203 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002204 p->prefixlen,
2205 ifindex);
2206 }
2207 return ZEBRA_ERR_RTNOEXIST;
2208 }
2209
2210 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002211 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002212 {
Paul Jakma6d691122006-07-27 21:49:00 +00002213 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2214 continue;
2215
paul718e3742002-12-13 20:15:29 +00002216 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2217 fib = rib;
2218
hassoebf1ead2005-09-21 14:58:20 +00002219 if (rib->type != type)
2220 continue;
2221 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002222 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002223 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002224 if (nexthop->ifindex != ifindex)
2225 continue;
hassoebf1ead2005-09-21 14:58:20 +00002226 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002227 {
hassoebf1ead2005-09-21 14:58:20 +00002228 rib->refcnt--;
2229 route_unlock_node (rn);
2230 route_unlock_node (rn);
2231 return 0;
paul718e3742002-12-13 20:15:29 +00002232 }
hassoebf1ead2005-09-21 14:58:20 +00002233 same = rib;
2234 break;
paul718e3742002-12-13 20:15:29 +00002235 }
hassoebf1ead2005-09-21 14:58:20 +00002236 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002237 else
paul5ec90d22003-06-19 01:41:37 +00002238 {
Christian Frankefa713d92013-07-05 15:35:37 +00002239 if (gate == NULL)
2240 {
2241 same = rib;
2242 break;
2243 }
2244 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2245 if (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate))
2246 {
2247 same = rib;
2248 break;
2249 }
2250 if (same)
2251 break;
2252 }
paul718e3742002-12-13 20:15:29 +00002253 }
paul718e3742002-12-13 20:15:29 +00002254 /* If same type of route can't be found and this message is from
2255 kernel. */
2256 if (! same)
2257 {
2258 if (fib && type == ZEBRA_ROUTE_KERNEL)
2259 {
2260 /* Unset flags. */
2261 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2262 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2263
2264 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2265 }
2266 else
2267 {
2268 if (IS_ZEBRA_DEBUG_KERNEL)
2269 {
2270 if (gate)
ajsb6178002004-12-07 21:12:56 +00002271 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002272 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002273 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002274 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002275 ifindex,
2276 type);
2277 else
ajsb6178002004-12-07 21:12:56 +00002278 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002279 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002280 p->prefixlen,
2281 ifindex,
2282 type);
2283 }
2284 route_unlock_node (rn);
2285 return ZEBRA_ERR_RTNOEXIST;
2286 }
2287 }
paul4d38fdb2005-04-28 17:35:14 +00002288
paul718e3742002-12-13 20:15:29 +00002289 if (same)
2290 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002291
paul718e3742002-12-13 20:15:29 +00002292 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002293 return 0;
2294}
David Lamparter6b0655a2014-06-04 06:53:35 +02002295
paul718e3742002-12-13 20:15:29 +00002296/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002297static void
Everton Marques96bb2662014-07-14 11:19:00 -03002298static_install_ipv4 (safi_t safi, struct prefix *p, struct static_ipv4 *si)
paul718e3742002-12-13 20:15:29 +00002299{
2300 struct rib *rib;
2301 struct route_node *rn;
2302 struct route_table *table;
2303
2304 /* Lookup table. */
Everton Marques96bb2662014-07-14 11:19:00 -03002305 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00002306 if (! table)
2307 return;
2308
2309 /* Lookup existing route */
2310 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002311 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002312 {
2313 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2314 continue;
2315
2316 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2317 break;
2318 }
paul718e3742002-12-13 20:15:29 +00002319
2320 if (rib)
2321 {
2322 /* Same distance static route is there. Update it with new
2323 nexthop. */
paul718e3742002-12-13 20:15:29 +00002324 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002325 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002326 {
2327 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002328 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002329 break;
2330 case STATIC_IPV4_IFNAME:
2331 nexthop_ifname_add (rib, si->gate.ifname);
2332 break;
2333 case STATIC_IPV4_BLACKHOLE:
2334 nexthop_blackhole_add (rib);
2335 break;
paul4d38fdb2005-04-28 17:35:14 +00002336 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002337 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002338 }
2339 else
2340 {
2341 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002342 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2343
paul718e3742002-12-13 20:15:29 +00002344 rib->type = ZEBRA_ROUTE_STATIC;
2345 rib->distance = si->distance;
2346 rib->metric = 0;
Nolan Leakeb0145dd2012-09-13 17:17:31 +00002347 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002348 rib->nexthop_num = 0;
2349
2350 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002351 {
2352 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002353 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002354 break;
2355 case STATIC_IPV4_IFNAME:
2356 nexthop_ifname_add (rib, si->gate.ifname);
2357 break;
2358 case STATIC_IPV4_BLACKHOLE:
2359 nexthop_blackhole_add (rib);
2360 break;
2361 }
paul718e3742002-12-13 20:15:29 +00002362
hasso81dfcaa2003-05-25 19:21:25 +00002363 /* Save the flags of this static routes (reject, blackhole) */
2364 rib->flags = si->flags;
2365
paul718e3742002-12-13 20:15:29 +00002366 /* Link this rib to the tree. */
2367 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002368 }
2369}
2370
paula1ac18c2005-06-28 17:17:12 +00002371static int
paul718e3742002-12-13 20:15:29 +00002372static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2373{
2374 if (nexthop->type == NEXTHOP_TYPE_IPV4
2375 && si->type == STATIC_IPV4_GATEWAY
2376 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2377 return 1;
2378 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2379 && si->type == STATIC_IPV4_IFNAME
2380 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2381 return 1;
paul595db7f2003-05-25 21:35:06 +00002382 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2383 && si->type == STATIC_IPV4_BLACKHOLE)
2384 return 1;
paule8e19462006-01-19 20:16:55 +00002385 return 0;
paul718e3742002-12-13 20:15:29 +00002386}
2387
2388/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002389static void
Everton Marques96bb2662014-07-14 11:19:00 -03002390static_uninstall_ipv4 (safi_t safi, struct prefix *p, struct static_ipv4 *si)
paul718e3742002-12-13 20:15:29 +00002391{
2392 struct route_node *rn;
2393 struct rib *rib;
2394 struct nexthop *nexthop;
2395 struct route_table *table;
2396
2397 /* Lookup table. */
Everton Marques96bb2662014-07-14 11:19:00 -03002398 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00002399 if (! table)
2400 return;
paul4d38fdb2005-04-28 17:35:14 +00002401
paul718e3742002-12-13 20:15:29 +00002402 /* Lookup existing route with type and distance. */
2403 rn = route_node_lookup (table, p);
2404 if (! rn)
2405 return;
2406
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002407 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002408 {
2409 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2410 continue;
2411
2412 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2413 break;
2414 }
paul718e3742002-12-13 20:15:29 +00002415
2416 if (! rib)
2417 {
2418 route_unlock_node (rn);
2419 return;
2420 }
2421
2422 /* Lookup nexthop. */
2423 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2424 if (static_ipv4_nexthop_same (nexthop, si))
2425 break;
2426
2427 /* Can't find nexthop. */
2428 if (! nexthop)
2429 {
2430 route_unlock_node (rn);
2431 return;
2432 }
2433
2434 /* Check nexthop. */
2435 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002436 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002437 else
2438 {
paul6baeb982003-10-28 03:47:15 +00002439 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2440 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002441 nexthop_delete (rib, nexthop);
2442 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002443 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002444 }
paul718e3742002-12-13 20:15:29 +00002445 /* Unlock node. */
2446 route_unlock_node (rn);
2447}
2448
paul718e3742002-12-13 20:15:29 +00002449int
Everton Marques96bb2662014-07-14 11:19:00 -03002450static_add_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate,
2451 const char *ifname, u_char flags, u_char distance,
2452 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002453{
2454 u_char type = 0;
2455 struct route_node *rn;
2456 struct static_ipv4 *si;
2457 struct static_ipv4 *pp;
2458 struct static_ipv4 *cp;
2459 struct static_ipv4 *update = NULL;
2460 struct route_table *stable;
2461
2462 /* Lookup table. */
Everton Marques96bb2662014-07-14 11:19:00 -03002463 stable = vrf_static_table (AFI_IP, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002464 if (! stable)
2465 return -1;
2466
2467 /* Lookup static route prefix. */
2468 rn = route_node_get (stable, p);
2469
2470 /* Make flags. */
2471 if (gate)
2472 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002473 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002474 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002475 else
2476 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002477
2478 /* Do nothing if there is a same static route. */
2479 for (si = rn->info; si; si = si->next)
2480 {
2481 if (type == si->type
2482 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2483 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2484 {
2485 if (distance == si->distance)
2486 {
2487 route_unlock_node (rn);
2488 return 0;
2489 }
2490 else
2491 update = si;
2492 }
2493 }
2494
Paul Jakma3c0755d2006-12-08 00:53:14 +00002495 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002496 if (update)
Everton Marques96bb2662014-07-14 11:19:00 -03002497 static_delete_ipv4_safi (safi, p, gate, ifname, update->distance, vrf_id);
paul718e3742002-12-13 20:15:29 +00002498
2499 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002500 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
paul718e3742002-12-13 20:15:29 +00002501
2502 si->type = type;
2503 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002504 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002505
2506 if (gate)
2507 si->gate.ipv4 = *gate;
2508 if (ifname)
2509 si->gate.ifname = XSTRDUP (0, ifname);
2510
2511 /* Add new static route information to the tree with sort by
2512 distance value and gateway address. */
2513 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2514 {
2515 if (si->distance < cp->distance)
2516 break;
2517 if (si->distance > cp->distance)
2518 continue;
2519 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2520 {
2521 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2522 break;
2523 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2524 continue;
2525 }
2526 }
2527
2528 /* Make linked list. */
2529 if (pp)
2530 pp->next = si;
2531 else
2532 rn->info = si;
2533 if (cp)
2534 cp->prev = si;
2535 si->prev = pp;
2536 si->next = cp;
2537
2538 /* Install into rib. */
Everton Marques96bb2662014-07-14 11:19:00 -03002539 static_install_ipv4 (safi, p, si);
paul718e3742002-12-13 20:15:29 +00002540
2541 return 1;
2542}
2543
paul718e3742002-12-13 20:15:29 +00002544int
Everton Marques96bb2662014-07-14 11:19:00 -03002545static_delete_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate,
2546 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002547{
2548 u_char type = 0;
2549 struct route_node *rn;
2550 struct static_ipv4 *si;
2551 struct route_table *stable;
2552
2553 /* Lookup table. */
Everton Marques96bb2662014-07-14 11:19:00 -03002554 stable = vrf_static_table (AFI_IP, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002555 if (! stable)
2556 return -1;
2557
2558 /* Lookup static route prefix. */
2559 rn = route_node_lookup (stable, p);
2560 if (! rn)
2561 return 0;
2562
2563 /* Make flags. */
2564 if (gate)
2565 type = STATIC_IPV4_GATEWAY;
2566 else if (ifname)
2567 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002568 else
2569 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002570
2571 /* Find same static route is the tree */
2572 for (si = rn->info; si; si = si->next)
2573 if (type == si->type
2574 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2575 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2576 break;
2577
2578 /* Can't find static route. */
2579 if (! si)
2580 {
2581 route_unlock_node (rn);
2582 return 0;
2583 }
2584
2585 /* Install into rib. */
Everton Marques96bb2662014-07-14 11:19:00 -03002586 static_uninstall_ipv4 (safi, p, si);
paul718e3742002-12-13 20:15:29 +00002587
2588 /* Unlink static route from linked list. */
2589 if (si->prev)
2590 si->prev->next = si->next;
2591 else
2592 rn->info = si->next;
2593 if (si->next)
2594 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002595 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002596
2597 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002598 if (ifname)
2599 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002600 XFREE (MTYPE_STATIC_IPV4, si);
2601
paul143a3852003-09-29 20:06:13 +00002602 route_unlock_node (rn);
2603
paul718e3742002-12-13 20:15:29 +00002604 return 1;
2605}
2606
paul718e3742002-12-13 20:15:29 +00002607#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00002608static int
paul718e3742002-12-13 20:15:29 +00002609rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2610 struct in6_addr *gate, unsigned int ifindex, int table)
2611{
hasso726f9b22003-05-25 21:04:54 +00002612 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2613#if defined (MUSICA) || defined (LINUX)
2614 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2615 if (p->prefixlen == 96)
2616 return 0;
2617#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00002618 return 1;
hasso726f9b22003-05-25 21:04:54 +00002619 }
paul718e3742002-12-13 20:15:29 +00002620 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
2621 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
2622 {
2623 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
2624 return 1;
2625 }
2626 return 0;
2627}
2628
2629int
2630rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00002631 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
G.Balajif768f362011-11-26 22:10:39 +04002632 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002633{
2634 struct rib *rib;
2635 struct rib *same = NULL;
2636 struct route_table *table;
2637 struct route_node *rn;
2638 struct nexthop *nexthop;
2639
paul718e3742002-12-13 20:15:29 +00002640 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002641 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002642 if (! table)
2643 return 0;
2644
2645 /* Make sure mask is applied. */
2646 apply_mask_ipv6 (p);
2647
2648 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002649 if (!distance)
2650 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002651
2652 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2653 distance = 200;
2654
2655 /* Filter bogus route. */
2656 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
2657 return 0;
2658
2659 /* Lookup route node.*/
2660 rn = route_node_get (table, (struct prefix *) p);
2661
2662 /* If same type of route are installed, treat it as a implicit
2663 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002664 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002665 {
Paul Jakma6d691122006-07-27 21:49:00 +00002666 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2667 continue;
2668
hassoebf1ead2005-09-21 14:58:20 +00002669 if (rib->type != type)
2670 continue;
2671 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002672 {
2673 same = rib;
paul718e3742002-12-13 20:15:29 +00002674 break;
2675 }
hassoebf1ead2005-09-21 14:58:20 +00002676 else if ((nexthop = rib->nexthop) &&
2677 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2678 nexthop->ifindex == ifindex)
2679 {
2680 rib->refcnt++;
2681 return 0;
2682 }
paul718e3742002-12-13 20:15:29 +00002683 }
2684
2685 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002686 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2687
paul718e3742002-12-13 20:15:29 +00002688 rib->type = type;
2689 rib->distance = distance;
2690 rib->flags = flags;
2691 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00002692 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00002693 rib->nexthop_num = 0;
2694 rib->uptime = time (NULL);
2695
2696 /* Nexthop settings. */
2697 if (gate)
2698 {
2699 if (ifindex)
2700 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2701 else
2702 nexthop_ipv6_add (rib, gate);
2703 }
2704 else
2705 nexthop_ifindex_add (rib, ifindex);
2706
2707 /* If this route is kernel route, set FIB flag to the route. */
2708 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2709 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2710 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2711
2712 /* Link new rib to node.*/
2713 rib_addnode (rn, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002714 if (IS_ZEBRA_DEBUG_RIB)
2715 {
2716 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
2717 __func__, rn, rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00002718 rib_dump (p, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002719 }
paul718e3742002-12-13 20:15:29 +00002720
paul718e3742002-12-13 20:15:29 +00002721 /* Free implicit route.*/
2722 if (same)
Vincent Bernatfed643f2012-10-23 16:00:42 +00002723 {
2724 if (IS_ZEBRA_DEBUG_RIB)
2725 {
2726 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
2727 __func__, rn, same);
David Lamparterf7bf4152013-10-22 17:10:21 +00002728 rib_dump (p, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002729 }
paul4d38fdb2005-04-28 17:35:14 +00002730 rib_delnode (rn, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002731 }
paul4d38fdb2005-04-28 17:35:14 +00002732
2733 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002734 return 0;
2735}
2736
hassoebf1ead2005-09-21 14:58:20 +00002737/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002738int
2739rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
G.Balajif768f362011-11-26 22:10:39 +04002740 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002741{
2742 struct route_table *table;
2743 struct route_node *rn;
2744 struct rib *rib;
2745 struct rib *fib = NULL;
2746 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002747 struct nexthop *nexthop, *tnexthop;
2748 int recursing;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002749 char buf1[INET6_ADDRSTRLEN];
2750 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002751
2752 /* Apply mask. */
2753 apply_mask_ipv6 (p);
2754
2755 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002756 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002757 if (! table)
2758 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002759
paul718e3742002-12-13 20:15:29 +00002760 /* Lookup route node. */
2761 rn = route_node_lookup (table, (struct prefix *) p);
2762 if (! rn)
2763 {
2764 if (IS_ZEBRA_DEBUG_KERNEL)
2765 {
2766 if (gate)
ajsb6178002004-12-07 21:12:56 +00002767 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002768 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002769 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002770 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002771 ifindex);
2772 else
ajsb6178002004-12-07 21:12:56 +00002773 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002774 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002775 p->prefixlen,
2776 ifindex);
2777 }
2778 return ZEBRA_ERR_RTNOEXIST;
2779 }
2780
2781 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002782 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002783 {
Paul Jakma6d691122006-07-27 21:49:00 +00002784 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2785 continue;
2786
paul718e3742002-12-13 20:15:29 +00002787 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2788 fib = rib;
2789
hassoebf1ead2005-09-21 14:58:20 +00002790 if (rib->type != type)
2791 continue;
2792 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002793 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002794 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002795 if (nexthop->ifindex != ifindex)
2796 continue;
hassoebf1ead2005-09-21 14:58:20 +00002797 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002798 {
hassoebf1ead2005-09-21 14:58:20 +00002799 rib->refcnt--;
2800 route_unlock_node (rn);
2801 route_unlock_node (rn);
2802 return 0;
paul718e3742002-12-13 20:15:29 +00002803 }
hassoebf1ead2005-09-21 14:58:20 +00002804 same = rib;
2805 break;
paul718e3742002-12-13 20:15:29 +00002806 }
hassoebf1ead2005-09-21 14:58:20 +00002807 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002808 else
2809 {
2810 if (gate == NULL)
2811 {
2812 same = rib;
2813 break;
2814 }
2815 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2816 if (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate))
2817 {
2818 same = rib;
2819 break;
2820 }
2821 if (same)
2822 break;
2823 }
paul718e3742002-12-13 20:15:29 +00002824 }
2825
2826 /* If same type of route can't be found and this message is from
2827 kernel. */
2828 if (! same)
2829 {
2830 if (fib && type == ZEBRA_ROUTE_KERNEL)
2831 {
2832 /* Unset flags. */
2833 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2834 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2835
2836 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2837 }
2838 else
2839 {
2840 if (IS_ZEBRA_DEBUG_KERNEL)
2841 {
2842 if (gate)
ajsb6178002004-12-07 21:12:56 +00002843 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002844 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002845 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002846 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002847 ifindex,
2848 type);
2849 else
ajsb6178002004-12-07 21:12:56 +00002850 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002851 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002852 p->prefixlen,
2853 ifindex,
2854 type);
2855 }
2856 route_unlock_node (rn);
2857 return ZEBRA_ERR_RTNOEXIST;
2858 }
2859 }
2860
2861 if (same)
2862 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002863
paul718e3742002-12-13 20:15:29 +00002864 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002865 return 0;
2866}
David Lamparter6b0655a2014-06-04 06:53:35 +02002867
paul718e3742002-12-13 20:15:29 +00002868/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002869static void
paul718e3742002-12-13 20:15:29 +00002870static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2871{
2872 struct rib *rib;
2873 struct route_table *table;
2874 struct route_node *rn;
2875
2876 /* Lookup table. */
2877 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2878 if (! table)
2879 return;
2880
2881 /* Lookup existing route */
2882 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002883 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002884 {
2885 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2886 continue;
2887
2888 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2889 break;
2890 }
paul718e3742002-12-13 20:15:29 +00002891
2892 if (rib)
2893 {
2894 /* Same distance static route is there. Update it with new
2895 nexthop. */
paul718e3742002-12-13 20:15:29 +00002896 route_unlock_node (rn);
2897
2898 switch (si->type)
2899 {
2900 case STATIC_IPV6_GATEWAY:
2901 nexthop_ipv6_add (rib, &si->ipv6);
2902 break;
2903 case STATIC_IPV6_IFNAME:
2904 nexthop_ifname_add (rib, si->ifname);
2905 break;
2906 case STATIC_IPV6_GATEWAY_IFNAME:
2907 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2908 break;
2909 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002910 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002911 }
2912 else
2913 {
2914 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002915 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2916
paul718e3742002-12-13 20:15:29 +00002917 rib->type = ZEBRA_ROUTE_STATIC;
2918 rib->distance = si->distance;
2919 rib->metric = 0;
Dinesh G Duttd1b09912014-09-30 12:54:13 -07002920 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002921 rib->nexthop_num = 0;
2922
2923 switch (si->type)
2924 {
2925 case STATIC_IPV6_GATEWAY:
2926 nexthop_ipv6_add (rib, &si->ipv6);
2927 break;
2928 case STATIC_IPV6_IFNAME:
2929 nexthop_ifname_add (rib, si->ifname);
2930 break;
2931 case STATIC_IPV6_GATEWAY_IFNAME:
2932 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2933 break;
2934 }
2935
hasso81dfcaa2003-05-25 19:21:25 +00002936 /* Save the flags of this static routes (reject, blackhole) */
2937 rib->flags = si->flags;
2938
paul718e3742002-12-13 20:15:29 +00002939 /* Link this rib to the tree. */
2940 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002941 }
2942}
2943
paula1ac18c2005-06-28 17:17:12 +00002944static int
paul718e3742002-12-13 20:15:29 +00002945static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2946{
2947 if (nexthop->type == NEXTHOP_TYPE_IPV6
2948 && si->type == STATIC_IPV6_GATEWAY
2949 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2950 return 1;
2951 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2952 && si->type == STATIC_IPV6_IFNAME
2953 && strcmp (nexthop->ifname, si->ifname) == 0)
2954 return 1;
2955 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2956 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2957 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2958 && strcmp (nexthop->ifname, si->ifname) == 0)
2959 return 1;
paule8e19462006-01-19 20:16:55 +00002960 return 0;
paul718e3742002-12-13 20:15:29 +00002961}
2962
paula1ac18c2005-06-28 17:17:12 +00002963static void
paul718e3742002-12-13 20:15:29 +00002964static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2965{
2966 struct route_table *table;
2967 struct route_node *rn;
2968 struct rib *rib;
2969 struct nexthop *nexthop;
2970
2971 /* Lookup table. */
2972 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2973 if (! table)
2974 return;
2975
2976 /* Lookup existing route with type and distance. */
2977 rn = route_node_lookup (table, (struct prefix *) p);
2978 if (! rn)
2979 return;
2980
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002981 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002982 {
2983 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2984 continue;
2985
2986 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2987 break;
2988 }
2989
paul718e3742002-12-13 20:15:29 +00002990 if (! rib)
2991 {
2992 route_unlock_node (rn);
2993 return;
2994 }
2995
2996 /* Lookup nexthop. */
2997 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2998 if (static_ipv6_nexthop_same (nexthop, si))
2999 break;
3000
3001 /* Can't find nexthop. */
3002 if (! nexthop)
3003 {
3004 route_unlock_node (rn);
3005 return;
3006 }
3007
3008 /* Check nexthop. */
3009 if (rib->nexthop_num == 1)
3010 {
3011 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003012 }
3013 else
3014 {
paul6baeb982003-10-28 03:47:15 +00003015 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
3016 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00003017 nexthop_delete (rib, nexthop);
3018 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00003019 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003020 }
paul718e3742002-12-13 20:15:29 +00003021 /* Unlock node. */
3022 route_unlock_node (rn);
3023}
3024
3025/* Add static route into static route configuration. */
3026int
3027static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00003028 const char *ifname, u_char flags, u_char distance,
3029 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00003030{
3031 struct route_node *rn;
3032 struct static_ipv6 *si;
3033 struct static_ipv6 *pp;
3034 struct static_ipv6 *cp;
3035 struct route_table *stable;
3036
3037 /* Lookup table. */
3038 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
3039 if (! stable)
3040 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00003041
3042 if (!gate &&
3043 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
3044 return -1;
3045
3046 if (!ifname &&
3047 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
3048 return -1;
paul718e3742002-12-13 20:15:29 +00003049
3050 /* Lookup static route prefix. */
3051 rn = route_node_get (stable, p);
3052
3053 /* Do nothing if there is a same static route. */
3054 for (si = rn->info; si; si = si->next)
3055 {
3056 if (distance == si->distance
3057 && type == si->type
3058 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
3059 && (! ifname || strcmp (ifname, si->ifname) == 0))
3060 {
3061 route_unlock_node (rn);
3062 return 0;
3063 }
3064 }
3065
3066 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07003067 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
paul718e3742002-12-13 20:15:29 +00003068
3069 si->type = type;
3070 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00003071 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00003072
3073 switch (type)
3074 {
3075 case STATIC_IPV6_GATEWAY:
3076 si->ipv6 = *gate;
3077 break;
3078 case STATIC_IPV6_IFNAME:
3079 si->ifname = XSTRDUP (0, ifname);
3080 break;
3081 case STATIC_IPV6_GATEWAY_IFNAME:
3082 si->ipv6 = *gate;
3083 si->ifname = XSTRDUP (0, ifname);
3084 break;
3085 }
3086
3087 /* Add new static route information to the tree with sort by
3088 distance value and gateway address. */
3089 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
3090 {
3091 if (si->distance < cp->distance)
3092 break;
3093 if (si->distance > cp->distance)
3094 continue;
3095 }
3096
3097 /* Make linked list. */
3098 if (pp)
3099 pp->next = si;
3100 else
3101 rn->info = si;
3102 if (cp)
3103 cp->prev = si;
3104 si->prev = pp;
3105 si->next = cp;
3106
3107 /* Install into rib. */
3108 static_install_ipv6 (p, si);
3109
3110 return 1;
3111}
3112
3113/* Delete static route from static route configuration. */
3114int
3115static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00003116 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00003117{
3118 struct route_node *rn;
3119 struct static_ipv6 *si;
3120 struct route_table *stable;
3121
3122 /* Lookup table. */
3123 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
3124 if (! stable)
3125 return -1;
3126
3127 /* Lookup static route prefix. */
3128 rn = route_node_lookup (stable, p);
3129 if (! rn)
3130 return 0;
3131
3132 /* Find same static route is the tree */
3133 for (si = rn->info; si; si = si->next)
3134 if (distance == si->distance
3135 && type == si->type
3136 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
3137 && (! ifname || strcmp (ifname, si->ifname) == 0))
3138 break;
3139
3140 /* Can't find static route. */
3141 if (! si)
3142 {
3143 route_unlock_node (rn);
3144 return 0;
3145 }
3146
3147 /* Install into rib. */
3148 static_uninstall_ipv6 (p, si);
3149
3150 /* Unlink static route from linked list. */
3151 if (si->prev)
3152 si->prev->next = si->next;
3153 else
3154 rn->info = si->next;
3155 if (si->next)
3156 si->next->prev = si->prev;
3157
3158 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00003159 if (ifname)
3160 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00003161 XFREE (MTYPE_STATIC_IPV6, si);
3162
3163 return 1;
3164}
3165#endif /* HAVE_IPV6 */
David Lamparter6b0655a2014-06-04 06:53:35 +02003166
paul718e3742002-12-13 20:15:29 +00003167/* RIB update function. */
3168void
paula1ac18c2005-06-28 17:17:12 +00003169rib_update (void)
paul718e3742002-12-13 20:15:29 +00003170{
3171 struct route_node *rn;
3172 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00003173
paul718e3742002-12-13 20:15:29 +00003174 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
3175 if (table)
3176 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003177 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003178 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003179
3180 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
3181 if (table)
3182 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003183 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003184 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003185}
3186
David Lamparter6b0655a2014-06-04 06:53:35 +02003187
paul718e3742002-12-13 20:15:29 +00003188/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00003189static void
paul718e3742002-12-13 20:15:29 +00003190rib_weed_table (struct route_table *table)
3191{
3192 struct route_node *rn;
3193 struct rib *rib;
3194 struct rib *next;
3195
3196 if (table)
3197 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003198 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003199 {
Paul Jakma6d691122006-07-27 21:49:00 +00003200 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3201 continue;
3202
paulb21b19c2003-06-15 01:28:29 +00003203 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00003204 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00003205 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003206 }
3207}
3208
3209/* Delete all routes from non main table. */
3210void
paula1ac18c2005-06-28 17:17:12 +00003211rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00003212{
3213 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3214 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3215}
David Lamparter6b0655a2014-06-04 06:53:35 +02003216
paul718e3742002-12-13 20:15:29 +00003217/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00003218static void
paul718e3742002-12-13 20:15:29 +00003219rib_sweep_table (struct route_table *table)
3220{
3221 struct route_node *rn;
3222 struct rib *rib;
3223 struct rib *next;
3224 int ret = 0;
3225
3226 if (table)
3227 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003228 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003229 {
Paul Jakma6d691122006-07-27 21:49:00 +00003230 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3231 continue;
3232
paul718e3742002-12-13 20:15:29 +00003233 if (rib->type == ZEBRA_ROUTE_KERNEL &&
3234 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
3235 {
3236 ret = rib_uninstall_kernel (rn, rib);
3237 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00003238 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003239 }
3240 }
3241}
3242
3243/* Sweep all RIB tables. */
3244void
paula1ac18c2005-06-28 17:17:12 +00003245rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00003246{
3247 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3248 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3249}
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003250
3251/* Remove specific by protocol routes from 'table'. */
3252static unsigned long
3253rib_score_proto_table (u_char proto, struct route_table *table)
3254{
3255 struct route_node *rn;
3256 struct rib *rib;
3257 struct rib *next;
3258 unsigned long n = 0;
3259
3260 if (table)
3261 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003262 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003263 {
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003264 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3265 continue;
3266 if (rib->type == proto)
3267 {
3268 rib_delnode (rn, rib);
3269 n++;
3270 }
3271 }
3272
3273 return n;
3274}
3275
3276/* Remove specific by protocol routes. */
3277unsigned long
3278rib_score_proto (u_char proto)
3279{
3280 return rib_score_proto_table (proto, vrf_table (AFI_IP, SAFI_UNICAST, 0))
3281 +rib_score_proto_table (proto, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3282}
3283
paul718e3742002-12-13 20:15:29 +00003284/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00003285static void
paul718e3742002-12-13 20:15:29 +00003286rib_close_table (struct route_table *table)
3287{
3288 struct route_node *rn;
David Lamparterc048dcc2015-01-12 07:05:06 +01003289 rib_table_info_t *info = table->info;
paul718e3742002-12-13 20:15:29 +00003290 struct rib *rib;
3291
3292 if (table)
3293 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003294 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00003295 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003296 if (!CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
3297 continue;
3298
David Lamparterc048dcc2015-01-12 07:05:06 +01003299 if (info->safi == SAFI_UNICAST)
3300 zfpm_trigger_update (rn, NULL);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00003301
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003302 if (! RIB_SYSTEM_ROUTE (rib))
3303 rib_uninstall_kernel (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00003304 }
paul718e3742002-12-13 20:15:29 +00003305}
3306
3307/* Close all RIB tables. */
3308void
paula1ac18c2005-06-28 17:17:12 +00003309rib_close (void)
paul718e3742002-12-13 20:15:29 +00003310{
3311 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3312 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3313}
David Lamparter6b0655a2014-06-04 06:53:35 +02003314
paul718e3742002-12-13 20:15:29 +00003315/* Routing information base initialize. */
3316void
paula1ac18c2005-06-28 17:17:12 +00003317rib_init (void)
paul718e3742002-12-13 20:15:29 +00003318{
paul4d38fdb2005-04-28 17:35:14 +00003319 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00003320 /* VRF initialization. */
3321 vrf_init ();
3322}
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003323
3324/*
3325 * vrf_id_get_next
3326 *
3327 * Get the first vrf id that is greater than the given vrf id if any.
3328 *
3329 * Returns TRUE if a vrf id was found, FALSE otherwise.
3330 */
3331static inline int
3332vrf_id_get_next (uint32_t id, uint32_t *next_id_p)
3333{
3334 while (++id < vector_active (vrf_vector))
3335 {
3336 if (vrf_lookup (id))
3337 {
3338 *next_id_p = id;
3339 return 1;
3340 }
3341 }
3342
3343 return 0;
3344}
3345
3346/*
3347 * rib_tables_iter_next
3348 *
3349 * Returns the next table in the iteration.
3350 */
3351struct route_table *
3352rib_tables_iter_next (rib_tables_iter_t *iter)
3353{
3354 struct route_table *table;
3355
3356 /*
3357 * Array that helps us go over all AFI/SAFI combinations via one
3358 * index.
3359 */
3360 static struct {
3361 afi_t afi;
3362 safi_t safi;
3363 } afi_safis[] = {
3364 { AFI_IP, SAFI_UNICAST },
3365 { AFI_IP, SAFI_MULTICAST },
3366 { AFI_IP6, SAFI_UNICAST },
3367 { AFI_IP6, SAFI_MULTICAST },
3368 };
3369
3370 table = NULL;
3371
3372 switch (iter->state)
3373 {
3374
3375 case RIB_TABLES_ITER_S_INIT:
3376 iter->vrf_id = 0;
3377 iter->afi_safi_ix = -1;
3378
3379 /* Fall through */
3380
3381 case RIB_TABLES_ITER_S_ITERATING:
3382 iter->afi_safi_ix++;
3383 while (1)
3384 {
3385
3386 while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
3387 {
3388 table = vrf_table (afi_safis[iter->afi_safi_ix].afi,
3389 afi_safis[iter->afi_safi_ix].safi,
3390 iter->vrf_id);
3391 if (table)
3392 break;
3393
3394 iter->afi_safi_ix++;
3395 }
3396
3397 /*
3398 * Found another table in this vrf.
3399 */
3400 if (table)
3401 break;
3402
3403 /*
3404 * Done with all tables in the current vrf, go to the next
3405 * one.
3406 */
3407 if (!vrf_id_get_next (iter->vrf_id, &iter->vrf_id))
3408 break;
3409
3410 iter->afi_safi_ix = 0;
3411 }
3412
3413 break;
3414
3415 case RIB_TABLES_ITER_S_DONE:
3416 return NULL;
3417 }
3418
3419 if (table)
3420 iter->state = RIB_TABLES_ITER_S_ITERATING;
3421 else
3422 iter->state = RIB_TABLES_ITER_S_DONE;
3423
3424 return table;
3425}