blob: f4a915542058bfe2226a0bef4ddcdb742d753e0d [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 Lamparter94813742014-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 Lamparterab2ba612015-01-22 19:02:13 +010092 rib_table_info_t *info = rn->table->info;
93
David Lamparter94813742014-04-24 20:22:53 +020094 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
95 bptr = buf + strlen(buf);
David Lamparterab2ba612015-01-22 19:02:13 +010096 snprintf(bptr, buf + sizeof(buf) - bptr, "/%d%s", rn->p.prefixlen,
97 info->safi == SAFI_MULTICAST ? " (MRIB)" : "");
David Lamparter94813742014-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 *
722rib_match_ipv4 (struct in_addr addr)
723{
Everton Marques83d71122014-09-19 16:39:34 -0300724 return rib_match_ipv4_safi (addr, SAFI_UNICAST, 1);
paul718e3742002-12-13 20:15:29 +0000725}
726
727struct rib *
Everton Marques83d71122014-09-19 16:39:34 -0300728rib_match_ipv4_safi (struct in_addr addr, safi_t safi, int skip_bgp)
Everton Marques3dea1782014-09-22 19:35:51 -0300729{
730 struct route_table *table;
731 struct route_node *rn;
732 struct rib *match;
733 struct nexthop *newhop, *tnewhop;
734 int recursing;
735
736 /* Lookup table. */
737 table = vrf_table (AFI_IP, safi, 0);
738 if (! table)
739 return 0;
740
741 rn = route_node_match_ipv4 (table, &addr);
742
743 while (rn)
744 {
745 route_unlock_node (rn);
746
747 /* Pick up selected route. */
748 RNODE_FOREACH_RIB (rn, match)
749 {
750 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
751 continue;
752 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
753 break;
754 }
755
756 /* If there is no selected route or matched route is EGP, go up
757 tree. */
Everton Marques83d71122014-09-19 16:39:34 -0300758 if (!match || (skip_bgp && (match->type == ZEBRA_ROUTE_BGP)))
Everton Marques3dea1782014-09-22 19:35:51 -0300759 {
760 do {
761 rn = rn->parent;
762 } while (rn && rn->info == NULL);
763 if (rn)
764 route_lock_node (rn);
765 }
766 else
767 {
768 if (match->type == ZEBRA_ROUTE_CONNECT)
769 /* Directly point connected route. */
770 return match;
771 else
772 {
773 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
774 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
775 return match;
776 return NULL;
777 }
778 }
779 }
780 return NULL;
781}
782
783struct rib *
paul718e3742002-12-13 20:15:29 +0000784rib_lookup_ipv4 (struct prefix_ipv4 *p)
785{
786 struct route_table *table;
787 struct route_node *rn;
788 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000789 struct nexthop *nexthop, *tnexthop;
790 int recursing;
paul718e3742002-12-13 20:15:29 +0000791
792 /* Lookup table. */
793 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
794 if (! table)
795 return 0;
796
797 rn = route_node_lookup (table, (struct prefix *) p);
798
799 /* No route for this prefix. */
800 if (! rn)
801 return NULL;
802
803 /* Unlock node. */
804 route_unlock_node (rn);
805
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000806 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100807 {
808 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
809 continue;
810 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
811 break;
812 }
paul718e3742002-12-13 20:15:29 +0000813
814 if (! match || match->type == ZEBRA_ROUTE_BGP)
815 return NULL;
816
817 if (match->type == ZEBRA_ROUTE_CONNECT)
818 return match;
819
Christian Frankefa713d92013-07-05 15:35:37 +0000820 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +0000821 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
822 return match;
823
824 return NULL;
825}
826
Denis Ovsienkodc958242007-08-13 16:03:06 +0000827/*
828 * This clone function, unlike its original rib_lookup_ipv4(), checks
829 * if specified IPv4 route record (prefix/mask -> gate) exists in
830 * the whole RIB and has ZEBRA_FLAG_SELECTED set.
831 *
832 * Return values:
833 * -1: error
834 * 0: exact match found
835 * 1: a match was found with a different gate
836 * 2: connected route found
837 * 3: no matches found
838 */
839int
840rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
841{
842 struct route_table *table;
843 struct route_node *rn;
844 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000845 struct nexthop *nexthop, *tnexthop;
846 int recursing;
847 int nexthops_active;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000848
849 /* Lookup table. */
850 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
851 if (! table)
852 return ZEBRA_RIB_LOOKUP_ERROR;
853
854 /* Scan the RIB table for exactly matching RIB entry. */
855 rn = route_node_lookup (table, (struct prefix *) p);
856
857 /* No route for this prefix. */
858 if (! rn)
859 return ZEBRA_RIB_NOTFOUND;
860
861 /* Unlock node. */
862 route_unlock_node (rn);
863
864 /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000865 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100866 {
867 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
868 continue;
869 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
870 break;
871 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000872
873 /* None such found :( */
874 if (!match)
875 return ZEBRA_RIB_NOTFOUND;
876
877 if (match->type == ZEBRA_ROUTE_CONNECT)
878 return ZEBRA_RIB_FOUND_CONNECTED;
879
880 /* Ok, we have a cood candidate, let's check it's nexthop list... */
Christian Frankefa713d92013-07-05 15:35:37 +0000881 nexthops_active = 0;
882 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000883 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000884 {
Christian Frankefa713d92013-07-05 15:35:37 +0000885 nexthops_active = 1;
886 if (nexthop->gate.ipv4.s_addr == sockunion2ip (qgate))
887 return ZEBRA_RIB_FOUND_EXACT;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000888 if (IS_ZEBRA_DEBUG_RIB)
Christian Frankefa713d92013-07-05 15:35:37 +0000889 {
890 char gate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
891 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
892 inet_ntop (AF_INET, &sockunion2ip(qgate), qgate_buf, INET_ADDRSTRLEN);
893 zlog_debug ("%s: qgate == %s, %s == %s", __func__,
894 qgate_buf, recursing ? "rgate" : "gate", gate_buf);
895 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000896 }
Christian Frankefa713d92013-07-05 15:35:37 +0000897
898 if (nexthops_active)
899 return ZEBRA_RIB_FOUND_NOGATE;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000900
901 return ZEBRA_RIB_NOTFOUND;
902}
903
paul718e3742002-12-13 20:15:29 +0000904#ifdef HAVE_IPV6
905struct rib *
906rib_match_ipv6 (struct in6_addr *addr)
907{
908 struct prefix_ipv6 p;
909 struct route_table *table;
910 struct route_node *rn;
911 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000912 struct nexthop *newhop, *tnewhop;
913 int recursing;
paul718e3742002-12-13 20:15:29 +0000914
915 /* Lookup table. */
916 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
917 if (! table)
918 return 0;
919
920 memset (&p, 0, sizeof (struct prefix_ipv6));
921 p.family = AF_INET6;
922 p.prefixlen = IPV6_MAX_PREFIXLEN;
923 IPV6_ADDR_COPY (&p.prefix, addr);
924
925 rn = route_node_match (table, (struct prefix *) &p);
926
927 while (rn)
928 {
929 route_unlock_node (rn);
930
931 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000932 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100933 {
934 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
935 continue;
936 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
937 break;
938 }
paul718e3742002-12-13 20:15:29 +0000939
940 /* If there is no selected route or matched route is EGP, go up
941 tree. */
942 if (! match
943 || match->type == ZEBRA_ROUTE_BGP)
944 {
945 do {
946 rn = rn->parent;
947 } while (rn && rn->info == NULL);
948 if (rn)
949 route_lock_node (rn);
950 }
951 else
952 {
953 if (match->type == ZEBRA_ROUTE_CONNECT)
954 /* Directly point connected route. */
955 return match;
956 else
957 {
Christian Frankefa713d92013-07-05 15:35:37 +0000958 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
paul718e3742002-12-13 20:15:29 +0000959 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
960 return match;
961 return NULL;
962 }
963 }
964 }
965 return NULL;
966}
967#endif /* HAVE_IPV6 */
968
Paul Jakma7514fb72007-05-02 16:05:35 +0000969#define RIB_SYSTEM_ROUTE(R) \
970 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
971
Denis Ovsienkodc958242007-08-13 16:03:06 +0000972/* This function verifies reachability of one given nexthop, which can be
973 * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
974 * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
975 * nexthop->ifindex will be updated appropriately as well.
976 * An existing route map can turn (otherwise active) nexthop into inactive, but
977 * not vice versa.
978 *
979 * The return value is the final value of 'ACTIVE' flag.
980 */
981
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300982static unsigned
paul718e3742002-12-13 20:15:29 +0000983nexthop_active_check (struct route_node *rn, struct rib *rib,
984 struct nexthop *nexthop, int set)
985{
Christian Frankef3a17322013-07-05 15:35:41 +0000986 rib_table_info_t *info = rn->table->info;
paul718e3742002-12-13 20:15:29 +0000987 struct interface *ifp;
Paul Jakma7514fb72007-05-02 16:05:35 +0000988 route_map_result_t ret = RMAP_MATCH;
989 extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
990 struct route_map *rmap;
991 int family;
paul718e3742002-12-13 20:15:29 +0000992
Paul Jakma7514fb72007-05-02 16:05:35 +0000993 family = 0;
paul718e3742002-12-13 20:15:29 +0000994 switch (nexthop->type)
995 {
996 case NEXTHOP_TYPE_IFINDEX:
997 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000998 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000999 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1000 else
1001 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1002 break;
paul718e3742002-12-13 20:15:29 +00001003 case NEXTHOP_TYPE_IPV6_IFNAME:
Paul Jakma7514fb72007-05-02 16:05:35 +00001004 family = AFI_IP6;
1005 case NEXTHOP_TYPE_IFNAME:
paul718e3742002-12-13 20:15:29 +00001006 ifp = if_lookup_by_name (nexthop->ifname);
Andrew J. Schorr3f087672008-01-08 20:12:46 +00001007 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001008 {
1009 if (set)
1010 nexthop->ifindex = ifp->ifindex;
1011 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1012 }
1013 else
1014 {
1015 if (set)
1016 nexthop->ifindex = 0;
1017 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1018 }
1019 break;
1020 case NEXTHOP_TYPE_IPV4:
1021 case NEXTHOP_TYPE_IPV4_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +00001022 family = AFI_IP;
paul718e3742002-12-13 20:15:29 +00001023 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
1024 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1025 else
1026 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1027 break;
1028#ifdef HAVE_IPV6
1029 case NEXTHOP_TYPE_IPV6:
Paul Jakma7514fb72007-05-02 16:05:35 +00001030 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +00001031 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
1032 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1033 else
1034 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1035 break;
1036 case NEXTHOP_TYPE_IPV6_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +00001037 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +00001038 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
1039 {
1040 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +00001041 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001042 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1043 else
1044 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1045 }
1046 else
1047 {
1048 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
1049 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1050 else
1051 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1052 }
1053 break;
1054#endif /* HAVE_IPV6 */
paul595db7f2003-05-25 21:35:06 +00001055 case NEXTHOP_TYPE_BLACKHOLE:
1056 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1057 break;
paul718e3742002-12-13 20:15:29 +00001058 default:
1059 break;
1060 }
Paul Jakma7514fb72007-05-02 16:05:35 +00001061 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1062 return 0;
1063
Christian Frankef3a17322013-07-05 15:35:41 +00001064 /* XXX: What exactly do those checks do? Do we support
1065 * e.g. IPv4 routes with IPv6 nexthops or vice versa? */
Paul Jakma7514fb72007-05-02 16:05:35 +00001066 if (RIB_SYSTEM_ROUTE(rib) ||
1067 (family == AFI_IP && rn->p.family != AF_INET) ||
1068 (family == AFI_IP6 && rn->p.family != AF_INET6))
1069 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1070
Christian Frankef3a17322013-07-05 15:35:41 +00001071 /* The original code didn't determine the family correctly
1072 * e.g. for NEXTHOP_TYPE_IFINDEX. Retrieve the correct afi
1073 * from the rib_table_info in those cases.
1074 * Possibly it may be better to use only the rib_table_info
1075 * in every case.
1076 */
1077 if (!family)
1078 family = info->afi;
1079
Paul Jakma7514fb72007-05-02 16:05:35 +00001080 rmap = 0;
1081 if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
1082 proto_rm[family][rib->type])
1083 rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
1084 if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
1085 rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
1086 if (rmap) {
1087 ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, nexthop);
1088 }
1089
1090 if (ret == RMAP_DENYMATCH)
1091 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
paul718e3742002-12-13 20:15:29 +00001092 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1093}
1094
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001095/* Iterate over all nexthops of the given RIB entry and refresh their
1096 * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
1097 * nexthop is found to toggle the ACTIVE flag, the whole rib structure
1098 * is flagged with ZEBRA_FLAG_CHANGED. The 4th 'set' argument is
1099 * transparently passed to nexthop_active_check().
1100 *
1101 * Return value is the new number of active nexthops.
1102 */
1103
paula1ac18c2005-06-28 17:17:12 +00001104static int
paul718e3742002-12-13 20:15:29 +00001105nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
1106{
1107 struct nexthop *nexthop;
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001108 unsigned int prev_active, prev_index, new_active;
paul718e3742002-12-13 20:15:29 +00001109
1110 rib->nexthop_active_num = 0;
1111 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1112
1113 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001114 {
1115 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001116 prev_index = nexthop->ifindex;
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001117 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
1118 rib->nexthop_active_num++;
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001119 if (prev_active != new_active ||
1120 prev_index != nexthop->ifindex)
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001121 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1122 }
paul718e3742002-12-13 20:15:29 +00001123 return rib->nexthop_active_num;
1124}
paul6baeb982003-10-28 03:47:15 +00001125
David Lamparter6b0655a2014-06-04 06:53:35 +02001126
paul718e3742002-12-13 20:15:29 +00001127
paula1ac18c2005-06-28 17:17:12 +00001128static void
paul718e3742002-12-13 20:15:29 +00001129rib_install_kernel (struct route_node *rn, struct rib *rib)
1130{
1131 int ret = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001132 struct nexthop *nexthop, *tnexthop;
1133 int recursing;
paul718e3742002-12-13 20:15:29 +00001134
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001135 /*
1136 * Make sure we update the FPM any time we send new information to
1137 * the kernel.
1138 */
1139 zfpm_trigger_update (rn, "installing in kernel");
paul718e3742002-12-13 20:15:29 +00001140 switch (PREFIX_FAMILY (&rn->p))
1141 {
1142 case AF_INET:
1143 ret = kernel_add_ipv4 (&rn->p, rib);
1144 break;
1145#ifdef HAVE_IPV6
1146 case AF_INET6:
1147 ret = kernel_add_ipv6 (&rn->p, rib);
1148 break;
1149#endif /* HAVE_IPV6 */
1150 }
1151
Denis Ovsienkodc958242007-08-13 16:03:06 +00001152 /* This condition is never met, if we are using rt_socket.c */
paul718e3742002-12-13 20:15:29 +00001153 if (ret < 0)
1154 {
Christian Frankefa713d92013-07-05 15:35:37 +00001155 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +00001156 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1157 }
1158}
1159
1160/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001161static int
paul718e3742002-12-13 20:15:29 +00001162rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
1163{
1164 int ret = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001165 struct nexthop *nexthop, *tnexthop;
1166 int recursing;
paul718e3742002-12-13 20:15:29 +00001167
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001168 /*
1169 * Make sure we update the FPM any time we send new information to
1170 * the kernel.
1171 */
1172 zfpm_trigger_update (rn, "uninstalling from kernel");
1173
paul718e3742002-12-13 20:15:29 +00001174 switch (PREFIX_FAMILY (&rn->p))
1175 {
1176 case AF_INET:
1177 ret = kernel_delete_ipv4 (&rn->p, rib);
1178 break;
1179#ifdef HAVE_IPV6
1180 case AF_INET6:
1181 ret = kernel_delete_ipv6 (&rn->p, rib);
1182 break;
1183#endif /* HAVE_IPV6 */
1184 }
1185
Christian Frankefa713d92013-07-05 15:35:37 +00001186 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +00001187 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1188
1189 return ret;
1190}
1191
1192/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001193static void
paul718e3742002-12-13 20:15:29 +00001194rib_uninstall (struct route_node *rn, struct rib *rib)
1195{
1196 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1197 {
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001198 zfpm_trigger_update (rn, "rib_uninstall");
1199
paul718e3742002-12-13 20:15:29 +00001200 redistribute_delete (&rn->p, rib);
1201 if (! RIB_SYSTEM_ROUTE (rib))
1202 rib_uninstall_kernel (rn, rib);
1203 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
1204 }
1205}
1206
Paul Jakma6d691122006-07-27 21:49:00 +00001207static void rib_unlink (struct route_node *, struct rib *);
1208
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001209/*
1210 * rib_can_delete_dest
1211 *
1212 * Returns TRUE if the given dest can be deleted from the table.
1213 */
1214static int
1215rib_can_delete_dest (rib_dest_t *dest)
1216{
1217 if (dest->routes)
1218 {
1219 return 0;
1220 }
1221
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001222 /*
1223 * Don't delete the dest if we have to update the FPM about this
1224 * prefix.
1225 */
1226 if (CHECK_FLAG (dest->flags, RIB_DEST_UPDATE_FPM) ||
1227 CHECK_FLAG (dest->flags, RIB_DEST_SENT_TO_FPM))
1228 return 0;
1229
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001230 return 1;
1231}
1232
1233/*
1234 * rib_gc_dest
1235 *
1236 * Garbage collect the rib dest corresponding to the given route node
1237 * if appropriate.
1238 *
1239 * Returns TRUE if the dest was deleted, FALSE otherwise.
1240 */
1241int
1242rib_gc_dest (struct route_node *rn)
1243{
1244 rib_dest_t *dest;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001245
1246 dest = rib_dest_from_rnode (rn);
1247 if (!dest)
1248 return 0;
1249
1250 if (!rib_can_delete_dest (dest))
1251 return 0;
1252
1253 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001254 rnode_debug (rn, "removing dest from table");
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001255
1256 dest->rnode = NULL;
1257 XFREE (MTYPE_RIB_DEST, dest);
1258 rn->info = NULL;
1259
1260 /*
1261 * Release the one reference that we keep on the route node.
1262 */
1263 route_unlock_node (rn);
1264 return 1;
1265}
1266
paul718e3742002-12-13 20:15:29 +00001267/* Core function for processing routing information base. */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001268static void
1269rib_process (struct route_node *rn)
paul718e3742002-12-13 20:15:29 +00001270{
1271 struct rib *rib;
1272 struct rib *next;
1273 struct rib *fib = NULL;
1274 struct rib *select = NULL;
Paul Jakma6d691122006-07-27 21:49:00 +00001275 struct rib *del = NULL;
pauld753e9e2003-01-22 19:45:50 +00001276 int installed = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001277 struct nexthop *nexthop = NULL, *tnexthop;
1278 int recursing;
Balaji95116332014-10-23 15:25:25 +00001279 rib_table_info_t *info;
1280
paul4d38fdb2005-04-28 17:35:14 +00001281 assert (rn);
Balaji95116332014-10-23 15:25:25 +00001282
1283 info = rn->table->info;
1284
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001285 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00001286 {
paul718e3742002-12-13 20:15:29 +00001287 /* Currently installed rib. */
1288 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Paul Jakma6d691122006-07-27 21:49:00 +00001289 {
1290 assert (fib == NULL);
1291 fib = rib;
1292 }
1293
1294 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1295 * which we need to do do further work with below.
1296 */
1297 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1298 {
1299 if (rib != fib)
1300 {
1301 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001302 rnode_debug (rn, "rn %p, removing rib %p", rn, rib);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001303 rib_unlink (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001304 }
1305 else
1306 del = rib;
1307
1308 continue;
1309 }
paul4d38fdb2005-04-28 17:35:14 +00001310
paul718e3742002-12-13 20:15:29 +00001311 /* Skip unreachable nexthop. */
1312 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +00001313 continue;
paul718e3742002-12-13 20:15:29 +00001314
Balaji95116332014-10-23 15:25:25 +00001315 if (info->safi == SAFI_MULTICAST)
1316 continue;
1317
paul718e3742002-12-13 20:15:29 +00001318 /* Infinit distance. */
1319 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +00001320 continue;
paul718e3742002-12-13 20:15:29 +00001321
paulaf887b52006-01-18 14:52:52 +00001322 /* Newly selected rib, the common case. */
1323 if (!select)
1324 {
1325 select = rib;
1326 continue;
1327 }
1328
1329 /* filter route selection in following order:
paulaf887b52006-01-18 14:52:52 +00001330 * - connected beats other types
paula8d9c1f2006-01-25 06:31:04 +00001331 * - lower distance beats higher
paulaf887b52006-01-18 14:52:52 +00001332 * - lower metric beats higher for equal distance
1333 * - last, hence oldest, route wins tie break.
1334 */
paula1038a12006-01-30 14:08:51 +00001335
1336 /* Connected routes. Pick the last connected
1337 * route of the set of lowest metric connected routes.
1338 */
paula8d9c1f2006-01-25 06:31:04 +00001339 if (rib->type == ZEBRA_ROUTE_CONNECT)
1340 {
paula1038a12006-01-30 14:08:51 +00001341 if (select->type != ZEBRA_ROUTE_CONNECT
paula8d9c1f2006-01-25 06:31:04 +00001342 || rib->metric <= select->metric)
paula1038a12006-01-30 14:08:51 +00001343 select = rib;
1344 continue;
paula8d9c1f2006-01-25 06:31:04 +00001345 }
1346 else if (select->type == ZEBRA_ROUTE_CONNECT)
1347 continue;
1348
1349 /* higher distance loses */
1350 if (rib->distance > select->distance)
1351 continue;
1352
1353 /* lower wins */
1354 if (rib->distance < select->distance)
1355 {
paulaf887b52006-01-18 14:52:52 +00001356 select = rib;
paula8d9c1f2006-01-25 06:31:04 +00001357 continue;
1358 }
1359
1360 /* metric tie-breaks equal distance */
1361 if (rib->metric <= select->metric)
1362 select = rib;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001363 } /* RNODE_FOREACH_RIB_SAFE */
Denis Ovsienkodc958242007-08-13 16:03:06 +00001364
1365 /* After the cycle is finished, the following pointers will be set:
1366 * select --- the winner RIB entry, if any was found, otherwise NULL
1367 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1368 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1369 * rib --- NULL
1370 */
1371
1372 /* Same RIB entry is selected. Update FIB and finish. */
paul718e3742002-12-13 20:15:29 +00001373 if (select && select == fib)
1374 {
Paul Jakma6d691122006-07-27 21:49:00 +00001375 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001376 rnode_debug (rn, "Updating existing route, select %p, fib %p",
1377 select, fib);
paul718e3742002-12-13 20:15:29 +00001378 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +00001379 {
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001380 zfpm_trigger_update (rn, "updating existing route");
1381
paul4d38fdb2005-04-28 17:35:14 +00001382 redistribute_delete (&rn->p, select);
1383 if (! RIB_SYSTEM_ROUTE (select))
1384 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001385
paul4d38fdb2005-04-28 17:35:14 +00001386 /* Set real nexthop. */
1387 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +00001388
paul4d38fdb2005-04-28 17:35:14 +00001389 if (! RIB_SYSTEM_ROUTE (select))
1390 rib_install_kernel (rn, select);
1391 redistribute_add (&rn->p, select);
1392 }
pauld753e9e2003-01-22 19:45:50 +00001393 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001394 {
1395 /* Housekeeping code to deal with
1396 race conditions in kernel with linux
1397 netlink reporting interface up before IPv4 or IPv6 protocol
1398 is ready to add routes.
1399 This makes sure the routes are IN the kernel.
1400 */
pauld753e9e2003-01-22 19:45:50 +00001401
Christian Frankefa713d92013-07-05 15:35:37 +00001402 for (ALL_NEXTHOPS_RO(select->nexthop, nexthop, tnexthop, recursing))
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001403 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
paul4d38fdb2005-04-28 17:35:14 +00001404 {
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001405 installed = 1;
1406 break;
paul4d38fdb2005-04-28 17:35:14 +00001407 }
1408 if (! installed)
1409 rib_install_kernel (rn, select);
1410 }
Paul Jakma6d691122006-07-27 21:49:00 +00001411 goto end;
paul718e3742002-12-13 20:15:29 +00001412 }
1413
Denis Ovsienkodc958242007-08-13 16:03:06 +00001414 /* At this point we either haven't found the best RIB entry or it is
1415 * different from what we currently intend to flag with SELECTED. In both
1416 * cases, if a RIB block is present in FIB, it should be withdrawn.
1417 */
paul718e3742002-12-13 20:15:29 +00001418 if (fib)
1419 {
Paul Jakma6d691122006-07-27 21:49:00 +00001420 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001421 rnode_debug (rn, "Removing existing route, fib %p", fib);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001422
1423 zfpm_trigger_update (rn, "removing existing route");
1424
paul718e3742002-12-13 20:15:29 +00001425 redistribute_delete (&rn->p, fib);
1426 if (! RIB_SYSTEM_ROUTE (fib))
1427 rib_uninstall_kernel (rn, fib);
1428 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1429
1430 /* Set real nexthop. */
1431 nexthop_active_update (rn, fib, 1);
1432 }
1433
Denis Ovsienkodc958242007-08-13 16:03:06 +00001434 /* Regardless of some RIB entry being SELECTED or not before, now we can
1435 * tell, that if a new winner exists, FIB is still not updated with this
1436 * data, but ready to be.
1437 */
paul718e3742002-12-13 20:15:29 +00001438 if (select)
1439 {
Paul Jakma6d691122006-07-27 21:49:00 +00001440 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001441 rnode_debug (rn, "Adding route, select %p", select);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001442
1443 zfpm_trigger_update (rn, "new route selected");
1444
paul718e3742002-12-13 20:15:29 +00001445 /* Set real nexthop. */
1446 nexthop_active_update (rn, select, 1);
1447
1448 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001449 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001450 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1451 redistribute_add (&rn->p, select);
1452 }
paul4d38fdb2005-04-28 17:35:14 +00001453
Paul Jakma6d691122006-07-27 21:49:00 +00001454 /* FIB route was removed, should be deleted */
1455 if (del)
1456 {
1457 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001458 rnode_debug (rn, "Deleting fib %p, rn %p", del, rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001459 rib_unlink (rn, del);
1460 }
paul4d38fdb2005-04-28 17:35:14 +00001461
Paul Jakma6d691122006-07-27 21:49:00 +00001462end:
1463 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lamparter94813742014-04-24 20:22:53 +02001464 rnode_debug (rn, "rn %p dequeued", rn);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001465
1466 /*
1467 * Check if the dest can be deleted now.
1468 */
1469 rib_gc_dest (rn);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001470}
1471
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001472/* Take a list of route_node structs and return 1, if there was a record
1473 * picked from it and processed by rib_process(). Don't process more,
1474 * than one RN record; operate only in the specified sub-queue.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001475 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001476static unsigned int
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001477process_subq (struct list * subq, u_char qindex)
1478{
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001479 struct listnode *lnode = listhead (subq);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001480 struct route_node *rnode;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001481
1482 if (!lnode)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001483 return 0;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001484
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001485 rnode = listgetdata (lnode);
1486 rib_process (rnode);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001487
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001488 if (rnode->info)
1489 UNSET_FLAG (rib_dest_from_rnode (rnode)->flags, RIB_ROUTE_QUEUED (qindex));
1490
Chris Caputo67b94672009-07-18 04:02:26 +00001491#if 0
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001492 else
1493 {
1494 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1495 __func__, rnode, rnode->lock);
1496 zlog_backtrace(LOG_DEBUG);
1497 }
Chris Caputo67b94672009-07-18 04:02:26 +00001498#endif
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001499 route_unlock_node (rnode);
1500 list_delete_node (subq, lnode);
1501 return 1;
1502}
1503
1504/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1505 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1506 * is pointed to the meta queue structure.
1507 */
1508static wq_item_status
1509meta_queue_process (struct work_queue *dummy, void *data)
1510{
1511 struct meta_queue * mq = data;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001512 unsigned i;
1513
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001514 for (i = 0; i < MQ_SIZE; i++)
1515 if (process_subq (mq->subq[i], i))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001516 {
1517 mq->size--;
1518 break;
1519 }
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001520 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1521}
1522
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001523/*
1524 * Map from rib types to queue type (priority) in meta queue
1525 */
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001526static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
1527 [ZEBRA_ROUTE_SYSTEM] = 4,
1528 [ZEBRA_ROUTE_KERNEL] = 0,
1529 [ZEBRA_ROUTE_CONNECT] = 0,
1530 [ZEBRA_ROUTE_STATIC] = 1,
1531 [ZEBRA_ROUTE_RIP] = 2,
1532 [ZEBRA_ROUTE_RIPNG] = 2,
1533 [ZEBRA_ROUTE_OSPF] = 2,
1534 [ZEBRA_ROUTE_OSPF6] = 2,
1535 [ZEBRA_ROUTE_ISIS] = 2,
1536 [ZEBRA_ROUTE_BGP] = 3,
1537 [ZEBRA_ROUTE_HSLS] = 4,
Paul Jakma57345092011-12-25 17:52:09 +01001538 [ZEBRA_ROUTE_BABEL] = 2,
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001539};
1540
1541/* Look into the RN and queue it into one or more priority queues,
1542 * increasing the size for each data push done.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001543 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001544static void
1545rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001546{
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001547 struct rib *rib;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001548
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001549 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001550 {
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001551 u_char qindex = meta_queue_map[rib->type];
1552
1553 /* Invariant: at this point we always have rn->info set. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001554 if (CHECK_FLAG (rib_dest_from_rnode (rn)->flags,
1555 RIB_ROUTE_QUEUED (qindex)))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001556 {
1557 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lamparter94813742014-04-24 20:22:53 +02001558 rnode_debug (rn, "rn %p is already queued in sub-queue %u",
1559 rn, qindex);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001560 continue;
1561 }
1562
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001563 SET_FLAG (rib_dest_from_rnode (rn)->flags, RIB_ROUTE_QUEUED (qindex));
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001564 listnode_add (mq->subq[qindex], rn);
1565 route_lock_node (rn);
1566 mq->size++;
1567
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001568 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lamparter94813742014-04-24 20:22:53 +02001569 rnode_debug (rn, "queued rn %p into sub-queue %u",
1570 rn, qindex);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001571 }
paul4d38fdb2005-04-28 17:35:14 +00001572}
1573
Paul Jakma6d691122006-07-27 21:49:00 +00001574/* Add route_node to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001575static void
Paul Jakma6d691122006-07-27 21:49:00 +00001576rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
paul4d38fdb2005-04-28 17:35:14 +00001577{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001578 assert (zebra && rn);
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001579
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001580 /* Pointless to queue a route_node with no RIB entries to add or remove */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001581 if (!rnode_to_ribs (rn))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001582 {
1583 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1584 __func__, rn, rn->lock);
1585 zlog_backtrace(LOG_DEBUG);
1586 return;
1587 }
1588
1589 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lamparter94813742014-04-24 20:22:53 +02001590 rnode_info (rn, "work queue added");
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001591
1592 assert (zebra);
1593
1594 if (zebra->ribq == NULL)
1595 {
1596 zlog_err ("%s: work_queue does not exist!", __func__);
1597 return;
Paul Jakma6d691122006-07-27 21:49:00 +00001598 }
paul4d38fdb2005-04-28 17:35:14 +00001599
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001600 /*
1601 * The RIB queue should normally be either empty or holding the only
1602 * work_queue_item element. In the latter case this element would
1603 * hold a pointer to the meta queue structure, which must be used to
1604 * actually queue the route nodes to process. So create the MQ
1605 * holder, if necessary, then push the work into it in any case.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001606 * This semantics was introduced after 0.99.9 release.
1607 */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001608 if (!zebra->ribq->items->count)
1609 work_queue_add (zebra->ribq, zebra->mq);
1610
1611 rib_meta_queue_add (zebra->mq, rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001612
1613 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lamparter94813742014-04-24 20:22:53 +02001614 rnode_debug (rn, "rn %p queued", rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001615
1616 return;
paul4d38fdb2005-04-28 17:35:14 +00001617}
1618
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001619/* Create new meta queue.
1620 A destructor function doesn't seem to be necessary here.
1621 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001622static struct meta_queue *
1623meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001624{
1625 struct meta_queue *new;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001626 unsigned i;
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001627
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001628 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1629 assert(new);
1630
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001631 for (i = 0; i < MQ_SIZE; i++)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001632 {
1633 new->subq[i] = list_new ();
1634 assert(new->subq[i]);
1635 }
1636
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001637 return new;
1638}
1639
paul4d38fdb2005-04-28 17:35:14 +00001640/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001641static void
paul4d38fdb2005-04-28 17:35:14 +00001642rib_queue_init (struct zebra_t *zebra)
1643{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001644 assert (zebra);
1645
paul4d38fdb2005-04-28 17:35:14 +00001646 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001647 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001648 {
Paul Jakma6d691122006-07-27 21:49:00 +00001649 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001650 return;
1651 }
1652
1653 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001654 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001655 zebra->ribq->spec.errorfunc = NULL;
paul4d38fdb2005-04-28 17:35:14 +00001656 /* XXX: TODO: These should be runtime configurable via vty */
1657 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001658 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001659
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001660 if (!(zebra->mq = meta_queue_new ()))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001661 {
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001662 zlog_err ("%s: could not initialise meta queue!", __func__);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001663 return;
1664 }
1665 return;
paul718e3742002-12-13 20:15:29 +00001666}
1667
Paul Jakma6d691122006-07-27 21:49:00 +00001668/* RIB updates are processed via a queue of pointers to route_nodes.
1669 *
1670 * The queue length is bounded by the maximal size of the routing table,
1671 * as a route_node will not be requeued, if already queued.
1672 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001673 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1674 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1675 * and then submit route_node to queue for best-path selection later.
1676 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001677 *
1678 * Deleted RIBs are reaped during best-path selection.
1679 *
1680 * rib_addnode
1681 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001682 * |-------->| | best RIB, if required
1683 * | |
1684 * static_install->|->rib_addqueue...... -> rib_process
1685 * | |
1686 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001687 * |-> set RIB_ENTRY_REMOVE |
1688 * rib_delnode (RIB freed)
1689 *
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001690 * The 'info' pointer of a route_node points to a rib_dest_t
1691 * ('dest'). Queueing state for a route_node is kept on the dest. The
1692 * dest is created on-demand by rib_link() and is kept around at least
1693 * as long as there are ribs hanging off it (@see rib_gc_dest()).
Paul Jakma6d691122006-07-27 21:49:00 +00001694 *
1695 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1696 *
1697 * - route_nodes: refcounted by:
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001698 * - dest attached to route_node:
1699 * - managed by: rib_link/rib_gc_dest
Paul Jakma6d691122006-07-27 21:49:00 +00001700 * - route_node processing queue
1701 * - managed by: rib_addqueue, rib_process.
1702 *
1703 */
1704
paul718e3742002-12-13 20:15:29 +00001705/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001706static void
Paul Jakma6d691122006-07-27 21:49:00 +00001707rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001708{
1709 struct rib *head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001710 rib_dest_t *dest;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001711
paul4d38fdb2005-04-28 17:35:14 +00001712 assert (rib && rn);
1713
Paul Jakma6d691122006-07-27 21:49:00 +00001714 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001715 rnode_debug (rn, "rn %p, rib %p", rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001716
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001717 dest = rib_dest_from_rnode (rn);
1718 if (!dest)
Paul Jakma6d691122006-07-27 21:49:00 +00001719 {
1720 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001721 rnode_debug (rn, "adding dest to table");
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001722
1723 dest = XCALLOC (MTYPE_RIB_DEST, sizeof (rib_dest_t));
1724 route_lock_node (rn); /* rn route table reference */
1725 rn->info = dest;
1726 dest->rnode = rn;
1727 }
1728
1729 head = dest->routes;
1730 if (head)
1731 {
Paul Jakma6d691122006-07-27 21:49:00 +00001732 head->prev = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001733 }
paul718e3742002-12-13 20:15:29 +00001734 rib->next = head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001735 dest->routes = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001736 rib_queue_add (&zebrad, rn);
1737}
1738
1739static void
1740rib_addnode (struct route_node *rn, struct rib *rib)
1741{
1742 /* RIB node has been un-removed before route-node is processed.
1743 * route_node must hence already be on the queue for processing..
1744 */
1745 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1746 {
1747 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001748 rnode_debug (rn, "rn %p, un-removed rib %p", rn, rib);
1749
Paul Jakma6d691122006-07-27 21:49:00 +00001750 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1751 return;
1752 }
1753 rib_link (rn, rib);
1754}
1755
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001756/*
1757 * rib_unlink
1758 *
1759 * Detach a rib structure from a route_node.
1760 *
1761 * Note that a call to rib_unlink() should be followed by a call to
1762 * rib_gc_dest() at some point. This allows a rib_dest_t that is no
1763 * longer required to be deleted.
1764 */
Paul Jakma6d691122006-07-27 21:49:00 +00001765static void
1766rib_unlink (struct route_node *rn, struct rib *rib)
1767{
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001768 rib_dest_t *dest;
Paul Jakma6d691122006-07-27 21:49:00 +00001769
1770 assert (rn && rib);
1771
1772 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001773 rnode_debug (rn, "rn %p, rib %p", rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001774
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001775 dest = rib_dest_from_rnode (rn);
1776
Paul Jakma6d691122006-07-27 21:49:00 +00001777 if (rib->next)
1778 rib->next->prev = rib->prev;
1779
1780 if (rib->prev)
1781 rib->prev->next = rib->next;
1782 else
1783 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001784 dest->routes = rib->next;
Paul Jakma6d691122006-07-27 21:49:00 +00001785 }
1786
1787 /* free RIB and nexthops */
Christian Frankefa713d92013-07-05 15:35:37 +00001788 nexthops_free(rib->nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00001789 XFREE (MTYPE_RIB, rib);
1790
paul718e3742002-12-13 20:15:29 +00001791}
1792
paula1ac18c2005-06-28 17:17:12 +00001793static void
paul718e3742002-12-13 20:15:29 +00001794rib_delnode (struct route_node *rn, struct rib *rib)
1795{
Paul Jakma6d691122006-07-27 21:49:00 +00001796 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001797 rnode_debug (rn, "rn %p, rib %p, removing", rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001798 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1799 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001800}
1801
1802int
1803rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001804 struct in_addr *gate, struct in_addr *src,
1805 unsigned int ifindex, u_int32_t vrf_id,
G.Balajicddf3912011-11-26 21:59:32 +04001806 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001807{
1808 struct rib *rib;
1809 struct rib *same = NULL;
1810 struct route_table *table;
1811 struct route_node *rn;
1812 struct nexthop *nexthop;
1813
1814 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04001815 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00001816 if (! table)
1817 return 0;
1818
1819 /* Make it sure prefixlen is applied to the prefix. */
1820 apply_mask_ipv4 (p);
1821
1822 /* Set default distance by route type. */
1823 if (distance == 0)
1824 {
Balaji.G837d16c2012-09-26 14:09:10 +05301825 if ((unsigned)type >= array_size(route_info))
David Lamparter7052f222009-08-27 00:28:28 +02001826 distance = 150;
1827 else
1828 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00001829
1830 /* iBGP distance is 200. */
1831 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1832 distance = 200;
1833 }
1834
1835 /* Lookup route node.*/
1836 rn = route_node_get (table, (struct prefix *) p);
1837
1838 /* If same type of route are installed, treat it as a implicit
1839 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001840 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00001841 {
Paul Jakma6d691122006-07-27 21:49:00 +00001842 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1843 continue;
1844
hassoebf1ead2005-09-21 14:58:20 +00001845 if (rib->type != type)
1846 continue;
1847 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001848 {
1849 same = rib;
1850 break;
1851 }
hassoebf1ead2005-09-21 14:58:20 +00001852 /* Duplicate connected route comes in. */
1853 else if ((nexthop = rib->nexthop) &&
1854 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001855 nexthop->ifindex == ifindex &&
1856 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001857 {
1858 rib->refcnt++;
1859 return 0 ;
1860 }
paul718e3742002-12-13 20:15:29 +00001861 }
1862
1863 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001864 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001865 rib->type = type;
1866 rib->distance = distance;
1867 rib->flags = flags;
1868 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001869 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001870 rib->nexthop_num = 0;
1871 rib->uptime = time (NULL);
1872
1873 /* Nexthop settings. */
1874 if (gate)
1875 {
1876 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001877 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001878 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001879 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001880 }
1881 else
1882 nexthop_ifindex_add (rib, ifindex);
1883
1884 /* If this route is kernel route, set FIB flag to the route. */
1885 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1886 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1887 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1888
1889 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001890 if (IS_ZEBRA_DEBUG_RIB)
1891 zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
paul718e3742002-12-13 20:15:29 +00001892 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001893
paul718e3742002-12-13 20:15:29 +00001894 /* Free implicit route.*/
1895 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001896 {
1897 if (IS_ZEBRA_DEBUG_RIB)
1898 zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001899 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001900 }
paul4d38fdb2005-04-28 17:35:14 +00001901
1902 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001903 return 0;
1904}
1905
Denis Ovsienkodc958242007-08-13 16:03:06 +00001906/* This function dumps the contents of a given RIB entry into
1907 * standard debug log. Calling function name and IP prefix in
1908 * question are passed as 1st and 2nd arguments.
1909 */
1910
David Lamparterf7bf4152013-10-22 17:10:21 +00001911void _rib_dump (const char * func,
1912 union prefix46constptr pp, const struct rib * rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001913{
David Lamparterf7bf4152013-10-22 17:10:21 +00001914 const struct prefix *p = pp.p;
Vincent Bernatfed643f2012-10-23 16:00:42 +00001915 char straddr[INET6_ADDRSTRLEN];
Christian Frankefa713d92013-07-05 15:35:37 +00001916 struct nexthop *nexthop, *tnexthop;
1917 int recursing;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001918
Vincent Bernatfed643f2012-10-23 16:00:42 +00001919 inet_ntop (p->family, &p->u.prefix, straddr, INET6_ADDRSTRLEN);
Christian Frankefa713d92013-07-05 15:35:37 +00001920 zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr, p->prefixlen);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001921 zlog_debug
1922 (
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001923 "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
Denis Ovsienkodc958242007-08-13 16:03:06 +00001924 func,
1925 rib->refcnt,
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001926 (unsigned long) rib->uptime,
Denis Ovsienkodc958242007-08-13 16:03:06 +00001927 rib->type,
1928 rib->table
1929 );
1930 zlog_debug
1931 (
1932 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1933 func,
1934 rib->metric,
1935 rib->distance,
1936 rib->flags,
1937 rib->status
1938 );
1939 zlog_debug
1940 (
1941 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1942 func,
1943 rib->nexthop_num,
1944 rib->nexthop_active_num,
1945 rib->nexthop_fib_num
1946 );
Vincent Bernatfed643f2012-10-23 16:00:42 +00001947
Christian Frankefa713d92013-07-05 15:35:37 +00001948 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1949 {
Vincent Bernatfed643f2012-10-23 16:00:42 +00001950 inet_ntop (p->family, &nexthop->gate, straddr, INET6_ADDRSTRLEN);
Christian Frankefa713d92013-07-05 15:35:37 +00001951 zlog_debug
1952 (
1953 "%s: %s %s with flags %s%s%s",
1954 func,
1955 (recursing ? " NH" : "NH"),
1956 straddr,
1957 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1958 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1959 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1960 );
1961 }
Denis Ovsienkodc958242007-08-13 16:03:06 +00001962 zlog_debug ("%s: dump complete", func);
1963}
1964
1965/* This is an exported helper to rtm_read() to dump the strange
1966 * RIB entry found by rib_lookup_ipv4_route()
1967 */
1968
1969void rib_lookup_and_dump (struct prefix_ipv4 * p)
1970{
1971 struct route_table *table;
1972 struct route_node *rn;
1973 struct rib *rib;
1974 char prefix_buf[INET_ADDRSTRLEN];
1975
1976 /* Lookup table. */
1977 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1978 if (! table)
1979 {
1980 zlog_err ("%s: vrf_table() returned NULL", __func__);
1981 return;
1982 }
1983
1984 inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
1985 /* Scan the RIB table for exactly matching RIB entry. */
1986 rn = route_node_lookup (table, (struct prefix *) p);
1987
1988 /* No route for this prefix. */
1989 if (! rn)
1990 {
1991 zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
1992 return;
1993 }
1994
1995 /* Unlock node. */
1996 route_unlock_node (rn);
1997
1998 /* let's go */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001999 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00002000 {
2001 zlog_debug
2002 (
2003 "%s: rn %p, rib %p: %s, %s",
2004 __func__,
2005 rn,
2006 rib,
2007 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
2008 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
2009 );
David Lamparterf7bf4152013-10-22 17:10:21 +00002010 rib_dump (p, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002011 }
2012}
2013
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002014/* Check if requested address assignment will fail due to another
2015 * route being installed by zebra in FIB already. Take necessary
2016 * actions, if needed: remove such a route from FIB and deSELECT
2017 * corresponding RIB entry. Then put affected RN into RIBQ head.
2018 */
2019void rib_lookup_and_pushup (struct prefix_ipv4 * p)
2020{
2021 struct route_table *table;
2022 struct route_node *rn;
2023 struct rib *rib;
2024 unsigned changed = 0;
2025
2026 if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
2027 {
2028 zlog_err ("%s: vrf_table() returned NULL", __func__);
2029 return;
2030 }
2031
2032 /* No matches would be the simplest case. */
2033 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
2034 return;
2035
2036 /* Unlock node. */
2037 route_unlock_node (rn);
2038
2039 /* Check all RIB entries. In case any changes have to be done, requeue
2040 * the RN into RIBQ head. If the routing message about the new connected
2041 * route (generated by the IP address we are going to assign very soon)
2042 * comes before the RIBQ is processed, the new RIB entry will join
2043 * RIBQ record already on head. This is necessary for proper revalidation
2044 * of the rest of the RIB.
2045 */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002046 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002047 {
2048 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
2049 ! RIB_SYSTEM_ROUTE (rib))
2050 {
2051 changed = 1;
2052 if (IS_ZEBRA_DEBUG_RIB)
2053 {
2054 char buf[INET_ADDRSTRLEN];
2055 inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
2056 zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
David Lamparterf7bf4152013-10-22 17:10:21 +00002057 rib_dump (&rn->p, rib);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002058 }
2059 rib_uninstall (rn, rib);
2060 }
2061 }
2062 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002063 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002064}
2065
paul718e3742002-12-13 20:15:29 +00002066int
G.Balajicddf3912011-11-26 21:59:32 +04002067rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002068{
2069 struct route_table *table;
2070 struct route_node *rn;
2071 struct rib *same;
2072 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00002073
paul718e3742002-12-13 20:15:29 +00002074 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04002075 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00002076 if (! table)
2077 return 0;
G.Balajicddf3912011-11-26 21:59:32 +04002078
paul718e3742002-12-13 20:15:29 +00002079 /* Make it sure prefixlen is applied to the prefix. */
2080 apply_mask_ipv4 (p);
2081
2082 /* Set default distance by route type. */
2083 if (rib->distance == 0)
2084 {
2085 rib->distance = route_info[rib->type].distance;
2086
2087 /* iBGP distance is 200. */
2088 if (rib->type == ZEBRA_ROUTE_BGP
2089 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
2090 rib->distance = 200;
2091 }
2092
2093 /* Lookup route node.*/
2094 rn = route_node_get (table, (struct prefix *) p);
2095
2096 /* If same type of route are installed, treat it as a implicit
2097 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002098 RNODE_FOREACH_RIB (rn, same)
paul718e3742002-12-13 20:15:29 +00002099 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00002100 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00002101 continue;
2102
paul718e3742002-12-13 20:15:29 +00002103 if (same->type == rib->type && same->table == rib->table
2104 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00002105 break;
paul718e3742002-12-13 20:15:29 +00002106 }
paul4d38fdb2005-04-28 17:35:14 +00002107
paul718e3742002-12-13 20:15:29 +00002108 /* If this route is kernel route, set FIB flag to the route. */
2109 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
2110 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2111 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2112
2113 /* Link new rib to node.*/
2114 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002115 if (IS_ZEBRA_DEBUG_RIB)
2116 {
2117 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
2118 __func__, rn, rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00002119 rib_dump (p, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002120 }
paul718e3742002-12-13 20:15:29 +00002121
paul718e3742002-12-13 20:15:29 +00002122 /* Free implicit route.*/
2123 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00002124 {
2125 if (IS_ZEBRA_DEBUG_RIB)
2126 {
2127 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
2128 __func__, rn, same);
David Lamparterf7bf4152013-10-22 17:10:21 +00002129 rib_dump (p, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002130 }
paul4d38fdb2005-04-28 17:35:14 +00002131 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002132 }
paul4d38fdb2005-04-28 17:35:14 +00002133
2134 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002135 return 0;
2136}
2137
hassoebf1ead2005-09-21 14:58:20 +00002138/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002139int
2140rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
G.Balajicddf3912011-11-26 21:59:32 +04002141 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002142{
2143 struct route_table *table;
2144 struct route_node *rn;
2145 struct rib *rib;
2146 struct rib *fib = NULL;
2147 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002148 struct nexthop *nexthop, *tnexthop;
2149 int recursing;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002150 char buf1[INET_ADDRSTRLEN];
2151 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002152
2153 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04002154 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00002155 if (! table)
2156 return 0;
2157
2158 /* Apply mask. */
2159 apply_mask_ipv4 (p);
2160
Christian Frankeb52aef12013-11-27 17:06:15 +00002161 if (IS_ZEBRA_DEBUG_KERNEL)
2162 {
2163 if (gate)
2164 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
2165 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
2166 p->prefixlen,
2167 inet_ntoa (*gate),
2168 ifindex);
2169 else
2170 zlog_debug ("rib_delete_ipv4(): route delete %s/%d ifindex %d",
2171 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
2172 p->prefixlen,
2173 ifindex);
2174 }
paul5ec90d22003-06-19 01:41:37 +00002175
paul718e3742002-12-13 20:15:29 +00002176 /* Lookup route node. */
2177 rn = route_node_lookup (table, (struct prefix *) p);
2178 if (! rn)
2179 {
2180 if (IS_ZEBRA_DEBUG_KERNEL)
2181 {
2182 if (gate)
ajsb6178002004-12-07 21:12:56 +00002183 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002184 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002185 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002186 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002187 ifindex);
2188 else
ajsb6178002004-12-07 21:12:56 +00002189 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002190 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002191 p->prefixlen,
2192 ifindex);
2193 }
2194 return ZEBRA_ERR_RTNOEXIST;
2195 }
2196
2197 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002198 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002199 {
Paul Jakma6d691122006-07-27 21:49:00 +00002200 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2201 continue;
2202
paul718e3742002-12-13 20:15:29 +00002203 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2204 fib = rib;
2205
hassoebf1ead2005-09-21 14:58:20 +00002206 if (rib->type != type)
2207 continue;
2208 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002209 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002210 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002211 if (nexthop->ifindex != ifindex)
2212 continue;
hassoebf1ead2005-09-21 14:58:20 +00002213 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002214 {
hassoebf1ead2005-09-21 14:58:20 +00002215 rib->refcnt--;
2216 route_unlock_node (rn);
2217 route_unlock_node (rn);
2218 return 0;
paul718e3742002-12-13 20:15:29 +00002219 }
hassoebf1ead2005-09-21 14:58:20 +00002220 same = rib;
2221 break;
paul718e3742002-12-13 20:15:29 +00002222 }
hassoebf1ead2005-09-21 14:58:20 +00002223 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002224 else
paul5ec90d22003-06-19 01:41:37 +00002225 {
Christian Frankefa713d92013-07-05 15:35:37 +00002226 if (gate == NULL)
2227 {
2228 same = rib;
2229 break;
2230 }
2231 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2232 if (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate))
2233 {
2234 same = rib;
2235 break;
2236 }
2237 if (same)
2238 break;
2239 }
paul718e3742002-12-13 20:15:29 +00002240 }
paul718e3742002-12-13 20:15:29 +00002241 /* If same type of route can't be found and this message is from
2242 kernel. */
2243 if (! same)
2244 {
2245 if (fib && type == ZEBRA_ROUTE_KERNEL)
2246 {
2247 /* Unset flags. */
2248 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2249 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2250
2251 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2252 }
2253 else
2254 {
2255 if (IS_ZEBRA_DEBUG_KERNEL)
2256 {
2257 if (gate)
ajsb6178002004-12-07 21:12:56 +00002258 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002259 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002260 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002261 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002262 ifindex,
2263 type);
2264 else
ajsb6178002004-12-07 21:12:56 +00002265 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002266 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002267 p->prefixlen,
2268 ifindex,
2269 type);
2270 }
2271 route_unlock_node (rn);
2272 return ZEBRA_ERR_RTNOEXIST;
2273 }
2274 }
paul4d38fdb2005-04-28 17:35:14 +00002275
paul718e3742002-12-13 20:15:29 +00002276 if (same)
2277 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002278
paul718e3742002-12-13 20:15:29 +00002279 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002280 return 0;
2281}
David Lamparter6b0655a2014-06-04 06:53:35 +02002282
paul718e3742002-12-13 20:15:29 +00002283/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002284static void
paul718e3742002-12-13 20:15:29 +00002285static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
2286{
2287 struct rib *rib;
2288 struct route_node *rn;
2289 struct route_table *table;
2290
2291 /* Lookup table. */
2292 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2293 if (! table)
2294 return;
2295
2296 /* Lookup existing route */
2297 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002298 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002299 {
2300 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2301 continue;
2302
2303 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2304 break;
2305 }
paul718e3742002-12-13 20:15:29 +00002306
2307 if (rib)
2308 {
2309 /* Same distance static route is there. Update it with new
2310 nexthop. */
paul718e3742002-12-13 20:15:29 +00002311 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002312 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002313 {
2314 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002315 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002316 break;
2317 case STATIC_IPV4_IFNAME:
2318 nexthop_ifname_add (rib, si->gate.ifname);
2319 break;
2320 case STATIC_IPV4_BLACKHOLE:
2321 nexthop_blackhole_add (rib);
2322 break;
paul4d38fdb2005-04-28 17:35:14 +00002323 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002324 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002325 }
2326 else
2327 {
2328 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002329 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2330
paul718e3742002-12-13 20:15:29 +00002331 rib->type = ZEBRA_ROUTE_STATIC;
2332 rib->distance = si->distance;
2333 rib->metric = 0;
Nolan Leakeb0145dd2012-09-13 17:17:31 +00002334 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002335 rib->nexthop_num = 0;
2336
2337 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002338 {
2339 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002340 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002341 break;
2342 case STATIC_IPV4_IFNAME:
2343 nexthop_ifname_add (rib, si->gate.ifname);
2344 break;
2345 case STATIC_IPV4_BLACKHOLE:
2346 nexthop_blackhole_add (rib);
2347 break;
2348 }
paul718e3742002-12-13 20:15:29 +00002349
hasso81dfcaa2003-05-25 19:21:25 +00002350 /* Save the flags of this static routes (reject, blackhole) */
2351 rib->flags = si->flags;
2352
paul718e3742002-12-13 20:15:29 +00002353 /* Link this rib to the tree. */
2354 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002355 }
2356}
2357
paula1ac18c2005-06-28 17:17:12 +00002358static int
paul718e3742002-12-13 20:15:29 +00002359static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2360{
2361 if (nexthop->type == NEXTHOP_TYPE_IPV4
2362 && si->type == STATIC_IPV4_GATEWAY
2363 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2364 return 1;
2365 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2366 && si->type == STATIC_IPV4_IFNAME
2367 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2368 return 1;
paul595db7f2003-05-25 21:35:06 +00002369 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2370 && si->type == STATIC_IPV4_BLACKHOLE)
2371 return 1;
paule8e19462006-01-19 20:16:55 +00002372 return 0;
paul718e3742002-12-13 20:15:29 +00002373}
2374
2375/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002376static void
paul718e3742002-12-13 20:15:29 +00002377static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
2378{
2379 struct route_node *rn;
2380 struct rib *rib;
2381 struct nexthop *nexthop;
2382 struct route_table *table;
2383
2384 /* Lookup table. */
2385 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2386 if (! table)
2387 return;
paul4d38fdb2005-04-28 17:35:14 +00002388
paul718e3742002-12-13 20:15:29 +00002389 /* Lookup existing route with type and distance. */
2390 rn = route_node_lookup (table, p);
2391 if (! rn)
2392 return;
2393
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002394 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002395 {
2396 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2397 continue;
2398
2399 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2400 break;
2401 }
paul718e3742002-12-13 20:15:29 +00002402
2403 if (! rib)
2404 {
2405 route_unlock_node (rn);
2406 return;
2407 }
2408
2409 /* Lookup nexthop. */
2410 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2411 if (static_ipv4_nexthop_same (nexthop, si))
2412 break;
2413
2414 /* Can't find nexthop. */
2415 if (! nexthop)
2416 {
2417 route_unlock_node (rn);
2418 return;
2419 }
2420
2421 /* Check nexthop. */
2422 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002423 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002424 else
2425 {
paul6baeb982003-10-28 03:47:15 +00002426 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2427 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002428 nexthop_delete (rib, nexthop);
2429 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002430 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002431 }
paul718e3742002-12-13 20:15:29 +00002432 /* Unlock node. */
2433 route_unlock_node (rn);
2434}
2435
2436/* Add static route into static route configuration. */
2437int
hasso39db97e2004-10-12 20:50:58 +00002438static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00002439 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002440{
2441 u_char type = 0;
2442 struct route_node *rn;
2443 struct static_ipv4 *si;
2444 struct static_ipv4 *pp;
2445 struct static_ipv4 *cp;
2446 struct static_ipv4 *update = NULL;
2447 struct route_table *stable;
2448
2449 /* Lookup table. */
2450 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2451 if (! stable)
2452 return -1;
2453
2454 /* Lookup static route prefix. */
2455 rn = route_node_get (stable, p);
2456
2457 /* Make flags. */
2458 if (gate)
2459 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002460 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002461 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002462 else
2463 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002464
2465 /* Do nothing if there is a same static route. */
2466 for (si = rn->info; si; si = si->next)
2467 {
2468 if (type == si->type
2469 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2470 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2471 {
2472 if (distance == si->distance)
2473 {
2474 route_unlock_node (rn);
2475 return 0;
2476 }
2477 else
2478 update = si;
2479 }
2480 }
2481
Paul Jakma3c0755d2006-12-08 00:53:14 +00002482 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002483 if (update)
2484 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
2485
2486 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002487 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
paul718e3742002-12-13 20:15:29 +00002488
2489 si->type = type;
2490 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002491 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002492
2493 if (gate)
2494 si->gate.ipv4 = *gate;
2495 if (ifname)
2496 si->gate.ifname = XSTRDUP (0, ifname);
2497
2498 /* Add new static route information to the tree with sort by
2499 distance value and gateway address. */
2500 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2501 {
2502 if (si->distance < cp->distance)
2503 break;
2504 if (si->distance > cp->distance)
2505 continue;
2506 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2507 {
2508 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2509 break;
2510 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2511 continue;
2512 }
2513 }
2514
2515 /* Make linked list. */
2516 if (pp)
2517 pp->next = si;
2518 else
2519 rn->info = si;
2520 if (cp)
2521 cp->prev = si;
2522 si->prev = pp;
2523 si->next = cp;
2524
2525 /* Install into rib. */
2526 static_install_ipv4 (p, si);
2527
2528 return 1;
2529}
2530
2531/* Delete static route from static route configuration. */
2532int
hasso39db97e2004-10-12 20:50:58 +00002533static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00002534 u_char distance, u_int32_t vrf_id)
2535{
2536 u_char type = 0;
2537 struct route_node *rn;
2538 struct static_ipv4 *si;
2539 struct route_table *stable;
2540
2541 /* Lookup table. */
2542 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2543 if (! stable)
2544 return -1;
2545
2546 /* Lookup static route prefix. */
2547 rn = route_node_lookup (stable, p);
2548 if (! rn)
2549 return 0;
2550
2551 /* Make flags. */
2552 if (gate)
2553 type = STATIC_IPV4_GATEWAY;
2554 else if (ifname)
2555 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002556 else
2557 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002558
2559 /* Find same static route is the tree */
2560 for (si = rn->info; si; si = si->next)
2561 if (type == si->type
2562 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2563 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2564 break;
2565
2566 /* Can't find static route. */
2567 if (! si)
2568 {
2569 route_unlock_node (rn);
2570 return 0;
2571 }
2572
2573 /* Install into rib. */
2574 static_uninstall_ipv4 (p, si);
2575
2576 /* Unlink static route from linked list. */
2577 if (si->prev)
2578 si->prev->next = si->next;
2579 else
2580 rn->info = si->next;
2581 if (si->next)
2582 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002583 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002584
2585 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002586 if (ifname)
2587 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002588 XFREE (MTYPE_STATIC_IPV4, si);
2589
paul143a3852003-09-29 20:06:13 +00002590 route_unlock_node (rn);
2591
paul718e3742002-12-13 20:15:29 +00002592 return 1;
2593}
2594
David Lamparter6b0655a2014-06-04 06:53:35 +02002595
paul718e3742002-12-13 20:15:29 +00002596#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00002597static int
paul718e3742002-12-13 20:15:29 +00002598rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2599 struct in6_addr *gate, unsigned int ifindex, int table)
2600{
hasso726f9b22003-05-25 21:04:54 +00002601 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2602#if defined (MUSICA) || defined (LINUX)
2603 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2604 if (p->prefixlen == 96)
2605 return 0;
2606#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00002607 return 1;
hasso726f9b22003-05-25 21:04:54 +00002608 }
paul718e3742002-12-13 20:15:29 +00002609 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
2610 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
2611 {
2612 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
2613 return 1;
2614 }
2615 return 0;
2616}
2617
2618int
2619rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00002620 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
G.Balajif768f362011-11-26 22:10:39 +04002621 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002622{
2623 struct rib *rib;
2624 struct rib *same = NULL;
2625 struct route_table *table;
2626 struct route_node *rn;
2627 struct nexthop *nexthop;
2628
paul718e3742002-12-13 20:15:29 +00002629 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002630 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002631 if (! table)
2632 return 0;
2633
2634 /* Make sure mask is applied. */
2635 apply_mask_ipv6 (p);
2636
2637 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002638 if (!distance)
2639 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002640
2641 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2642 distance = 200;
2643
2644 /* Filter bogus route. */
2645 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
2646 return 0;
2647
2648 /* Lookup route node.*/
2649 rn = route_node_get (table, (struct prefix *) p);
2650
2651 /* If same type of route are installed, treat it as a implicit
2652 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002653 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002654 {
Paul Jakma6d691122006-07-27 21:49:00 +00002655 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2656 continue;
2657
hassoebf1ead2005-09-21 14:58:20 +00002658 if (rib->type != type)
2659 continue;
2660 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002661 {
2662 same = rib;
paul718e3742002-12-13 20:15:29 +00002663 break;
2664 }
hassoebf1ead2005-09-21 14:58:20 +00002665 else if ((nexthop = rib->nexthop) &&
2666 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2667 nexthop->ifindex == ifindex)
2668 {
2669 rib->refcnt++;
2670 return 0;
2671 }
paul718e3742002-12-13 20:15:29 +00002672 }
2673
2674 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002675 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2676
paul718e3742002-12-13 20:15:29 +00002677 rib->type = type;
2678 rib->distance = distance;
2679 rib->flags = flags;
2680 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00002681 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00002682 rib->nexthop_num = 0;
2683 rib->uptime = time (NULL);
2684
2685 /* Nexthop settings. */
2686 if (gate)
2687 {
2688 if (ifindex)
2689 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2690 else
2691 nexthop_ipv6_add (rib, gate);
2692 }
2693 else
2694 nexthop_ifindex_add (rib, ifindex);
2695
2696 /* If this route is kernel route, set FIB flag to the route. */
2697 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2698 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2699 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2700
2701 /* Link new rib to node.*/
2702 rib_addnode (rn, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002703 if (IS_ZEBRA_DEBUG_RIB)
2704 {
2705 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
2706 __func__, rn, rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00002707 rib_dump (p, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002708 }
paul718e3742002-12-13 20:15:29 +00002709
paul718e3742002-12-13 20:15:29 +00002710 /* Free implicit route.*/
2711 if (same)
Vincent Bernatfed643f2012-10-23 16:00:42 +00002712 {
2713 if (IS_ZEBRA_DEBUG_RIB)
2714 {
2715 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
2716 __func__, rn, same);
David Lamparterf7bf4152013-10-22 17:10:21 +00002717 rib_dump (p, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002718 }
paul4d38fdb2005-04-28 17:35:14 +00002719 rib_delnode (rn, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002720 }
paul4d38fdb2005-04-28 17:35:14 +00002721
2722 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002723 return 0;
2724}
2725
hassoebf1ead2005-09-21 14:58:20 +00002726/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002727int
2728rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
G.Balajif768f362011-11-26 22:10:39 +04002729 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002730{
2731 struct route_table *table;
2732 struct route_node *rn;
2733 struct rib *rib;
2734 struct rib *fib = NULL;
2735 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002736 struct nexthop *nexthop, *tnexthop;
2737 int recursing;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002738 char buf1[INET6_ADDRSTRLEN];
2739 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002740
2741 /* Apply mask. */
2742 apply_mask_ipv6 (p);
2743
2744 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002745 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002746 if (! table)
2747 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002748
paul718e3742002-12-13 20:15:29 +00002749 /* Lookup route node. */
2750 rn = route_node_lookup (table, (struct prefix *) p);
2751 if (! rn)
2752 {
2753 if (IS_ZEBRA_DEBUG_KERNEL)
2754 {
2755 if (gate)
ajsb6178002004-12-07 21:12:56 +00002756 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002757 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002758 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002759 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002760 ifindex);
2761 else
ajsb6178002004-12-07 21:12:56 +00002762 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002763 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002764 p->prefixlen,
2765 ifindex);
2766 }
2767 return ZEBRA_ERR_RTNOEXIST;
2768 }
2769
2770 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002771 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002772 {
Paul Jakma6d691122006-07-27 21:49:00 +00002773 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2774 continue;
2775
paul718e3742002-12-13 20:15:29 +00002776 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2777 fib = rib;
2778
hassoebf1ead2005-09-21 14:58:20 +00002779 if (rib->type != type)
2780 continue;
2781 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002782 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002783 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002784 if (nexthop->ifindex != ifindex)
2785 continue;
hassoebf1ead2005-09-21 14:58:20 +00002786 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002787 {
hassoebf1ead2005-09-21 14:58:20 +00002788 rib->refcnt--;
2789 route_unlock_node (rn);
2790 route_unlock_node (rn);
2791 return 0;
paul718e3742002-12-13 20:15:29 +00002792 }
hassoebf1ead2005-09-21 14:58:20 +00002793 same = rib;
2794 break;
paul718e3742002-12-13 20:15:29 +00002795 }
hassoebf1ead2005-09-21 14:58:20 +00002796 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002797 else
2798 {
2799 if (gate == NULL)
2800 {
2801 same = rib;
2802 break;
2803 }
2804 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2805 if (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate))
2806 {
2807 same = rib;
2808 break;
2809 }
2810 if (same)
2811 break;
2812 }
paul718e3742002-12-13 20:15:29 +00002813 }
2814
2815 /* If same type of route can't be found and this message is from
2816 kernel. */
2817 if (! same)
2818 {
2819 if (fib && type == ZEBRA_ROUTE_KERNEL)
2820 {
2821 /* Unset flags. */
2822 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2823 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2824
2825 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2826 }
2827 else
2828 {
2829 if (IS_ZEBRA_DEBUG_KERNEL)
2830 {
2831 if (gate)
ajsb6178002004-12-07 21:12:56 +00002832 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002833 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002834 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002835 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002836 ifindex,
2837 type);
2838 else
ajsb6178002004-12-07 21:12:56 +00002839 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002840 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002841 p->prefixlen,
2842 ifindex,
2843 type);
2844 }
2845 route_unlock_node (rn);
2846 return ZEBRA_ERR_RTNOEXIST;
2847 }
2848 }
2849
2850 if (same)
2851 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002852
paul718e3742002-12-13 20:15:29 +00002853 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002854 return 0;
2855}
David Lamparter6b0655a2014-06-04 06:53:35 +02002856
paul718e3742002-12-13 20:15:29 +00002857/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002858static void
paul718e3742002-12-13 20:15:29 +00002859static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2860{
2861 struct rib *rib;
2862 struct route_table *table;
2863 struct route_node *rn;
2864
2865 /* Lookup table. */
2866 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2867 if (! table)
2868 return;
2869
2870 /* Lookup existing route */
2871 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002872 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002873 {
2874 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2875 continue;
2876
2877 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2878 break;
2879 }
paul718e3742002-12-13 20:15:29 +00002880
2881 if (rib)
2882 {
2883 /* Same distance static route is there. Update it with new
2884 nexthop. */
paul718e3742002-12-13 20:15:29 +00002885 route_unlock_node (rn);
2886
2887 switch (si->type)
2888 {
2889 case STATIC_IPV6_GATEWAY:
2890 nexthop_ipv6_add (rib, &si->ipv6);
2891 break;
2892 case STATIC_IPV6_IFNAME:
2893 nexthop_ifname_add (rib, si->ifname);
2894 break;
2895 case STATIC_IPV6_GATEWAY_IFNAME:
2896 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2897 break;
2898 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002899 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002900 }
2901 else
2902 {
2903 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002904 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2905
paul718e3742002-12-13 20:15:29 +00002906 rib->type = ZEBRA_ROUTE_STATIC;
2907 rib->distance = si->distance;
2908 rib->metric = 0;
Dinesh G Duttd1b09912014-09-30 12:54:13 -07002909 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002910 rib->nexthop_num = 0;
2911
2912 switch (si->type)
2913 {
2914 case STATIC_IPV6_GATEWAY:
2915 nexthop_ipv6_add (rib, &si->ipv6);
2916 break;
2917 case STATIC_IPV6_IFNAME:
2918 nexthop_ifname_add (rib, si->ifname);
2919 break;
2920 case STATIC_IPV6_GATEWAY_IFNAME:
2921 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2922 break;
2923 }
2924
hasso81dfcaa2003-05-25 19:21:25 +00002925 /* Save the flags of this static routes (reject, blackhole) */
2926 rib->flags = si->flags;
2927
paul718e3742002-12-13 20:15:29 +00002928 /* Link this rib to the tree. */
2929 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002930 }
2931}
2932
paula1ac18c2005-06-28 17:17:12 +00002933static int
paul718e3742002-12-13 20:15:29 +00002934static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2935{
2936 if (nexthop->type == NEXTHOP_TYPE_IPV6
2937 && si->type == STATIC_IPV6_GATEWAY
2938 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2939 return 1;
2940 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2941 && si->type == STATIC_IPV6_IFNAME
2942 && strcmp (nexthop->ifname, si->ifname) == 0)
2943 return 1;
2944 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2945 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2946 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2947 && strcmp (nexthop->ifname, si->ifname) == 0)
2948 return 1;
paule8e19462006-01-19 20:16:55 +00002949 return 0;
paul718e3742002-12-13 20:15:29 +00002950}
2951
paula1ac18c2005-06-28 17:17:12 +00002952static void
paul718e3742002-12-13 20:15:29 +00002953static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2954{
2955 struct route_table *table;
2956 struct route_node *rn;
2957 struct rib *rib;
2958 struct nexthop *nexthop;
2959
2960 /* Lookup table. */
2961 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2962 if (! table)
2963 return;
2964
2965 /* Lookup existing route with type and distance. */
2966 rn = route_node_lookup (table, (struct prefix *) p);
2967 if (! rn)
2968 return;
2969
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002970 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002971 {
2972 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2973 continue;
2974
2975 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2976 break;
2977 }
2978
paul718e3742002-12-13 20:15:29 +00002979 if (! rib)
2980 {
2981 route_unlock_node (rn);
2982 return;
2983 }
2984
2985 /* Lookup nexthop. */
2986 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2987 if (static_ipv6_nexthop_same (nexthop, si))
2988 break;
2989
2990 /* Can't find nexthop. */
2991 if (! nexthop)
2992 {
2993 route_unlock_node (rn);
2994 return;
2995 }
2996
2997 /* Check nexthop. */
2998 if (rib->nexthop_num == 1)
2999 {
3000 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003001 }
3002 else
3003 {
paul6baeb982003-10-28 03:47:15 +00003004 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
3005 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00003006 nexthop_delete (rib, nexthop);
3007 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00003008 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003009 }
paul718e3742002-12-13 20:15:29 +00003010 /* Unlock node. */
3011 route_unlock_node (rn);
3012}
3013
3014/* Add static route into static route configuration. */
3015int
3016static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00003017 const char *ifname, u_char flags, u_char distance,
3018 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00003019{
3020 struct route_node *rn;
3021 struct static_ipv6 *si;
3022 struct static_ipv6 *pp;
3023 struct static_ipv6 *cp;
3024 struct route_table *stable;
3025
3026 /* Lookup table. */
3027 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
3028 if (! stable)
3029 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00003030
3031 if (!gate &&
3032 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
3033 return -1;
3034
3035 if (!ifname &&
3036 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
3037 return -1;
paul718e3742002-12-13 20:15:29 +00003038
3039 /* Lookup static route prefix. */
3040 rn = route_node_get (stable, p);
3041
3042 /* Do nothing if there is a same static route. */
3043 for (si = rn->info; si; si = si->next)
3044 {
3045 if (distance == si->distance
3046 && type == si->type
3047 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
3048 && (! ifname || strcmp (ifname, si->ifname) == 0))
3049 {
3050 route_unlock_node (rn);
3051 return 0;
3052 }
3053 }
3054
3055 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07003056 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
paul718e3742002-12-13 20:15:29 +00003057
3058 si->type = type;
3059 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00003060 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00003061
3062 switch (type)
3063 {
3064 case STATIC_IPV6_GATEWAY:
3065 si->ipv6 = *gate;
3066 break;
3067 case STATIC_IPV6_IFNAME:
3068 si->ifname = XSTRDUP (0, ifname);
3069 break;
3070 case STATIC_IPV6_GATEWAY_IFNAME:
3071 si->ipv6 = *gate;
3072 si->ifname = XSTRDUP (0, ifname);
3073 break;
3074 }
3075
3076 /* Add new static route information to the tree with sort by
3077 distance value and gateway address. */
3078 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
3079 {
3080 if (si->distance < cp->distance)
3081 break;
3082 if (si->distance > cp->distance)
3083 continue;
3084 }
3085
3086 /* Make linked list. */
3087 if (pp)
3088 pp->next = si;
3089 else
3090 rn->info = si;
3091 if (cp)
3092 cp->prev = si;
3093 si->prev = pp;
3094 si->next = cp;
3095
3096 /* Install into rib. */
3097 static_install_ipv6 (p, si);
3098
3099 return 1;
3100}
3101
3102/* Delete static route from static route configuration. */
3103int
3104static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00003105 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00003106{
3107 struct route_node *rn;
3108 struct static_ipv6 *si;
3109 struct route_table *stable;
3110
3111 /* Lookup table. */
3112 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
3113 if (! stable)
3114 return -1;
3115
3116 /* Lookup static route prefix. */
3117 rn = route_node_lookup (stable, p);
3118 if (! rn)
3119 return 0;
3120
3121 /* Find same static route is the tree */
3122 for (si = rn->info; si; si = si->next)
3123 if (distance == si->distance
3124 && type == si->type
3125 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
3126 && (! ifname || strcmp (ifname, si->ifname) == 0))
3127 break;
3128
3129 /* Can't find static route. */
3130 if (! si)
3131 {
3132 route_unlock_node (rn);
3133 return 0;
3134 }
3135
3136 /* Install into rib. */
3137 static_uninstall_ipv6 (p, si);
3138
3139 /* Unlink static route from linked list. */
3140 if (si->prev)
3141 si->prev->next = si->next;
3142 else
3143 rn->info = si->next;
3144 if (si->next)
3145 si->next->prev = si->prev;
3146
3147 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00003148 if (ifname)
3149 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00003150 XFREE (MTYPE_STATIC_IPV6, si);
3151
3152 return 1;
3153}
3154#endif /* HAVE_IPV6 */
David Lamparter6b0655a2014-06-04 06:53:35 +02003155
paul718e3742002-12-13 20:15:29 +00003156/* RIB update function. */
3157void
paula1ac18c2005-06-28 17:17:12 +00003158rib_update (void)
paul718e3742002-12-13 20:15:29 +00003159{
3160 struct route_node *rn;
3161 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00003162
paul718e3742002-12-13 20:15:29 +00003163 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
3164 if (table)
3165 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003166 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003167 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003168
3169 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
3170 if (table)
3171 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003172 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003173 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003174}
3175
David Lamparter6b0655a2014-06-04 06:53:35 +02003176
paul718e3742002-12-13 20:15:29 +00003177/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00003178static void
paul718e3742002-12-13 20:15:29 +00003179rib_weed_table (struct route_table *table)
3180{
3181 struct route_node *rn;
3182 struct rib *rib;
3183 struct rib *next;
3184
3185 if (table)
3186 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003187 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003188 {
Paul Jakma6d691122006-07-27 21:49:00 +00003189 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3190 continue;
3191
paulb21b19c2003-06-15 01:28:29 +00003192 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00003193 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00003194 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003195 }
3196}
3197
3198/* Delete all routes from non main table. */
3199void
paula1ac18c2005-06-28 17:17:12 +00003200rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00003201{
3202 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3203 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3204}
David Lamparter6b0655a2014-06-04 06:53:35 +02003205
paul718e3742002-12-13 20:15:29 +00003206/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00003207static void
paul718e3742002-12-13 20:15:29 +00003208rib_sweep_table (struct route_table *table)
3209{
3210 struct route_node *rn;
3211 struct rib *rib;
3212 struct rib *next;
3213 int ret = 0;
3214
3215 if (table)
3216 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003217 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003218 {
Paul Jakma6d691122006-07-27 21:49:00 +00003219 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3220 continue;
3221
paul718e3742002-12-13 20:15:29 +00003222 if (rib->type == ZEBRA_ROUTE_KERNEL &&
3223 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
3224 {
3225 ret = rib_uninstall_kernel (rn, rib);
3226 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00003227 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003228 }
3229 }
3230}
3231
3232/* Sweep all RIB tables. */
3233void
paula1ac18c2005-06-28 17:17:12 +00003234rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00003235{
3236 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3237 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3238}
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003239
3240/* Remove specific by protocol routes from 'table'. */
3241static unsigned long
3242rib_score_proto_table (u_char proto, struct route_table *table)
3243{
3244 struct route_node *rn;
3245 struct rib *rib;
3246 struct rib *next;
3247 unsigned long n = 0;
3248
3249 if (table)
3250 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003251 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003252 {
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003253 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3254 continue;
3255 if (rib->type == proto)
3256 {
3257 rib_delnode (rn, rib);
3258 n++;
3259 }
3260 }
3261
3262 return n;
3263}
3264
3265/* Remove specific by protocol routes. */
3266unsigned long
3267rib_score_proto (u_char proto)
3268{
3269 return rib_score_proto_table (proto, vrf_table (AFI_IP, SAFI_UNICAST, 0))
3270 +rib_score_proto_table (proto, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3271}
3272
paul718e3742002-12-13 20:15:29 +00003273/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00003274static void
paul718e3742002-12-13 20:15:29 +00003275rib_close_table (struct route_table *table)
3276{
3277 struct route_node *rn;
3278 struct rib *rib;
3279
3280 if (table)
3281 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003282 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00003283 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003284 if (!CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
3285 continue;
3286
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00003287 zfpm_trigger_update (rn, NULL);
3288
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003289 if (! RIB_SYSTEM_ROUTE (rib))
3290 rib_uninstall_kernel (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00003291 }
paul718e3742002-12-13 20:15:29 +00003292}
3293
3294/* Close all RIB tables. */
3295void
paula1ac18c2005-06-28 17:17:12 +00003296rib_close (void)
paul718e3742002-12-13 20:15:29 +00003297{
3298 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3299 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3300}
David Lamparter6b0655a2014-06-04 06:53:35 +02003301
paul718e3742002-12-13 20:15:29 +00003302/* Routing information base initialize. */
3303void
paula1ac18c2005-06-28 17:17:12 +00003304rib_init (void)
paul718e3742002-12-13 20:15:29 +00003305{
paul4d38fdb2005-04-28 17:35:14 +00003306 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00003307 /* VRF initialization. */
3308 vrf_init ();
3309}
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003310
3311/*
3312 * vrf_id_get_next
3313 *
3314 * Get the first vrf id that is greater than the given vrf id if any.
3315 *
3316 * Returns TRUE if a vrf id was found, FALSE otherwise.
3317 */
3318static inline int
3319vrf_id_get_next (uint32_t id, uint32_t *next_id_p)
3320{
3321 while (++id < vector_active (vrf_vector))
3322 {
3323 if (vrf_lookup (id))
3324 {
3325 *next_id_p = id;
3326 return 1;
3327 }
3328 }
3329
3330 return 0;
3331}
3332
3333/*
3334 * rib_tables_iter_next
3335 *
3336 * Returns the next table in the iteration.
3337 */
3338struct route_table *
3339rib_tables_iter_next (rib_tables_iter_t *iter)
3340{
3341 struct route_table *table;
3342
3343 /*
3344 * Array that helps us go over all AFI/SAFI combinations via one
3345 * index.
3346 */
3347 static struct {
3348 afi_t afi;
3349 safi_t safi;
3350 } afi_safis[] = {
3351 { AFI_IP, SAFI_UNICAST },
3352 { AFI_IP, SAFI_MULTICAST },
3353 { AFI_IP6, SAFI_UNICAST },
3354 { AFI_IP6, SAFI_MULTICAST },
3355 };
3356
3357 table = NULL;
3358
3359 switch (iter->state)
3360 {
3361
3362 case RIB_TABLES_ITER_S_INIT:
3363 iter->vrf_id = 0;
3364 iter->afi_safi_ix = -1;
3365
3366 /* Fall through */
3367
3368 case RIB_TABLES_ITER_S_ITERATING:
3369 iter->afi_safi_ix++;
3370 while (1)
3371 {
3372
3373 while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
3374 {
3375 table = vrf_table (afi_safis[iter->afi_safi_ix].afi,
3376 afi_safis[iter->afi_safi_ix].safi,
3377 iter->vrf_id);
3378 if (table)
3379 break;
3380
3381 iter->afi_safi_ix++;
3382 }
3383
3384 /*
3385 * Found another table in this vrf.
3386 */
3387 if (table)
3388 break;
3389
3390 /*
3391 * Done with all tables in the current vrf, go to the next
3392 * one.
3393 */
3394 if (!vrf_id_get_next (iter->vrf_id, &iter->vrf_id))
3395 break;
3396
3397 iter->afi_safi_ix = 0;
3398 }
3399
3400 break;
3401
3402 case RIB_TABLES_ITER_S_DONE:
3403 return NULL;
3404 }
3405
3406 if (table)
3407 iter->state = RIB_TABLES_ITER_S_ITERATING;
3408 else
3409 iter->state = RIB_TABLES_ITER_S_DONE;
3410
3411 return table;
3412}