blob: 469c10b216e6ca7721c96d405194135d29ac6950 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* Routing Information Base.
2 * Copyright (C) 1997, 98, 99, 2001 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "prefix.h"
25#include "table.h"
26#include "memory.h"
27#include "str.h"
28#include "command.h"
29#include "if.h"
30#include "log.h"
31#include "sockunion.h"
paul4d38fdb2005-04-28 17:35:14 +000032#include "linklist.h"
33#include "thread.h"
34#include "workqueue.h"
Paul Jakma7514fb72007-05-02 16:05:35 +000035#include "prefix.h"
36#include "routemap.h"
paul718e3742002-12-13 20:15:29 +000037
38#include "zebra/rib.h"
39#include "zebra/rt.h"
40#include "zebra/zserv.h"
41#include "zebra/redistribute.h"
42#include "zebra/debug.h"
Avneesh Sachdev5adc2522012-11-13 22:48:59 +000043#include "zebra/zebra_fpm.h"
paul718e3742002-12-13 20:15:29 +000044
45/* Default rtm_table for all clients */
paulb21b19c2003-06-15 01:28:29 +000046extern struct zebra_t zebrad;
paul718e3742002-12-13 20:15:29 +000047
Paul Jakma457eb9a2006-07-27 19:59:58 +000048/* Hold time for RIB process, should be very minimal.
49 * it is useful to able to set it otherwise for testing, hence exported
50 * as global here for test-rig code.
51 */
52int rib_process_hold_time = 10;
53
paul718e3742002-12-13 20:15:29 +000054/* Each route type's string and default distance value. */
Stephen Hemmingerd145bc02008-08-17 17:41:37 +010055static const struct
paul718e3742002-12-13 20:15:29 +000056{
57 int key;
58 int distance;
Paul Jakma57345092011-12-25 17:52:09 +010059} route_info[ZEBRA_ROUTE_MAX] =
paul718e3742002-12-13 20:15:29 +000060{
Paul Jakma57345092011-12-25 17:52:09 +010061 [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0},
62 [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0},
63 [ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0},
64 [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1},
65 [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120},
66 [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120},
67 [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110},
68 [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110},
69 [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115},
70 [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */},
71 [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 95},
David Lamparter7052f222009-08-27 00:28:28 +020072 /* no entry/default: 150 */
paul718e3742002-12-13 20:15:29 +000073};
David Lamparter6b0655a2014-06-04 06:53:35 +020074
paul718e3742002-12-13 20:15:29 +000075/* Vector for routing table. */
Stephen Hemmingerd145bc02008-08-17 17:41:37 +010076static vector vrf_vector;
paul718e3742002-12-13 20:15:29 +000077
David Lampartere0b0ac82014-04-24 20:22:53 +020078static void
79_rnode_zlog(const char *_func, struct route_node *rn, int priority,
80 const char *msgfmt, ...)
81{
82 char buf[INET6_ADDRSTRLEN + 4], *bptr;
83 char msgbuf[512];
84 va_list ap;
85
86 va_start(ap, msgfmt);
87 vsnprintf(msgbuf, sizeof(msgbuf), msgfmt, ap);
88 va_end(ap);
89
90 if (rn)
91 {
David Lamparterf7b3d1e2015-01-22 19:02:13 +010092 rib_table_info_t *info = rn->table->info;
93
David Lampartere0b0ac82014-04-24 20:22:53 +020094 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
95 bptr = buf + strlen(buf);
David Lamparterf7b3d1e2015-01-22 19:02:13 +010096 snprintf(bptr, buf + sizeof(buf) - bptr, "/%d%s", rn->p.prefixlen,
97 info->safi == SAFI_MULTICAST ? " (MRIB)" : "");
David Lampartere0b0ac82014-04-24 20:22:53 +020098 }
99 else
100 {
101 snprintf(buf, sizeof(buf), "{(route_node *) NULL}");
102 }
103
104 zlog (NULL, priority, "%s: %s: %s", _func, buf, msgbuf);
105}
106
107#define rnode_debug(node, ...) \
108 _rnode_zlog(__func__, node, LOG_DEBUG, __VA_ARGS__)
109#define rnode_info(node, ...) \
110 _rnode_zlog(__func__, node, LOG_INFO, __VA_ARGS__)
111
Avneesh Sachdev1b5ed1b2012-11-13 22:48:54 +0000112/*
113 * vrf_table_create
114 */
115static void
116vrf_table_create (struct vrf *vrf, afi_t afi, safi_t safi)
117{
118 rib_table_info_t *info;
119 struct route_table *table;
120
121 assert (!vrf->table[afi][safi]);
122
123 table = route_table_init ();
124 vrf->table[afi][safi] = table;
125
126 info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
127 info->vrf = vrf;
128 info->afi = afi;
129 info->safi = safi;
130 table->info = info;
131}
132
paul718e3742002-12-13 20:15:29 +0000133/* Allocate new VRF. */
paula1ac18c2005-06-28 17:17:12 +0000134static struct vrf *
hassofce954f2004-10-07 20:29:24 +0000135vrf_alloc (const char *name)
paul718e3742002-12-13 20:15:29 +0000136{
137 struct vrf *vrf;
138
139 vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
140
141 /* Put name. */
142 if (name)
143 vrf->name = XSTRDUP (MTYPE_VRF_NAME, name);
144
145 /* Allocate routing table and static table. */
Avneesh Sachdev1b5ed1b2012-11-13 22:48:54 +0000146 vrf_table_create (vrf, AFI_IP, SAFI_UNICAST);
147 vrf_table_create (vrf, AFI_IP6, SAFI_UNICAST);
paul718e3742002-12-13 20:15:29 +0000148 vrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
149 vrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
Avneesh Sachdev1b5ed1b2012-11-13 22:48:54 +0000150 vrf_table_create (vrf, AFI_IP, SAFI_MULTICAST);
151 vrf_table_create (vrf, AFI_IP6, SAFI_MULTICAST);
G.Balajicddf3912011-11-26 21:59:32 +0400152 vrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
153 vrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
154
paul718e3742002-12-13 20:15:29 +0000155
156 return vrf;
157}
158
paul718e3742002-12-13 20:15:29 +0000159/* Lookup VRF by identifier. */
160struct vrf *
161vrf_lookup (u_int32_t id)
162{
163 return vector_lookup (vrf_vector, id);
164}
165
paul718e3742002-12-13 20:15:29 +0000166/* Initialize VRF. */
paula1ac18c2005-06-28 17:17:12 +0000167static void
168vrf_init (void)
paul718e3742002-12-13 20:15:29 +0000169{
170 struct vrf *default_table;
171
172 /* Allocate VRF vector. */
173 vrf_vector = vector_init (1);
174
175 /* Allocate default main table. */
176 default_table = vrf_alloc ("Default-IP-Routing-Table");
177
178 /* Default table index must be 0. */
179 vector_set_index (vrf_vector, 0, default_table);
180}
181
182/* Lookup route table. */
183struct route_table *
184vrf_table (afi_t afi, safi_t safi, u_int32_t id)
185{
186 struct vrf *vrf;
187
188 vrf = vrf_lookup (id);
189 if (! vrf)
190 return NULL;
191
Leonid Rosenboim9499bf22012-12-06 20:17:41 +0000192 if( afi >= AFI_MAX || safi >= SAFI_MAX )
193 return NULL;
194
paul718e3742002-12-13 20:15:29 +0000195 return vrf->table[afi][safi];
196}
197
198/* Lookup static route table. */
199struct route_table *
200vrf_static_table (afi_t afi, safi_t safi, u_int32_t id)
201{
202 struct vrf *vrf;
203
204 vrf = vrf_lookup (id);
205 if (! vrf)
206 return NULL;
207
Leonid Rosenboim9499bf22012-12-06 20:17:41 +0000208 if( afi >= AFI_MAX || safi >= SAFI_MAX )
209 return NULL;
210
paul718e3742002-12-13 20:15:29 +0000211 return vrf->stable[afi][safi];
212}
David Lamparter6b0655a2014-06-04 06:53:35 +0200213
Avneesh Sachdev78deec42012-11-13 22:48:56 +0000214/*
215 * nexthop_type_to_str
216 */
217const char *
218nexthop_type_to_str (enum nexthop_types_t nh_type)
219{
220 static const char *desc[] = {
221 "none",
222 "Directly connected",
223 "Interface route",
224 "IPv4 nexthop",
225 "IPv4 nexthop with ifindex",
226 "IPv4 nexthop with ifname",
227 "IPv6 nexthop",
228 "IPv6 nexthop with ifindex",
229 "IPv6 nexthop with ifname",
230 "Null0 nexthop",
231 };
232
233 if (nh_type >= ZEBRA_NUM_OF (desc))
234 return "<Invalid nh type>";
235
236 return desc[nh_type];
237}
238
Christian Frankefa713d92013-07-05 15:35:37 +0000239/* Add nexthop to the end of a nexthop list. */
paula1ac18c2005-06-28 17:17:12 +0000240static void
Christian Frankefa713d92013-07-05 15:35:37 +0000241_nexthop_add (struct nexthop **target, struct nexthop *nexthop)
paul718e3742002-12-13 20:15:29 +0000242{
243 struct nexthop *last;
244
Christian Frankefa713d92013-07-05 15:35:37 +0000245 for (last = *target; last && last->next; last = last->next)
paul718e3742002-12-13 20:15:29 +0000246 ;
247 if (last)
248 last->next = nexthop;
249 else
Christian Frankefa713d92013-07-05 15:35:37 +0000250 *target = nexthop;
paul718e3742002-12-13 20:15:29 +0000251 nexthop->prev = last;
Christian Frankefa713d92013-07-05 15:35:37 +0000252}
paul718e3742002-12-13 20:15:29 +0000253
Christian Frankefa713d92013-07-05 15:35:37 +0000254/* Add nexthop to the end of a rib node's nexthop list */
255static void
256nexthop_add (struct rib *rib, struct nexthop *nexthop)
257{
258 _nexthop_add(&rib->nexthop, nexthop);
paul718e3742002-12-13 20:15:29 +0000259 rib->nexthop_num++;
260}
261
262/* Delete specified nexthop from the list. */
paula1ac18c2005-06-28 17:17:12 +0000263static void
paul718e3742002-12-13 20:15:29 +0000264nexthop_delete (struct rib *rib, struct nexthop *nexthop)
265{
266 if (nexthop->next)
267 nexthop->next->prev = nexthop->prev;
268 if (nexthop->prev)
269 nexthop->prev->next = nexthop->next;
270 else
271 rib->nexthop = nexthop->next;
272 rib->nexthop_num--;
273}
274
Christian Frankefa713d92013-07-05 15:35:37 +0000275static void nexthops_free(struct nexthop *nexthop);
276
paul718e3742002-12-13 20:15:29 +0000277/* Free nexthop. */
paula1ac18c2005-06-28 17:17:12 +0000278static void
paul718e3742002-12-13 20:15:29 +0000279nexthop_free (struct nexthop *nexthop)
280{
paula4b70762003-05-16 17:19:48 +0000281 if (nexthop->ifname)
282 XFREE (0, nexthop->ifname);
Christian Frankefa713d92013-07-05 15:35:37 +0000283 if (nexthop->resolved)
284 nexthops_free(nexthop->resolved);
paul718e3742002-12-13 20:15:29 +0000285 XFREE (MTYPE_NEXTHOP, nexthop);
286}
287
Christian Frankefa713d92013-07-05 15:35:37 +0000288/* Frees a list of nexthops */
289static void
290nexthops_free (struct nexthop *nexthop)
291{
292 struct nexthop *nh, *next;
293
294 for (nh = nexthop; nh; nh = next)
295 {
296 next = nh->next;
297 nexthop_free (nh);
298 }
299}
300
paul718e3742002-12-13 20:15:29 +0000301struct nexthop *
302nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
303{
304 struct nexthop *nexthop;
305
Stephen Hemminger393deb92008-08-18 14:13:29 -0700306 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000307 nexthop->type = NEXTHOP_TYPE_IFINDEX;
308 nexthop->ifindex = ifindex;
309
310 nexthop_add (rib, nexthop);
311
312 return nexthop;
313}
314
315struct nexthop *
316nexthop_ifname_add (struct rib *rib, char *ifname)
317{
318 struct nexthop *nexthop;
319
Stephen Hemminger393deb92008-08-18 14:13:29 -0700320 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000321 nexthop->type = NEXTHOP_TYPE_IFNAME;
paula4b70762003-05-16 17:19:48 +0000322 nexthop->ifname = XSTRDUP (0, ifname);
paul718e3742002-12-13 20:15:29 +0000323
324 nexthop_add (rib, nexthop);
325
326 return nexthop;
327}
328
329struct nexthop *
Paul Jakma7514fb72007-05-02 16:05:35 +0000330nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src)
paul718e3742002-12-13 20:15:29 +0000331{
332 struct nexthop *nexthop;
333
Stephen Hemminger393deb92008-08-18 14:13:29 -0700334 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000335 nexthop->type = NEXTHOP_TYPE_IPV4;
336 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000337 if (src)
338 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000339
340 nexthop_add (rib, nexthop);
341
342 return nexthop;
343}
344
Josh Bailey26e2ae32012-03-22 01:09:21 -0700345struct nexthop *
paul718e3742002-12-13 20:15:29 +0000346nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
Paul Jakma7514fb72007-05-02 16:05:35 +0000347 struct in_addr *src, unsigned int ifindex)
paul718e3742002-12-13 20:15:29 +0000348{
349 struct nexthop *nexthop;
350
Stephen Hemminger393deb92008-08-18 14:13:29 -0700351 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000352 nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
353 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000354 if (src)
355 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000356 nexthop->ifindex = ifindex;
357
358 nexthop_add (rib, nexthop);
359
360 return nexthop;
361}
362
363#ifdef HAVE_IPV6
364struct nexthop *
365nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
366{
367 struct nexthop *nexthop;
368
Stephen Hemminger393deb92008-08-18 14:13:29 -0700369 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000370 nexthop->type = NEXTHOP_TYPE_IPV6;
371 nexthop->gate.ipv6 = *ipv6;
372
373 nexthop_add (rib, nexthop);
374
375 return nexthop;
376}
377
paula1ac18c2005-06-28 17:17:12 +0000378static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000379nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
380 char *ifname)
381{
382 struct nexthop *nexthop;
383
Stephen Hemminger393deb92008-08-18 14:13:29 -0700384 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000385 nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
386 nexthop->gate.ipv6 = *ipv6;
387 nexthop->ifname = XSTRDUP (0, ifname);
388
389 nexthop_add (rib, nexthop);
390
391 return nexthop;
392}
393
paula1ac18c2005-06-28 17:17:12 +0000394static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000395nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
396 unsigned int ifindex)
397{
398 struct nexthop *nexthop;
399
Stephen Hemminger393deb92008-08-18 14:13:29 -0700400 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000401 nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
402 nexthop->gate.ipv6 = *ipv6;
403 nexthop->ifindex = ifindex;
404
405 nexthop_add (rib, nexthop);
406
407 return nexthop;
408}
409#endif /* HAVE_IPV6 */
410
paul595db7f2003-05-25 21:35:06 +0000411struct nexthop *
412nexthop_blackhole_add (struct rib *rib)
413{
414 struct nexthop *nexthop;
415
Stephen Hemminger393deb92008-08-18 14:13:29 -0700416 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul595db7f2003-05-25 21:35:06 +0000417 nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
418 SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
419
420 nexthop_add (rib, nexthop);
421
422 return nexthop;
423}
424
Christian Frankefa713d92013-07-05 15:35:37 +0000425/* This method checks whether a recursive nexthop has at
426 * least one resolved nexthop in the fib.
427 */
428int
429nexthop_has_fib_child(struct nexthop *nexthop)
430{
431 struct nexthop *nh;
432
433 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
434 return 0;
435
436 for (nh = nexthop->resolved; nh; nh = nh->next)
437 if (CHECK_FLAG (nh->flags, NEXTHOP_FLAG_FIB))
438 return 1;
439
440 return 0;
441}
442
paul718e3742002-12-13 20:15:29 +0000443/* If force flag is not set, do not modify falgs at all for uninstall
444 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000445static int
paul718e3742002-12-13 20:15:29 +0000446nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
447 struct route_node *top)
448{
449 struct prefix_ipv4 p;
450 struct route_table *table;
451 struct route_node *rn;
452 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000453 int resolved;
paul718e3742002-12-13 20:15:29 +0000454 struct nexthop *newhop;
Christian Frankefa713d92013-07-05 15:35:37 +0000455 struct nexthop *resolved_hop;
paul718e3742002-12-13 20:15:29 +0000456
457 if (nexthop->type == NEXTHOP_TYPE_IPV4)
458 nexthop->ifindex = 0;
459
460 if (set)
Christian Frankefa713d92013-07-05 15:35:37 +0000461 {
462 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
463 nexthops_free(nexthop->resolved);
464 nexthop->resolved = NULL;
465 }
paul718e3742002-12-13 20:15:29 +0000466
467 /* Make lookup prefix. */
468 memset (&p, 0, sizeof (struct prefix_ipv4));
469 p.family = AF_INET;
470 p.prefixlen = IPV4_MAX_PREFIXLEN;
471 p.prefix = nexthop->gate.ipv4;
472
473 /* Lookup table. */
474 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
475 if (! table)
476 return 0;
477
478 rn = route_node_match (table, (struct prefix *) &p);
479 while (rn)
480 {
481 route_unlock_node (rn);
482
David Warda50c1072009-12-03 15:34:39 +0300483 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000484 if (rn == top)
485 return 0;
486
487 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000488 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100489 {
490 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
491 continue;
492 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
493 break;
494 }
paul718e3742002-12-13 20:15:29 +0000495
496 /* If there is no selected route or matched route is EGP, go up
497 tree. */
498 if (! match
499 || match->type == ZEBRA_ROUTE_BGP)
500 {
501 do {
502 rn = rn->parent;
503 } while (rn && rn->info == NULL);
504 if (rn)
505 route_lock_node (rn);
506 }
507 else
508 {
Christian Franke48a53dc2013-07-05 15:35:38 +0000509 /* If the longest prefix match for the nexthop yields
510 * a blackhole, mark it as inactive. */
511 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE)
512 || CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT))
513 return 0;
514
paul718e3742002-12-13 20:15:29 +0000515 if (match->type == ZEBRA_ROUTE_CONNECT)
516 {
517 /* Directly point connected route. */
518 newhop = match->nexthop;
519 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
520 nexthop->ifindex = newhop->ifindex;
521
522 return 1;
523 }
524 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
525 {
Christian Frankefa713d92013-07-05 15:35:37 +0000526 resolved = 0;
paul718e3742002-12-13 20:15:29 +0000527 for (newhop = match->nexthop; newhop; newhop = newhop->next)
528 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
529 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
530 {
531 if (set)
532 {
533 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
Christian Frankefa713d92013-07-05 15:35:37 +0000534
535 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
536 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
Christian Frankec3e6b592013-07-05 15:35:40 +0000537 /* If the resolving route specifies a gateway, use it */
538 if (newhop->type == NEXTHOP_TYPE_IPV4
539 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX
540 || newhop->type == NEXTHOP_TYPE_IPV4_IFNAME)
541 {
542 resolved_hop->type = newhop->type;
543 resolved_hop->gate.ipv4 = newhop->gate.ipv4;
Christian Frankefa713d92013-07-05 15:35:37 +0000544
Christian Frankec3e6b592013-07-05 15:35:40 +0000545 if (newhop->ifindex)
546 {
547 resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
548 resolved_hop->ifindex = newhop->ifindex;
549 }
550 }
Christian Frankefa713d92013-07-05 15:35:37 +0000551
Christian Frankec3e6b592013-07-05 15:35:40 +0000552 /* If the resolving route is an interface route,
553 * it means the gateway we are looking up is connected
554 * to that interface. (The actual network is _not_ onlink).
555 * Therefore, the resolved route should have the original
556 * gateway as nexthop as it is directly connected.
557 *
558 * On Linux, we have to set the onlink netlink flag because
559 * otherwise, the kernel won't accept the route. */
paul718e3742002-12-13 20:15:29 +0000560 if (newhop->type == NEXTHOP_TYPE_IFINDEX
Christian Frankec3e6b592013-07-05 15:35:40 +0000561 || newhop->type == NEXTHOP_TYPE_IFNAME)
562 {
563 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
564 resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
565 resolved_hop->gate.ipv4 = nexthop->gate.ipv4;
566 resolved_hop->ifindex = newhop->ifindex;
567 }
Christian Frankefa713d92013-07-05 15:35:37 +0000568
569 _nexthop_add(&nexthop->resolved, resolved_hop);
paul718e3742002-12-13 20:15:29 +0000570 }
Christian Frankefa713d92013-07-05 15:35:37 +0000571 resolved = 1;
paul718e3742002-12-13 20:15:29 +0000572 }
Christian Frankefa713d92013-07-05 15:35:37 +0000573 return resolved;
paul718e3742002-12-13 20:15:29 +0000574 }
575 else
576 {
577 return 0;
578 }
579 }
580 }
581 return 0;
582}
583
584#ifdef HAVE_IPV6
585/* If force flag is not set, do not modify falgs at all for uninstall
586 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000587static int
paul718e3742002-12-13 20:15:29 +0000588nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
589 struct route_node *top)
590{
591 struct prefix_ipv6 p;
592 struct route_table *table;
593 struct route_node *rn;
594 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000595 int resolved;
paul718e3742002-12-13 20:15:29 +0000596 struct nexthop *newhop;
Christian Frankefa713d92013-07-05 15:35:37 +0000597 struct nexthop *resolved_hop;
paul718e3742002-12-13 20:15:29 +0000598
599 if (nexthop->type == NEXTHOP_TYPE_IPV6)
600 nexthop->ifindex = 0;
601
602 if (set)
Christian Frankefa713d92013-07-05 15:35:37 +0000603 {
604 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
605 nexthops_free(nexthop->resolved);
606 nexthop->resolved = NULL;
607 }
paul718e3742002-12-13 20:15:29 +0000608
609 /* Make lookup prefix. */
610 memset (&p, 0, sizeof (struct prefix_ipv6));
611 p.family = AF_INET6;
612 p.prefixlen = IPV6_MAX_PREFIXLEN;
613 p.prefix = nexthop->gate.ipv6;
614
615 /* Lookup table. */
616 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
617 if (! table)
618 return 0;
619
620 rn = route_node_match (table, (struct prefix *) &p);
621 while (rn)
622 {
623 route_unlock_node (rn);
624
David Warda50c1072009-12-03 15:34:39 +0300625 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000626 if (rn == top)
627 return 0;
628
629 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000630 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100631 {
632 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
633 continue;
634 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
635 break;
636 }
paul718e3742002-12-13 20:15:29 +0000637
638 /* If there is no selected route or matched route is EGP, go up
639 tree. */
640 if (! match
641 || match->type == ZEBRA_ROUTE_BGP)
642 {
643 do {
644 rn = rn->parent;
645 } while (rn && rn->info == NULL);
646 if (rn)
647 route_lock_node (rn);
648 }
649 else
650 {
Christian Franke48a53dc2013-07-05 15:35:38 +0000651 /* If the longest prefix match for the nexthop yields
652 * a blackhole, mark it as inactive. */
653 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE)
654 || CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT))
655 return 0;
656
paul718e3742002-12-13 20:15:29 +0000657 if (match->type == ZEBRA_ROUTE_CONNECT)
658 {
659 /* Directly point connected route. */
660 newhop = match->nexthop;
661
662 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
663 nexthop->ifindex = newhop->ifindex;
664
665 return 1;
666 }
667 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
668 {
Christian Frankefa713d92013-07-05 15:35:37 +0000669 resolved = 0;
paul718e3742002-12-13 20:15:29 +0000670 for (newhop = match->nexthop; newhop; newhop = newhop->next)
671 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
672 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
673 {
674 if (set)
675 {
676 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
Christian Frankefa713d92013-07-05 15:35:37 +0000677
678 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
679 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
Christian Frankec3e6b592013-07-05 15:35:40 +0000680 /* See nexthop_active_ipv4 for a description how the
681 * resolved nexthop is constructed. */
paul718e3742002-12-13 20:15:29 +0000682 if (newhop->type == NEXTHOP_TYPE_IPV6
683 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
684 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
Christian Frankec3e6b592013-07-05 15:35:40 +0000685 {
686 resolved_hop->type = newhop->type;
687 resolved_hop->gate.ipv6 = newhop->gate.ipv6;
688
689 if (newhop->ifindex)
690 {
691 resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
692 resolved_hop->ifindex = newhop->ifindex;
693 }
694 }
Christian Frankefa713d92013-07-05 15:35:37 +0000695
paul718e3742002-12-13 20:15:29 +0000696 if (newhop->type == NEXTHOP_TYPE_IFINDEX
Christian Frankec3e6b592013-07-05 15:35:40 +0000697 || newhop->type == NEXTHOP_TYPE_IFNAME)
698 {
699 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
700 resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
701 resolved_hop->gate.ipv6 = nexthop->gate.ipv6;
702 resolved_hop->ifindex = newhop->ifindex;
703 }
Christian Frankefa713d92013-07-05 15:35:37 +0000704
705 _nexthop_add(&nexthop->resolved, resolved_hop);
paul718e3742002-12-13 20:15:29 +0000706 }
Christian Frankefa713d92013-07-05 15:35:37 +0000707 resolved = 1;
paul718e3742002-12-13 20:15:29 +0000708 }
Christian Frankefa713d92013-07-05 15:35:37 +0000709 return resolved;
paul718e3742002-12-13 20:15:29 +0000710 }
711 else
712 {
713 return 0;
714 }
715 }
716 }
717 return 0;
718}
719#endif /* HAVE_IPV6 */
720
721struct rib *
722rib_match_ipv4 (struct in_addr addr)
723{
Everton Marquesa59b6152014-11-21 15:57:45 -0800724 return rib_match_ipv4_safi (addr, SAFI_UNICAST);
paul718e3742002-12-13 20:15:29 +0000725}
726
727struct rib *
Everton Marques346a8b52014-09-22 19:35:51 -0300728rib_match_ipv4_safi (struct in_addr addr, safi_t safi)
729{
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. */
758 if (! match
759 || match->type == ZEBRA_ROUTE_BGP)
760 {
761 do {
762 rn = rn->parent;
763 } while (rn && rn->info == NULL);
764 if (rn)
765 route_lock_node (rn);
766 }
767 else
768 {
769 if (match->type == ZEBRA_ROUTE_CONNECT)
770 /* Directly point connected route. */
771 return match;
772 else
773 {
774 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
775 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
776 return match;
777 return NULL;
778 }
779 }
780 }
781 return NULL;
782}
783
784struct rib *
paul718e3742002-12-13 20:15:29 +0000785rib_lookup_ipv4 (struct prefix_ipv4 *p)
786{
787 struct route_table *table;
788 struct route_node *rn;
789 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000790 struct nexthop *nexthop, *tnexthop;
791 int recursing;
paul718e3742002-12-13 20:15:29 +0000792
793 /* Lookup table. */
794 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
795 if (! table)
796 return 0;
797
798 rn = route_node_lookup (table, (struct prefix *) p);
799
800 /* No route for this prefix. */
801 if (! rn)
802 return NULL;
803
804 /* Unlock node. */
805 route_unlock_node (rn);
806
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000807 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100808 {
809 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
810 continue;
811 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
812 break;
813 }
paul718e3742002-12-13 20:15:29 +0000814
815 if (! match || match->type == ZEBRA_ROUTE_BGP)
816 return NULL;
817
818 if (match->type == ZEBRA_ROUTE_CONNECT)
819 return match;
820
Christian Frankefa713d92013-07-05 15:35:37 +0000821 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +0000822 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
823 return match;
824
825 return NULL;
826}
827
Denis Ovsienkodc958242007-08-13 16:03:06 +0000828/*
829 * This clone function, unlike its original rib_lookup_ipv4(), checks
830 * if specified IPv4 route record (prefix/mask -> gate) exists in
831 * the whole RIB and has ZEBRA_FLAG_SELECTED set.
832 *
833 * Return values:
834 * -1: error
835 * 0: exact match found
836 * 1: a match was found with a different gate
837 * 2: connected route found
838 * 3: no matches found
839 */
840int
841rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
842{
843 struct route_table *table;
844 struct route_node *rn;
845 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000846 struct nexthop *nexthop, *tnexthop;
847 int recursing;
848 int nexthops_active;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000849
850 /* Lookup table. */
851 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
852 if (! table)
853 return ZEBRA_RIB_LOOKUP_ERROR;
854
855 /* Scan the RIB table for exactly matching RIB entry. */
856 rn = route_node_lookup (table, (struct prefix *) p);
857
858 /* No route for this prefix. */
859 if (! rn)
860 return ZEBRA_RIB_NOTFOUND;
861
862 /* Unlock node. */
863 route_unlock_node (rn);
864
865 /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000866 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100867 {
868 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
869 continue;
870 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
871 break;
872 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000873
874 /* None such found :( */
875 if (!match)
876 return ZEBRA_RIB_NOTFOUND;
877
878 if (match->type == ZEBRA_ROUTE_CONNECT)
879 return ZEBRA_RIB_FOUND_CONNECTED;
880
881 /* Ok, we have a cood candidate, let's check it's nexthop list... */
Christian Frankefa713d92013-07-05 15:35:37 +0000882 nexthops_active = 0;
883 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000884 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000885 {
Christian Frankefa713d92013-07-05 15:35:37 +0000886 nexthops_active = 1;
887 if (nexthop->gate.ipv4.s_addr == sockunion2ip (qgate))
888 return ZEBRA_RIB_FOUND_EXACT;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000889 if (IS_ZEBRA_DEBUG_RIB)
Christian Frankefa713d92013-07-05 15:35:37 +0000890 {
891 char gate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
892 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
893 inet_ntop (AF_INET, &sockunion2ip(qgate), qgate_buf, INET_ADDRSTRLEN);
894 zlog_debug ("%s: qgate == %s, %s == %s", __func__,
895 qgate_buf, recursing ? "rgate" : "gate", gate_buf);
896 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000897 }
Christian Frankefa713d92013-07-05 15:35:37 +0000898
899 if (nexthops_active)
900 return ZEBRA_RIB_FOUND_NOGATE;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000901
902 return ZEBRA_RIB_NOTFOUND;
903}
904
paul718e3742002-12-13 20:15:29 +0000905#ifdef HAVE_IPV6
906struct rib *
907rib_match_ipv6 (struct in6_addr *addr)
908{
909 struct prefix_ipv6 p;
910 struct route_table *table;
911 struct route_node *rn;
912 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000913 struct nexthop *newhop, *tnewhop;
914 int recursing;
paul718e3742002-12-13 20:15:29 +0000915
916 /* Lookup table. */
917 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
918 if (! table)
919 return 0;
920
921 memset (&p, 0, sizeof (struct prefix_ipv6));
922 p.family = AF_INET6;
923 p.prefixlen = IPV6_MAX_PREFIXLEN;
924 IPV6_ADDR_COPY (&p.prefix, addr);
925
926 rn = route_node_match (table, (struct prefix *) &p);
927
928 while (rn)
929 {
930 route_unlock_node (rn);
931
932 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000933 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100934 {
935 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
936 continue;
937 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
938 break;
939 }
paul718e3742002-12-13 20:15:29 +0000940
941 /* If there is no selected route or matched route is EGP, go up
942 tree. */
943 if (! match
944 || match->type == ZEBRA_ROUTE_BGP)
945 {
946 do {
947 rn = rn->parent;
948 } while (rn && rn->info == NULL);
949 if (rn)
950 route_lock_node (rn);
951 }
952 else
953 {
954 if (match->type == ZEBRA_ROUTE_CONNECT)
955 /* Directly point connected route. */
956 return match;
957 else
958 {
Christian Frankefa713d92013-07-05 15:35:37 +0000959 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
paul718e3742002-12-13 20:15:29 +0000960 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
961 return match;
962 return NULL;
963 }
964 }
965 }
966 return NULL;
967}
968#endif /* HAVE_IPV6 */
969
Paul Jakma7514fb72007-05-02 16:05:35 +0000970#define RIB_SYSTEM_ROUTE(R) \
971 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
972
Denis Ovsienkodc958242007-08-13 16:03:06 +0000973/* This function verifies reachability of one given nexthop, which can be
974 * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
975 * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
976 * nexthop->ifindex will be updated appropriately as well.
977 * An existing route map can turn (otherwise active) nexthop into inactive, but
978 * not vice versa.
979 *
980 * The return value is the final value of 'ACTIVE' flag.
981 */
982
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300983static unsigned
paul718e3742002-12-13 20:15:29 +0000984nexthop_active_check (struct route_node *rn, struct rib *rib,
985 struct nexthop *nexthop, int set)
986{
Christian Frankef3a17322013-07-05 15:35:41 +0000987 rib_table_info_t *info = rn->table->info;
paul718e3742002-12-13 20:15:29 +0000988 struct interface *ifp;
Paul Jakma7514fb72007-05-02 16:05:35 +0000989 route_map_result_t ret = RMAP_MATCH;
990 extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
991 struct route_map *rmap;
992 int family;
paul718e3742002-12-13 20:15:29 +0000993
Paul Jakma7514fb72007-05-02 16:05:35 +0000994 family = 0;
paul718e3742002-12-13 20:15:29 +0000995 switch (nexthop->type)
996 {
997 case NEXTHOP_TYPE_IFINDEX:
998 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000999 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001000 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1001 else
1002 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1003 break;
paul718e3742002-12-13 20:15:29 +00001004 case NEXTHOP_TYPE_IPV6_IFNAME:
Paul Jakma7514fb72007-05-02 16:05:35 +00001005 family = AFI_IP6;
1006 case NEXTHOP_TYPE_IFNAME:
paul718e3742002-12-13 20:15:29 +00001007 ifp = if_lookup_by_name (nexthop->ifname);
Andrew J. Schorr3f087672008-01-08 20:12:46 +00001008 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001009 {
1010 if (set)
1011 nexthop->ifindex = ifp->ifindex;
1012 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1013 }
1014 else
1015 {
1016 if (set)
1017 nexthop->ifindex = 0;
1018 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1019 }
1020 break;
1021 case NEXTHOP_TYPE_IPV4:
1022 case NEXTHOP_TYPE_IPV4_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +00001023 family = AFI_IP;
paul718e3742002-12-13 20:15:29 +00001024 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
1025 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1026 else
1027 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1028 break;
1029#ifdef HAVE_IPV6
1030 case NEXTHOP_TYPE_IPV6:
Paul Jakma7514fb72007-05-02 16:05:35 +00001031 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +00001032 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
1033 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1034 else
1035 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1036 break;
1037 case NEXTHOP_TYPE_IPV6_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +00001038 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +00001039 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
1040 {
1041 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +00001042 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001043 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1044 else
1045 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1046 }
1047 else
1048 {
1049 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
1050 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1051 else
1052 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1053 }
1054 break;
1055#endif /* HAVE_IPV6 */
paul595db7f2003-05-25 21:35:06 +00001056 case NEXTHOP_TYPE_BLACKHOLE:
1057 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1058 break;
paul718e3742002-12-13 20:15:29 +00001059 default:
1060 break;
1061 }
Paul Jakma7514fb72007-05-02 16:05:35 +00001062 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1063 return 0;
1064
Christian Frankef3a17322013-07-05 15:35:41 +00001065 /* XXX: What exactly do those checks do? Do we support
1066 * e.g. IPv4 routes with IPv6 nexthops or vice versa? */
Paul Jakma7514fb72007-05-02 16:05:35 +00001067 if (RIB_SYSTEM_ROUTE(rib) ||
1068 (family == AFI_IP && rn->p.family != AF_INET) ||
1069 (family == AFI_IP6 && rn->p.family != AF_INET6))
1070 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1071
Christian Frankef3a17322013-07-05 15:35:41 +00001072 /* The original code didn't determine the family correctly
1073 * e.g. for NEXTHOP_TYPE_IFINDEX. Retrieve the correct afi
1074 * from the rib_table_info in those cases.
1075 * Possibly it may be better to use only the rib_table_info
1076 * in every case.
1077 */
1078 if (!family)
1079 family = info->afi;
1080
Paul Jakma7514fb72007-05-02 16:05:35 +00001081 rmap = 0;
1082 if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
1083 proto_rm[family][rib->type])
1084 rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
1085 if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
1086 rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
1087 if (rmap) {
1088 ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, nexthop);
1089 }
1090
1091 if (ret == RMAP_DENYMATCH)
1092 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
paul718e3742002-12-13 20:15:29 +00001093 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1094}
1095
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001096/* Iterate over all nexthops of the given RIB entry and refresh their
1097 * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
1098 * nexthop is found to toggle the ACTIVE flag, the whole rib structure
1099 * is flagged with ZEBRA_FLAG_CHANGED. The 4th 'set' argument is
1100 * transparently passed to nexthop_active_check().
1101 *
1102 * Return value is the new number of active nexthops.
1103 */
1104
paula1ac18c2005-06-28 17:17:12 +00001105static int
paul718e3742002-12-13 20:15:29 +00001106nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
1107{
1108 struct nexthop *nexthop;
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001109 unsigned int prev_active, prev_index, new_active;
paul718e3742002-12-13 20:15:29 +00001110
1111 rib->nexthop_active_num = 0;
1112 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1113
1114 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001115 {
1116 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001117 prev_index = nexthop->ifindex;
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001118 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
1119 rib->nexthop_active_num++;
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001120 if (prev_active != new_active ||
1121 prev_index != nexthop->ifindex)
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001122 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1123 }
paul718e3742002-12-13 20:15:29 +00001124 return rib->nexthop_active_num;
1125}
paul6baeb982003-10-28 03:47:15 +00001126
David Lamparter6b0655a2014-06-04 06:53:35 +02001127
paul718e3742002-12-13 20:15:29 +00001128
paula1ac18c2005-06-28 17:17:12 +00001129static void
paul718e3742002-12-13 20:15:29 +00001130rib_install_kernel (struct route_node *rn, struct rib *rib)
1131{
1132 int ret = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001133 struct nexthop *nexthop, *tnexthop;
1134 int recursing;
paul718e3742002-12-13 20:15:29 +00001135
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001136 /*
1137 * Make sure we update the FPM any time we send new information to
1138 * the kernel.
1139 */
1140 zfpm_trigger_update (rn, "installing in kernel");
paul718e3742002-12-13 20:15:29 +00001141 switch (PREFIX_FAMILY (&rn->p))
1142 {
1143 case AF_INET:
1144 ret = kernel_add_ipv4 (&rn->p, rib);
1145 break;
1146#ifdef HAVE_IPV6
1147 case AF_INET6:
1148 ret = kernel_add_ipv6 (&rn->p, rib);
1149 break;
1150#endif /* HAVE_IPV6 */
1151 }
1152
Denis Ovsienkodc958242007-08-13 16:03:06 +00001153 /* This condition is never met, if we are using rt_socket.c */
paul718e3742002-12-13 20:15:29 +00001154 if (ret < 0)
1155 {
Christian Frankefa713d92013-07-05 15:35:37 +00001156 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +00001157 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1158 }
1159}
1160
1161/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001162static int
paul718e3742002-12-13 20:15:29 +00001163rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
1164{
1165 int ret = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001166 struct nexthop *nexthop, *tnexthop;
1167 int recursing;
paul718e3742002-12-13 20:15:29 +00001168
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001169 /*
1170 * Make sure we update the FPM any time we send new information to
1171 * the kernel.
1172 */
1173 zfpm_trigger_update (rn, "uninstalling from kernel");
1174
paul718e3742002-12-13 20:15:29 +00001175 switch (PREFIX_FAMILY (&rn->p))
1176 {
1177 case AF_INET:
1178 ret = kernel_delete_ipv4 (&rn->p, rib);
1179 break;
1180#ifdef HAVE_IPV6
1181 case AF_INET6:
1182 ret = kernel_delete_ipv6 (&rn->p, rib);
1183 break;
1184#endif /* HAVE_IPV6 */
1185 }
1186
Christian Frankefa713d92013-07-05 15:35:37 +00001187 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +00001188 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1189
1190 return ret;
1191}
1192
1193/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001194static void
paul718e3742002-12-13 20:15:29 +00001195rib_uninstall (struct route_node *rn, struct rib *rib)
1196{
1197 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1198 {
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001199 zfpm_trigger_update (rn, "rib_uninstall");
1200
paul718e3742002-12-13 20:15:29 +00001201 redistribute_delete (&rn->p, rib);
1202 if (! RIB_SYSTEM_ROUTE (rib))
1203 rib_uninstall_kernel (rn, rib);
1204 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
1205 }
1206}
1207
Paul Jakma6d691122006-07-27 21:49:00 +00001208static void rib_unlink (struct route_node *, struct rib *);
1209
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001210/*
1211 * rib_can_delete_dest
1212 *
1213 * Returns TRUE if the given dest can be deleted from the table.
1214 */
1215static int
1216rib_can_delete_dest (rib_dest_t *dest)
1217{
1218 if (dest->routes)
1219 {
1220 return 0;
1221 }
1222
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001223 /*
1224 * Don't delete the dest if we have to update the FPM about this
1225 * prefix.
1226 */
1227 if (CHECK_FLAG (dest->flags, RIB_DEST_UPDATE_FPM) ||
1228 CHECK_FLAG (dest->flags, RIB_DEST_SENT_TO_FPM))
1229 return 0;
1230
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001231 return 1;
1232}
1233
1234/*
1235 * rib_gc_dest
1236 *
1237 * Garbage collect the rib dest corresponding to the given route node
1238 * if appropriate.
1239 *
1240 * Returns TRUE if the dest was deleted, FALSE otherwise.
1241 */
1242int
1243rib_gc_dest (struct route_node *rn)
1244{
1245 rib_dest_t *dest;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001246
1247 dest = rib_dest_from_rnode (rn);
1248 if (!dest)
1249 return 0;
1250
1251 if (!rib_can_delete_dest (dest))
1252 return 0;
1253
1254 if (IS_ZEBRA_DEBUG_RIB)
David Lampartere0b0ac82014-04-24 20:22:53 +02001255 rnode_debug (rn, "removing dest from table");
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001256
1257 dest->rnode = NULL;
1258 XFREE (MTYPE_RIB_DEST, dest);
1259 rn->info = NULL;
1260
1261 /*
1262 * Release the one reference that we keep on the route node.
1263 */
1264 route_unlock_node (rn);
1265 return 1;
1266}
1267
paul718e3742002-12-13 20:15:29 +00001268/* Core function for processing routing information base. */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001269static void
1270rib_process (struct route_node *rn)
paul718e3742002-12-13 20:15:29 +00001271{
1272 struct rib *rib;
1273 struct rib *next;
1274 struct rib *fib = NULL;
1275 struct rib *select = NULL;
Paul Jakma6d691122006-07-27 21:49:00 +00001276 struct rib *del = NULL;
pauld753e9e2003-01-22 19:45:50 +00001277 int installed = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001278 struct nexthop *nexthop = NULL, *tnexthop;
1279 int recursing;
Balaji95116332014-10-23 15:25:25 +00001280 rib_table_info_t *info;
1281
paul4d38fdb2005-04-28 17:35:14 +00001282 assert (rn);
Balaji95116332014-10-23 15:25:25 +00001283
1284 info = rn->table->info;
1285
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001286 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00001287 {
paul718e3742002-12-13 20:15:29 +00001288 /* Currently installed rib. */
1289 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Paul Jakma6d691122006-07-27 21:49:00 +00001290 {
1291 assert (fib == NULL);
1292 fib = rib;
1293 }
1294
1295 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1296 * which we need to do do further work with below.
1297 */
1298 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1299 {
1300 if (rib != fib)
1301 {
1302 if (IS_ZEBRA_DEBUG_RIB)
David Lampartere0b0ac82014-04-24 20:22:53 +02001303 rnode_debug (rn, "rn %p, removing rib %p", rn, rib);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001304 rib_unlink (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001305 }
1306 else
1307 del = rib;
1308
1309 continue;
1310 }
paul4d38fdb2005-04-28 17:35:14 +00001311
paul718e3742002-12-13 20:15:29 +00001312 /* Skip unreachable nexthop. */
1313 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +00001314 continue;
paul718e3742002-12-13 20:15:29 +00001315
Balaji95116332014-10-23 15:25:25 +00001316 if (info->safi == SAFI_MULTICAST)
1317 continue;
1318
paul718e3742002-12-13 20:15:29 +00001319 /* Infinit distance. */
1320 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +00001321 continue;
paul718e3742002-12-13 20:15:29 +00001322
paulaf887b52006-01-18 14:52:52 +00001323 /* Newly selected rib, the common case. */
1324 if (!select)
1325 {
1326 select = rib;
1327 continue;
1328 }
1329
1330 /* filter route selection in following order:
paulaf887b52006-01-18 14:52:52 +00001331 * - connected beats other types
paula8d9c1f2006-01-25 06:31:04 +00001332 * - lower distance beats higher
paulaf887b52006-01-18 14:52:52 +00001333 * - lower metric beats higher for equal distance
1334 * - last, hence oldest, route wins tie break.
1335 */
paula1038a12006-01-30 14:08:51 +00001336
1337 /* Connected routes. Pick the last connected
1338 * route of the set of lowest metric connected routes.
1339 */
paula8d9c1f2006-01-25 06:31:04 +00001340 if (rib->type == ZEBRA_ROUTE_CONNECT)
1341 {
paula1038a12006-01-30 14:08:51 +00001342 if (select->type != ZEBRA_ROUTE_CONNECT
paula8d9c1f2006-01-25 06:31:04 +00001343 || rib->metric <= select->metric)
paula1038a12006-01-30 14:08:51 +00001344 select = rib;
1345 continue;
paula8d9c1f2006-01-25 06:31:04 +00001346 }
1347 else if (select->type == ZEBRA_ROUTE_CONNECT)
1348 continue;
1349
1350 /* higher distance loses */
1351 if (rib->distance > select->distance)
1352 continue;
1353
1354 /* lower wins */
1355 if (rib->distance < select->distance)
1356 {
paulaf887b52006-01-18 14:52:52 +00001357 select = rib;
paula8d9c1f2006-01-25 06:31:04 +00001358 continue;
1359 }
1360
1361 /* metric tie-breaks equal distance */
1362 if (rib->metric <= select->metric)
1363 select = rib;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001364 } /* RNODE_FOREACH_RIB_SAFE */
Denis Ovsienkodc958242007-08-13 16:03:06 +00001365
1366 /* After the cycle is finished, the following pointers will be set:
1367 * select --- the winner RIB entry, if any was found, otherwise NULL
1368 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1369 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1370 * rib --- NULL
1371 */
1372
1373 /* Same RIB entry is selected. Update FIB and finish. */
paul718e3742002-12-13 20:15:29 +00001374 if (select && select == fib)
1375 {
Paul Jakma6d691122006-07-27 21:49:00 +00001376 if (IS_ZEBRA_DEBUG_RIB)
David Lampartere0b0ac82014-04-24 20:22:53 +02001377 rnode_debug (rn, "Updating existing route, select %p, fib %p",
1378 select, fib);
paul718e3742002-12-13 20:15:29 +00001379 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +00001380 {
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001381 zfpm_trigger_update (rn, "updating existing route");
1382
paul4d38fdb2005-04-28 17:35:14 +00001383 redistribute_delete (&rn->p, select);
1384 if (! RIB_SYSTEM_ROUTE (select))
1385 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001386
paul4d38fdb2005-04-28 17:35:14 +00001387 /* Set real nexthop. */
1388 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +00001389
paul4d38fdb2005-04-28 17:35:14 +00001390 if (! RIB_SYSTEM_ROUTE (select))
1391 rib_install_kernel (rn, select);
1392 redistribute_add (&rn->p, select);
1393 }
pauld753e9e2003-01-22 19:45:50 +00001394 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001395 {
1396 /* Housekeeping code to deal with
1397 race conditions in kernel with linux
1398 netlink reporting interface up before IPv4 or IPv6 protocol
1399 is ready to add routes.
1400 This makes sure the routes are IN the kernel.
1401 */
pauld753e9e2003-01-22 19:45:50 +00001402
Christian Frankefa713d92013-07-05 15:35:37 +00001403 for (ALL_NEXTHOPS_RO(select->nexthop, nexthop, tnexthop, recursing))
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001404 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
paul4d38fdb2005-04-28 17:35:14 +00001405 {
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001406 installed = 1;
1407 break;
paul4d38fdb2005-04-28 17:35:14 +00001408 }
1409 if (! installed)
1410 rib_install_kernel (rn, select);
1411 }
Paul Jakma6d691122006-07-27 21:49:00 +00001412 goto end;
paul718e3742002-12-13 20:15:29 +00001413 }
1414
Denis Ovsienkodc958242007-08-13 16:03:06 +00001415 /* At this point we either haven't found the best RIB entry or it is
1416 * different from what we currently intend to flag with SELECTED. In both
1417 * cases, if a RIB block is present in FIB, it should be withdrawn.
1418 */
paul718e3742002-12-13 20:15:29 +00001419 if (fib)
1420 {
Paul Jakma6d691122006-07-27 21:49:00 +00001421 if (IS_ZEBRA_DEBUG_RIB)
David Lampartere0b0ac82014-04-24 20:22:53 +02001422 rnode_debug (rn, "Removing existing route, fib %p", fib);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001423
1424 zfpm_trigger_update (rn, "removing existing route");
1425
paul718e3742002-12-13 20:15:29 +00001426 redistribute_delete (&rn->p, fib);
1427 if (! RIB_SYSTEM_ROUTE (fib))
1428 rib_uninstall_kernel (rn, fib);
1429 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1430
1431 /* Set real nexthop. */
1432 nexthop_active_update (rn, fib, 1);
1433 }
1434
Denis Ovsienkodc958242007-08-13 16:03:06 +00001435 /* Regardless of some RIB entry being SELECTED or not before, now we can
1436 * tell, that if a new winner exists, FIB is still not updated with this
1437 * data, but ready to be.
1438 */
paul718e3742002-12-13 20:15:29 +00001439 if (select)
1440 {
Paul Jakma6d691122006-07-27 21:49:00 +00001441 if (IS_ZEBRA_DEBUG_RIB)
David Lampartere0b0ac82014-04-24 20:22:53 +02001442 rnode_debug (rn, "Adding route, select %p", select);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001443
1444 zfpm_trigger_update (rn, "new route selected");
1445
paul718e3742002-12-13 20:15:29 +00001446 /* Set real nexthop. */
1447 nexthop_active_update (rn, select, 1);
1448
1449 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001450 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001451 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1452 redistribute_add (&rn->p, select);
1453 }
paul4d38fdb2005-04-28 17:35:14 +00001454
Paul Jakma6d691122006-07-27 21:49:00 +00001455 /* FIB route was removed, should be deleted */
1456 if (del)
1457 {
1458 if (IS_ZEBRA_DEBUG_RIB)
David Lampartere0b0ac82014-04-24 20:22:53 +02001459 rnode_debug (rn, "Deleting fib %p, rn %p", del, rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001460 rib_unlink (rn, del);
1461 }
paul4d38fdb2005-04-28 17:35:14 +00001462
Paul Jakma6d691122006-07-27 21:49:00 +00001463end:
1464 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lampartere0b0ac82014-04-24 20:22:53 +02001465 rnode_debug (rn, "rn %p dequeued", rn);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001466
1467 /*
1468 * Check if the dest can be deleted now.
1469 */
1470 rib_gc_dest (rn);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001471}
1472
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001473/* Take a list of route_node structs and return 1, if there was a record
1474 * picked from it and processed by rib_process(). Don't process more,
1475 * than one RN record; operate only in the specified sub-queue.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001476 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001477static unsigned int
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001478process_subq (struct list * subq, u_char qindex)
1479{
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001480 struct listnode *lnode = listhead (subq);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001481 struct route_node *rnode;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001482
1483 if (!lnode)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001484 return 0;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001485
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001486 rnode = listgetdata (lnode);
1487 rib_process (rnode);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001488
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001489 if (rnode->info)
1490 UNSET_FLAG (rib_dest_from_rnode (rnode)->flags, RIB_ROUTE_QUEUED (qindex));
1491
Chris Caputo67b94672009-07-18 04:02:26 +00001492#if 0
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001493 else
1494 {
1495 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1496 __func__, rnode, rnode->lock);
1497 zlog_backtrace(LOG_DEBUG);
1498 }
Chris Caputo67b94672009-07-18 04:02:26 +00001499#endif
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001500 route_unlock_node (rnode);
1501 list_delete_node (subq, lnode);
1502 return 1;
1503}
1504
1505/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1506 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1507 * is pointed to the meta queue structure.
1508 */
1509static wq_item_status
1510meta_queue_process (struct work_queue *dummy, void *data)
1511{
1512 struct meta_queue * mq = data;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001513 unsigned i;
1514
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001515 for (i = 0; i < MQ_SIZE; i++)
1516 if (process_subq (mq->subq[i], i))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001517 {
1518 mq->size--;
1519 break;
1520 }
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001521 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1522}
1523
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001524/*
1525 * Map from rib types to queue type (priority) in meta queue
1526 */
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001527static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
1528 [ZEBRA_ROUTE_SYSTEM] = 4,
1529 [ZEBRA_ROUTE_KERNEL] = 0,
1530 [ZEBRA_ROUTE_CONNECT] = 0,
1531 [ZEBRA_ROUTE_STATIC] = 1,
1532 [ZEBRA_ROUTE_RIP] = 2,
1533 [ZEBRA_ROUTE_RIPNG] = 2,
1534 [ZEBRA_ROUTE_OSPF] = 2,
1535 [ZEBRA_ROUTE_OSPF6] = 2,
1536 [ZEBRA_ROUTE_ISIS] = 2,
1537 [ZEBRA_ROUTE_BGP] = 3,
1538 [ZEBRA_ROUTE_HSLS] = 4,
Paul Jakma57345092011-12-25 17:52:09 +01001539 [ZEBRA_ROUTE_BABEL] = 2,
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001540};
1541
1542/* Look into the RN and queue it into one or more priority queues,
1543 * increasing the size for each data push done.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001544 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001545static void
1546rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001547{
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001548 struct rib *rib;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001549
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001550 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001551 {
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001552 u_char qindex = meta_queue_map[rib->type];
1553
1554 /* Invariant: at this point we always have rn->info set. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001555 if (CHECK_FLAG (rib_dest_from_rnode (rn)->flags,
1556 RIB_ROUTE_QUEUED (qindex)))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001557 {
1558 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lampartere0b0ac82014-04-24 20:22:53 +02001559 rnode_debug (rn, "rn %p is already queued in sub-queue %u",
1560 rn, qindex);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001561 continue;
1562 }
1563
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001564 SET_FLAG (rib_dest_from_rnode (rn)->flags, RIB_ROUTE_QUEUED (qindex));
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001565 listnode_add (mq->subq[qindex], rn);
1566 route_lock_node (rn);
1567 mq->size++;
1568
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001569 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lampartere0b0ac82014-04-24 20:22:53 +02001570 rnode_debug (rn, "queued rn %p into sub-queue %u",
1571 rn, qindex);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001572 }
paul4d38fdb2005-04-28 17:35:14 +00001573}
1574
Paul Jakma6d691122006-07-27 21:49:00 +00001575/* Add route_node to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001576static void
Paul Jakma6d691122006-07-27 21:49:00 +00001577rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
paul4d38fdb2005-04-28 17:35:14 +00001578{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001579 assert (zebra && rn);
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001580
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001581 /* Pointless to queue a route_node with no RIB entries to add or remove */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001582 if (!rnode_to_ribs (rn))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001583 {
1584 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1585 __func__, rn, rn->lock);
1586 zlog_backtrace(LOG_DEBUG);
1587 return;
1588 }
1589
1590 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lampartere0b0ac82014-04-24 20:22:53 +02001591 rnode_info (rn, "work queue added");
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001592
1593 assert (zebra);
1594
1595 if (zebra->ribq == NULL)
1596 {
1597 zlog_err ("%s: work_queue does not exist!", __func__);
1598 return;
Paul Jakma6d691122006-07-27 21:49:00 +00001599 }
paul4d38fdb2005-04-28 17:35:14 +00001600
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001601 /*
1602 * The RIB queue should normally be either empty or holding the only
1603 * work_queue_item element. In the latter case this element would
1604 * hold a pointer to the meta queue structure, which must be used to
1605 * actually queue the route nodes to process. So create the MQ
1606 * holder, if necessary, then push the work into it in any case.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001607 * This semantics was introduced after 0.99.9 release.
1608 */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001609 if (!zebra->ribq->items->count)
1610 work_queue_add (zebra->ribq, zebra->mq);
1611
1612 rib_meta_queue_add (zebra->mq, rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001613
1614 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lampartere0b0ac82014-04-24 20:22:53 +02001615 rnode_debug (rn, "rn %p queued", rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001616
1617 return;
paul4d38fdb2005-04-28 17:35:14 +00001618}
1619
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001620/* Create new meta queue.
1621 A destructor function doesn't seem to be necessary here.
1622 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001623static struct meta_queue *
1624meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001625{
1626 struct meta_queue *new;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001627 unsigned i;
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001628
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001629 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1630 assert(new);
1631
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001632 for (i = 0; i < MQ_SIZE; i++)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001633 {
1634 new->subq[i] = list_new ();
1635 assert(new->subq[i]);
1636 }
1637
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001638 return new;
1639}
1640
paul4d38fdb2005-04-28 17:35:14 +00001641/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001642static void
paul4d38fdb2005-04-28 17:35:14 +00001643rib_queue_init (struct zebra_t *zebra)
1644{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001645 assert (zebra);
1646
paul4d38fdb2005-04-28 17:35:14 +00001647 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001648 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001649 {
Paul Jakma6d691122006-07-27 21:49:00 +00001650 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001651 return;
1652 }
1653
1654 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001655 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001656 zebra->ribq->spec.errorfunc = NULL;
paul4d38fdb2005-04-28 17:35:14 +00001657 /* XXX: TODO: These should be runtime configurable via vty */
1658 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001659 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001660
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001661 if (!(zebra->mq = meta_queue_new ()))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001662 {
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001663 zlog_err ("%s: could not initialise meta queue!", __func__);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001664 return;
1665 }
1666 return;
paul718e3742002-12-13 20:15:29 +00001667}
1668
Paul Jakma6d691122006-07-27 21:49:00 +00001669/* RIB updates are processed via a queue of pointers to route_nodes.
1670 *
1671 * The queue length is bounded by the maximal size of the routing table,
1672 * as a route_node will not be requeued, if already queued.
1673 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001674 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1675 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1676 * and then submit route_node to queue for best-path selection later.
1677 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001678 *
1679 * Deleted RIBs are reaped during best-path selection.
1680 *
1681 * rib_addnode
1682 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001683 * |-------->| | best RIB, if required
1684 * | |
1685 * static_install->|->rib_addqueue...... -> rib_process
1686 * | |
1687 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001688 * |-> set RIB_ENTRY_REMOVE |
1689 * rib_delnode (RIB freed)
1690 *
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001691 * The 'info' pointer of a route_node points to a rib_dest_t
1692 * ('dest'). Queueing state for a route_node is kept on the dest. The
1693 * dest is created on-demand by rib_link() and is kept around at least
1694 * as long as there are ribs hanging off it (@see rib_gc_dest()).
Paul Jakma6d691122006-07-27 21:49:00 +00001695 *
1696 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1697 *
1698 * - route_nodes: refcounted by:
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001699 * - dest attached to route_node:
1700 * - managed by: rib_link/rib_gc_dest
Paul Jakma6d691122006-07-27 21:49:00 +00001701 * - route_node processing queue
1702 * - managed by: rib_addqueue, rib_process.
1703 *
1704 */
1705
paul718e3742002-12-13 20:15:29 +00001706/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001707static void
Paul Jakma6d691122006-07-27 21:49:00 +00001708rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001709{
1710 struct rib *head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001711 rib_dest_t *dest;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001712
paul4d38fdb2005-04-28 17:35:14 +00001713 assert (rib && rn);
1714
Paul Jakma6d691122006-07-27 21:49:00 +00001715 if (IS_ZEBRA_DEBUG_RIB)
David Lampartere0b0ac82014-04-24 20:22:53 +02001716 rnode_debug (rn, "rn %p, rib %p", rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001717
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001718 dest = rib_dest_from_rnode (rn);
1719 if (!dest)
Paul Jakma6d691122006-07-27 21:49:00 +00001720 {
1721 if (IS_ZEBRA_DEBUG_RIB)
David Lampartere0b0ac82014-04-24 20:22:53 +02001722 rnode_debug (rn, "adding dest to table");
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001723
1724 dest = XCALLOC (MTYPE_RIB_DEST, sizeof (rib_dest_t));
1725 route_lock_node (rn); /* rn route table reference */
1726 rn->info = dest;
1727 dest->rnode = rn;
1728 }
1729
1730 head = dest->routes;
1731 if (head)
1732 {
Paul Jakma6d691122006-07-27 21:49:00 +00001733 head->prev = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001734 }
paul718e3742002-12-13 20:15:29 +00001735 rib->next = head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001736 dest->routes = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001737 rib_queue_add (&zebrad, rn);
1738}
1739
1740static void
1741rib_addnode (struct route_node *rn, struct rib *rib)
1742{
1743 /* RIB node has been un-removed before route-node is processed.
1744 * route_node must hence already be on the queue for processing..
1745 */
1746 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1747 {
1748 if (IS_ZEBRA_DEBUG_RIB)
David Lampartere0b0ac82014-04-24 20:22:53 +02001749 rnode_debug (rn, "rn %p, un-removed rib %p", rn, rib);
1750
Paul Jakma6d691122006-07-27 21:49:00 +00001751 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1752 return;
1753 }
1754 rib_link (rn, rib);
1755}
1756
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001757/*
1758 * rib_unlink
1759 *
1760 * Detach a rib structure from a route_node.
1761 *
1762 * Note that a call to rib_unlink() should be followed by a call to
1763 * rib_gc_dest() at some point. This allows a rib_dest_t that is no
1764 * longer required to be deleted.
1765 */
Paul Jakma6d691122006-07-27 21:49:00 +00001766static void
1767rib_unlink (struct route_node *rn, struct rib *rib)
1768{
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001769 rib_dest_t *dest;
Paul Jakma6d691122006-07-27 21:49:00 +00001770
1771 assert (rn && rib);
1772
1773 if (IS_ZEBRA_DEBUG_RIB)
David Lampartere0b0ac82014-04-24 20:22:53 +02001774 rnode_debug (rn, "rn %p, rib %p", rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001775
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001776 dest = rib_dest_from_rnode (rn);
1777
Paul Jakma6d691122006-07-27 21:49:00 +00001778 if (rib->next)
1779 rib->next->prev = rib->prev;
1780
1781 if (rib->prev)
1782 rib->prev->next = rib->next;
1783 else
1784 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001785 dest->routes = rib->next;
Paul Jakma6d691122006-07-27 21:49:00 +00001786 }
1787
1788 /* free RIB and nexthops */
Christian Frankefa713d92013-07-05 15:35:37 +00001789 nexthops_free(rib->nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00001790 XFREE (MTYPE_RIB, rib);
1791
paul718e3742002-12-13 20:15:29 +00001792}
1793
paula1ac18c2005-06-28 17:17:12 +00001794static void
paul718e3742002-12-13 20:15:29 +00001795rib_delnode (struct route_node *rn, struct rib *rib)
1796{
Paul Jakma6d691122006-07-27 21:49:00 +00001797 if (IS_ZEBRA_DEBUG_RIB)
David Lampartere0b0ac82014-04-24 20:22:53 +02001798 rnode_debug (rn, "rn %p, rib %p, removing", rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001799 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1800 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001801}
1802
1803int
1804rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001805 struct in_addr *gate, struct in_addr *src,
1806 unsigned int ifindex, u_int32_t vrf_id,
G.Balajicddf3912011-11-26 21:59:32 +04001807 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001808{
1809 struct rib *rib;
1810 struct rib *same = NULL;
1811 struct route_table *table;
1812 struct route_node *rn;
1813 struct nexthop *nexthop;
1814
1815 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04001816 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00001817 if (! table)
1818 return 0;
1819
1820 /* Make it sure prefixlen is applied to the prefix. */
1821 apply_mask_ipv4 (p);
1822
1823 /* Set default distance by route type. */
1824 if (distance == 0)
1825 {
Balaji.G837d16c2012-09-26 14:09:10 +05301826 if ((unsigned)type >= array_size(route_info))
David Lamparter7052f222009-08-27 00:28:28 +02001827 distance = 150;
1828 else
1829 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00001830
1831 /* iBGP distance is 200. */
1832 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1833 distance = 200;
1834 }
1835
1836 /* Lookup route node.*/
1837 rn = route_node_get (table, (struct prefix *) p);
1838
1839 /* If same type of route are installed, treat it as a implicit
1840 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001841 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00001842 {
Paul Jakma6d691122006-07-27 21:49:00 +00001843 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1844 continue;
1845
hassoebf1ead2005-09-21 14:58:20 +00001846 if (rib->type != type)
1847 continue;
1848 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001849 {
1850 same = rib;
1851 break;
1852 }
hassoebf1ead2005-09-21 14:58:20 +00001853 /* Duplicate connected route comes in. */
1854 else if ((nexthop = rib->nexthop) &&
1855 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001856 nexthop->ifindex == ifindex &&
1857 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001858 {
1859 rib->refcnt++;
1860 return 0 ;
1861 }
paul718e3742002-12-13 20:15:29 +00001862 }
1863
1864 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001865 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001866 rib->type = type;
1867 rib->distance = distance;
1868 rib->flags = flags;
1869 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001870 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001871 rib->nexthop_num = 0;
1872 rib->uptime = time (NULL);
1873
1874 /* Nexthop settings. */
1875 if (gate)
1876 {
1877 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001878 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001879 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001880 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001881 }
1882 else
1883 nexthop_ifindex_add (rib, ifindex);
1884
1885 /* If this route is kernel route, set FIB flag to the route. */
1886 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1887 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1888 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1889
1890 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001891 if (IS_ZEBRA_DEBUG_RIB)
1892 zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
paul718e3742002-12-13 20:15:29 +00001893 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001894
paul718e3742002-12-13 20:15:29 +00001895 /* Free implicit route.*/
1896 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001897 {
1898 if (IS_ZEBRA_DEBUG_RIB)
1899 zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001900 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001901 }
paul4d38fdb2005-04-28 17:35:14 +00001902
1903 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001904 return 0;
1905}
1906
Denis Ovsienkodc958242007-08-13 16:03:06 +00001907/* This function dumps the contents of a given RIB entry into
1908 * standard debug log. Calling function name and IP prefix in
1909 * question are passed as 1st and 2nd arguments.
1910 */
1911
David Lamparterf7bf4152013-10-22 17:10:21 +00001912void _rib_dump (const char * func,
1913 union prefix46constptr pp, const struct rib * rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001914{
David Lamparterf7bf4152013-10-22 17:10:21 +00001915 const struct prefix *p = pp.p;
Vincent Bernatfed643f2012-10-23 16:00:42 +00001916 char straddr[INET6_ADDRSTRLEN];
Christian Frankefa713d92013-07-05 15:35:37 +00001917 struct nexthop *nexthop, *tnexthop;
1918 int recursing;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001919
Vincent Bernatfed643f2012-10-23 16:00:42 +00001920 inet_ntop (p->family, &p->u.prefix, straddr, INET6_ADDRSTRLEN);
Christian Frankefa713d92013-07-05 15:35:37 +00001921 zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr, p->prefixlen);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001922 zlog_debug
1923 (
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001924 "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
Denis Ovsienkodc958242007-08-13 16:03:06 +00001925 func,
1926 rib->refcnt,
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001927 (unsigned long) rib->uptime,
Denis Ovsienkodc958242007-08-13 16:03:06 +00001928 rib->type,
1929 rib->table
1930 );
1931 zlog_debug
1932 (
1933 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1934 func,
1935 rib->metric,
1936 rib->distance,
1937 rib->flags,
1938 rib->status
1939 );
1940 zlog_debug
1941 (
1942 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1943 func,
1944 rib->nexthop_num,
1945 rib->nexthop_active_num,
1946 rib->nexthop_fib_num
1947 );
Vincent Bernatfed643f2012-10-23 16:00:42 +00001948
Christian Frankefa713d92013-07-05 15:35:37 +00001949 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1950 {
Vincent Bernatfed643f2012-10-23 16:00:42 +00001951 inet_ntop (p->family, &nexthop->gate, straddr, INET6_ADDRSTRLEN);
Christian Frankefa713d92013-07-05 15:35:37 +00001952 zlog_debug
1953 (
1954 "%s: %s %s with flags %s%s%s",
1955 func,
1956 (recursing ? " NH" : "NH"),
1957 straddr,
1958 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1959 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1960 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1961 );
1962 }
Denis Ovsienkodc958242007-08-13 16:03:06 +00001963 zlog_debug ("%s: dump complete", func);
1964}
1965
1966/* This is an exported helper to rtm_read() to dump the strange
1967 * RIB entry found by rib_lookup_ipv4_route()
1968 */
1969
1970void rib_lookup_and_dump (struct prefix_ipv4 * p)
1971{
1972 struct route_table *table;
1973 struct route_node *rn;
1974 struct rib *rib;
1975 char prefix_buf[INET_ADDRSTRLEN];
1976
1977 /* Lookup table. */
1978 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1979 if (! table)
1980 {
1981 zlog_err ("%s: vrf_table() returned NULL", __func__);
1982 return;
1983 }
1984
1985 inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
1986 /* Scan the RIB table for exactly matching RIB entry. */
1987 rn = route_node_lookup (table, (struct prefix *) p);
1988
1989 /* No route for this prefix. */
1990 if (! rn)
1991 {
1992 zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
1993 return;
1994 }
1995
1996 /* Unlock node. */
1997 route_unlock_node (rn);
1998
1999 /* let's go */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002000 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00002001 {
2002 zlog_debug
2003 (
2004 "%s: rn %p, rib %p: %s, %s",
2005 __func__,
2006 rn,
2007 rib,
2008 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
2009 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
2010 );
David Lamparterf7bf4152013-10-22 17:10:21 +00002011 rib_dump (p, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002012 }
2013}
2014
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002015/* Check if requested address assignment will fail due to another
2016 * route being installed by zebra in FIB already. Take necessary
2017 * actions, if needed: remove such a route from FIB and deSELECT
2018 * corresponding RIB entry. Then put affected RN into RIBQ head.
2019 */
2020void rib_lookup_and_pushup (struct prefix_ipv4 * p)
2021{
2022 struct route_table *table;
2023 struct route_node *rn;
2024 struct rib *rib;
2025 unsigned changed = 0;
2026
2027 if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
2028 {
2029 zlog_err ("%s: vrf_table() returned NULL", __func__);
2030 return;
2031 }
2032
2033 /* No matches would be the simplest case. */
2034 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
2035 return;
2036
2037 /* Unlock node. */
2038 route_unlock_node (rn);
2039
2040 /* Check all RIB entries. In case any changes have to be done, requeue
2041 * the RN into RIBQ head. If the routing message about the new connected
2042 * route (generated by the IP address we are going to assign very soon)
2043 * comes before the RIBQ is processed, the new RIB entry will join
2044 * RIBQ record already on head. This is necessary for proper revalidation
2045 * of the rest of the RIB.
2046 */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002047 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002048 {
2049 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
2050 ! RIB_SYSTEM_ROUTE (rib))
2051 {
2052 changed = 1;
2053 if (IS_ZEBRA_DEBUG_RIB)
2054 {
2055 char buf[INET_ADDRSTRLEN];
2056 inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
2057 zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
David Lamparterf7bf4152013-10-22 17:10:21 +00002058 rib_dump (&rn->p, rib);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002059 }
2060 rib_uninstall (rn, rib);
2061 }
2062 }
2063 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002064 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002065}
2066
paul718e3742002-12-13 20:15:29 +00002067int
G.Balajicddf3912011-11-26 21:59:32 +04002068rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002069{
2070 struct route_table *table;
2071 struct route_node *rn;
2072 struct rib *same;
2073 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00002074
paul718e3742002-12-13 20:15:29 +00002075 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04002076 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00002077 if (! table)
2078 return 0;
G.Balajicddf3912011-11-26 21:59:32 +04002079
paul718e3742002-12-13 20:15:29 +00002080 /* Make it sure prefixlen is applied to the prefix. */
2081 apply_mask_ipv4 (p);
2082
2083 /* Set default distance by route type. */
2084 if (rib->distance == 0)
2085 {
2086 rib->distance = route_info[rib->type].distance;
2087
2088 /* iBGP distance is 200. */
2089 if (rib->type == ZEBRA_ROUTE_BGP
2090 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
2091 rib->distance = 200;
2092 }
2093
2094 /* Lookup route node.*/
2095 rn = route_node_get (table, (struct prefix *) p);
2096
2097 /* If same type of route are installed, treat it as a implicit
2098 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002099 RNODE_FOREACH_RIB (rn, same)
paul718e3742002-12-13 20:15:29 +00002100 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00002101 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00002102 continue;
2103
paul718e3742002-12-13 20:15:29 +00002104 if (same->type == rib->type && same->table == rib->table
2105 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00002106 break;
paul718e3742002-12-13 20:15:29 +00002107 }
paul4d38fdb2005-04-28 17:35:14 +00002108
paul718e3742002-12-13 20:15:29 +00002109 /* If this route is kernel route, set FIB flag to the route. */
2110 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
2111 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2112 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2113
2114 /* Link new rib to node.*/
2115 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002116 if (IS_ZEBRA_DEBUG_RIB)
2117 {
2118 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
2119 __func__, rn, rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00002120 rib_dump (p, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002121 }
paul718e3742002-12-13 20:15:29 +00002122
paul718e3742002-12-13 20:15:29 +00002123 /* Free implicit route.*/
2124 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00002125 {
2126 if (IS_ZEBRA_DEBUG_RIB)
2127 {
2128 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
2129 __func__, rn, same);
David Lamparterf7bf4152013-10-22 17:10:21 +00002130 rib_dump (p, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002131 }
paul4d38fdb2005-04-28 17:35:14 +00002132 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002133 }
paul4d38fdb2005-04-28 17:35:14 +00002134
2135 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002136 return 0;
2137}
2138
hassoebf1ead2005-09-21 14:58:20 +00002139/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002140int
2141rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
G.Balajicddf3912011-11-26 21:59:32 +04002142 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002143{
2144 struct route_table *table;
2145 struct route_node *rn;
2146 struct rib *rib;
2147 struct rib *fib = NULL;
2148 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002149 struct nexthop *nexthop, *tnexthop;
2150 int recursing;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002151 char buf1[INET_ADDRSTRLEN];
2152 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002153
2154 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04002155 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00002156 if (! table)
2157 return 0;
2158
2159 /* Apply mask. */
2160 apply_mask_ipv4 (p);
2161
Christian Frankeb52aef12013-11-27 17:06:15 +00002162 if (IS_ZEBRA_DEBUG_KERNEL)
2163 {
2164 if (gate)
2165 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
2166 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
2167 p->prefixlen,
2168 inet_ntoa (*gate),
2169 ifindex);
2170 else
2171 zlog_debug ("rib_delete_ipv4(): route delete %s/%d ifindex %d",
2172 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
2173 p->prefixlen,
2174 ifindex);
2175 }
paul5ec90d22003-06-19 01:41:37 +00002176
paul718e3742002-12-13 20:15:29 +00002177 /* Lookup route node. */
2178 rn = route_node_lookup (table, (struct prefix *) p);
2179 if (! rn)
2180 {
2181 if (IS_ZEBRA_DEBUG_KERNEL)
2182 {
2183 if (gate)
ajsb6178002004-12-07 21:12:56 +00002184 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002185 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002186 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002187 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002188 ifindex);
2189 else
ajsb6178002004-12-07 21:12:56 +00002190 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002191 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002192 p->prefixlen,
2193 ifindex);
2194 }
2195 return ZEBRA_ERR_RTNOEXIST;
2196 }
2197
2198 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002199 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002200 {
Paul Jakma6d691122006-07-27 21:49:00 +00002201 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2202 continue;
2203
paul718e3742002-12-13 20:15:29 +00002204 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2205 fib = rib;
2206
hassoebf1ead2005-09-21 14:58:20 +00002207 if (rib->type != type)
2208 continue;
2209 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002210 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002211 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002212 if (nexthop->ifindex != ifindex)
2213 continue;
hassoebf1ead2005-09-21 14:58:20 +00002214 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002215 {
hassoebf1ead2005-09-21 14:58:20 +00002216 rib->refcnt--;
2217 route_unlock_node (rn);
2218 route_unlock_node (rn);
2219 return 0;
paul718e3742002-12-13 20:15:29 +00002220 }
hassoebf1ead2005-09-21 14:58:20 +00002221 same = rib;
2222 break;
paul718e3742002-12-13 20:15:29 +00002223 }
hassoebf1ead2005-09-21 14:58:20 +00002224 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002225 else
paul5ec90d22003-06-19 01:41:37 +00002226 {
Christian Frankefa713d92013-07-05 15:35:37 +00002227 if (gate == NULL)
2228 {
2229 same = rib;
2230 break;
2231 }
2232 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2233 if (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate))
2234 {
2235 same = rib;
2236 break;
2237 }
2238 if (same)
2239 break;
2240 }
paul718e3742002-12-13 20:15:29 +00002241 }
paul718e3742002-12-13 20:15:29 +00002242 /* If same type of route can't be found and this message is from
2243 kernel. */
2244 if (! same)
2245 {
2246 if (fib && type == ZEBRA_ROUTE_KERNEL)
2247 {
2248 /* Unset flags. */
2249 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2250 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2251
2252 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2253 }
2254 else
2255 {
2256 if (IS_ZEBRA_DEBUG_KERNEL)
2257 {
2258 if (gate)
ajsb6178002004-12-07 21:12:56 +00002259 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002260 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002261 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002262 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002263 ifindex,
2264 type);
2265 else
ajsb6178002004-12-07 21:12:56 +00002266 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002267 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002268 p->prefixlen,
2269 ifindex,
2270 type);
2271 }
2272 route_unlock_node (rn);
2273 return ZEBRA_ERR_RTNOEXIST;
2274 }
2275 }
paul4d38fdb2005-04-28 17:35:14 +00002276
paul718e3742002-12-13 20:15:29 +00002277 if (same)
2278 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002279
paul718e3742002-12-13 20:15:29 +00002280 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002281 return 0;
2282}
David Lamparter6b0655a2014-06-04 06:53:35 +02002283
paul718e3742002-12-13 20:15:29 +00002284/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002285static void
paul718e3742002-12-13 20:15:29 +00002286static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
2287{
2288 struct rib *rib;
2289 struct route_node *rn;
2290 struct route_table *table;
2291
2292 /* Lookup table. */
2293 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2294 if (! table)
2295 return;
2296
2297 /* Lookup existing route */
2298 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002299 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002300 {
2301 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2302 continue;
2303
2304 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2305 break;
2306 }
paul718e3742002-12-13 20:15:29 +00002307
2308 if (rib)
2309 {
2310 /* Same distance static route is there. Update it with new
2311 nexthop. */
paul718e3742002-12-13 20:15:29 +00002312 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002313 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002314 {
2315 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002316 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002317 break;
2318 case STATIC_IPV4_IFNAME:
2319 nexthop_ifname_add (rib, si->gate.ifname);
2320 break;
2321 case STATIC_IPV4_BLACKHOLE:
2322 nexthop_blackhole_add (rib);
2323 break;
paul4d38fdb2005-04-28 17:35:14 +00002324 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002325 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002326 }
2327 else
2328 {
2329 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002330 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2331
paul718e3742002-12-13 20:15:29 +00002332 rib->type = ZEBRA_ROUTE_STATIC;
2333 rib->distance = si->distance;
2334 rib->metric = 0;
Nolan Leakeb0145dd2012-09-13 17:17:31 +00002335 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002336 rib->nexthop_num = 0;
2337
2338 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002339 {
2340 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002341 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002342 break;
2343 case STATIC_IPV4_IFNAME:
2344 nexthop_ifname_add (rib, si->gate.ifname);
2345 break;
2346 case STATIC_IPV4_BLACKHOLE:
2347 nexthop_blackhole_add (rib);
2348 break;
2349 }
paul718e3742002-12-13 20:15:29 +00002350
hasso81dfcaa2003-05-25 19:21:25 +00002351 /* Save the flags of this static routes (reject, blackhole) */
2352 rib->flags = si->flags;
2353
paul718e3742002-12-13 20:15:29 +00002354 /* Link this rib to the tree. */
2355 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002356 }
2357}
2358
paula1ac18c2005-06-28 17:17:12 +00002359static int
paul718e3742002-12-13 20:15:29 +00002360static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2361{
2362 if (nexthop->type == NEXTHOP_TYPE_IPV4
2363 && si->type == STATIC_IPV4_GATEWAY
2364 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2365 return 1;
2366 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2367 && si->type == STATIC_IPV4_IFNAME
2368 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2369 return 1;
paul595db7f2003-05-25 21:35:06 +00002370 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2371 && si->type == STATIC_IPV4_BLACKHOLE)
2372 return 1;
paule8e19462006-01-19 20:16:55 +00002373 return 0;
paul718e3742002-12-13 20:15:29 +00002374}
2375
2376/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002377static void
paul718e3742002-12-13 20:15:29 +00002378static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
2379{
2380 struct route_node *rn;
2381 struct rib *rib;
2382 struct nexthop *nexthop;
2383 struct route_table *table;
2384
2385 /* Lookup table. */
2386 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2387 if (! table)
2388 return;
paul4d38fdb2005-04-28 17:35:14 +00002389
paul718e3742002-12-13 20:15:29 +00002390 /* Lookup existing route with type and distance. */
2391 rn = route_node_lookup (table, p);
2392 if (! rn)
2393 return;
2394
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002395 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002396 {
2397 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2398 continue;
2399
2400 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2401 break;
2402 }
paul718e3742002-12-13 20:15:29 +00002403
2404 if (! rib)
2405 {
2406 route_unlock_node (rn);
2407 return;
2408 }
2409
2410 /* Lookup nexthop. */
2411 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2412 if (static_ipv4_nexthop_same (nexthop, si))
2413 break;
2414
2415 /* Can't find nexthop. */
2416 if (! nexthop)
2417 {
2418 route_unlock_node (rn);
2419 return;
2420 }
2421
2422 /* Check nexthop. */
2423 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002424 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002425 else
2426 {
paul6baeb982003-10-28 03:47:15 +00002427 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2428 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002429 nexthop_delete (rib, nexthop);
2430 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002431 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002432 }
paul718e3742002-12-13 20:15:29 +00002433 /* Unlock node. */
2434 route_unlock_node (rn);
2435}
2436
2437/* Add static route into static route configuration. */
2438int
hasso39db97e2004-10-12 20:50:58 +00002439static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00002440 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002441{
2442 u_char type = 0;
2443 struct route_node *rn;
2444 struct static_ipv4 *si;
2445 struct static_ipv4 *pp;
2446 struct static_ipv4 *cp;
2447 struct static_ipv4 *update = NULL;
2448 struct route_table *stable;
2449
2450 /* Lookup table. */
2451 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2452 if (! stable)
2453 return -1;
2454
2455 /* Lookup static route prefix. */
2456 rn = route_node_get (stable, p);
2457
2458 /* Make flags. */
2459 if (gate)
2460 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002461 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002462 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002463 else
2464 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002465
2466 /* Do nothing if there is a same static route. */
2467 for (si = rn->info; si; si = si->next)
2468 {
2469 if (type == si->type
2470 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2471 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2472 {
2473 if (distance == si->distance)
2474 {
2475 route_unlock_node (rn);
2476 return 0;
2477 }
2478 else
2479 update = si;
2480 }
2481 }
2482
Paul Jakma3c0755d2006-12-08 00:53:14 +00002483 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002484 if (update)
2485 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
2486
2487 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002488 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
paul718e3742002-12-13 20:15:29 +00002489
2490 si->type = type;
2491 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002492 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002493
2494 if (gate)
2495 si->gate.ipv4 = *gate;
2496 if (ifname)
2497 si->gate.ifname = XSTRDUP (0, ifname);
2498
2499 /* Add new static route information to the tree with sort by
2500 distance value and gateway address. */
2501 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2502 {
2503 if (si->distance < cp->distance)
2504 break;
2505 if (si->distance > cp->distance)
2506 continue;
2507 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2508 {
2509 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2510 break;
2511 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2512 continue;
2513 }
2514 }
2515
2516 /* Make linked list. */
2517 if (pp)
2518 pp->next = si;
2519 else
2520 rn->info = si;
2521 if (cp)
2522 cp->prev = si;
2523 si->prev = pp;
2524 si->next = cp;
2525
2526 /* Install into rib. */
2527 static_install_ipv4 (p, si);
2528
2529 return 1;
2530}
2531
2532/* Delete static route from static route configuration. */
2533int
hasso39db97e2004-10-12 20:50:58 +00002534static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00002535 u_char distance, u_int32_t vrf_id)
2536{
2537 u_char type = 0;
2538 struct route_node *rn;
2539 struct static_ipv4 *si;
2540 struct route_table *stable;
2541
2542 /* Lookup table. */
2543 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2544 if (! stable)
2545 return -1;
2546
2547 /* Lookup static route prefix. */
2548 rn = route_node_lookup (stable, p);
2549 if (! rn)
2550 return 0;
2551
2552 /* Make flags. */
2553 if (gate)
2554 type = STATIC_IPV4_GATEWAY;
2555 else if (ifname)
2556 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002557 else
2558 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002559
2560 /* Find same static route is the tree */
2561 for (si = rn->info; si; si = si->next)
2562 if (type == si->type
2563 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2564 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2565 break;
2566
2567 /* Can't find static route. */
2568 if (! si)
2569 {
2570 route_unlock_node (rn);
2571 return 0;
2572 }
2573
2574 /* Install into rib. */
2575 static_uninstall_ipv4 (p, si);
2576
2577 /* Unlink static route from linked list. */
2578 if (si->prev)
2579 si->prev->next = si->next;
2580 else
2581 rn->info = si->next;
2582 if (si->next)
2583 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002584 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002585
2586 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002587 if (ifname)
2588 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002589 XFREE (MTYPE_STATIC_IPV4, si);
2590
paul143a3852003-09-29 20:06:13 +00002591 route_unlock_node (rn);
2592
paul718e3742002-12-13 20:15:29 +00002593 return 1;
2594}
2595
David Lamparter6b0655a2014-06-04 06:53:35 +02002596
paul718e3742002-12-13 20:15:29 +00002597#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00002598static int
paul718e3742002-12-13 20:15:29 +00002599rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2600 struct in6_addr *gate, unsigned int ifindex, int table)
2601{
hasso726f9b22003-05-25 21:04:54 +00002602 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2603#if defined (MUSICA) || defined (LINUX)
2604 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2605 if (p->prefixlen == 96)
2606 return 0;
2607#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00002608 return 1;
hasso726f9b22003-05-25 21:04:54 +00002609 }
paul718e3742002-12-13 20:15:29 +00002610 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
2611 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
2612 {
2613 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
2614 return 1;
2615 }
2616 return 0;
2617}
2618
2619int
2620rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00002621 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
G.Balajif768f362011-11-26 22:10:39 +04002622 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002623{
2624 struct rib *rib;
2625 struct rib *same = NULL;
2626 struct route_table *table;
2627 struct route_node *rn;
2628 struct nexthop *nexthop;
2629
paul718e3742002-12-13 20:15:29 +00002630 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002631 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002632 if (! table)
2633 return 0;
2634
2635 /* Make sure mask is applied. */
2636 apply_mask_ipv6 (p);
2637
2638 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002639 if (!distance)
2640 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002641
2642 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2643 distance = 200;
2644
2645 /* Filter bogus route. */
2646 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
2647 return 0;
2648
2649 /* Lookup route node.*/
2650 rn = route_node_get (table, (struct prefix *) p);
2651
2652 /* If same type of route are installed, treat it as a implicit
2653 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002654 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002655 {
Paul Jakma6d691122006-07-27 21:49:00 +00002656 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2657 continue;
2658
hassoebf1ead2005-09-21 14:58:20 +00002659 if (rib->type != type)
2660 continue;
2661 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002662 {
2663 same = rib;
paul718e3742002-12-13 20:15:29 +00002664 break;
2665 }
hassoebf1ead2005-09-21 14:58:20 +00002666 else if ((nexthop = rib->nexthop) &&
2667 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2668 nexthop->ifindex == ifindex)
2669 {
2670 rib->refcnt++;
2671 return 0;
2672 }
paul718e3742002-12-13 20:15:29 +00002673 }
2674
2675 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002676 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2677
paul718e3742002-12-13 20:15:29 +00002678 rib->type = type;
2679 rib->distance = distance;
2680 rib->flags = flags;
2681 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00002682 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00002683 rib->nexthop_num = 0;
2684 rib->uptime = time (NULL);
2685
2686 /* Nexthop settings. */
2687 if (gate)
2688 {
2689 if (ifindex)
2690 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2691 else
2692 nexthop_ipv6_add (rib, gate);
2693 }
2694 else
2695 nexthop_ifindex_add (rib, ifindex);
2696
2697 /* If this route is kernel route, set FIB flag to the route. */
2698 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2699 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2700 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2701
2702 /* Link new rib to node.*/
2703 rib_addnode (rn, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002704 if (IS_ZEBRA_DEBUG_RIB)
2705 {
2706 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
2707 __func__, rn, rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00002708 rib_dump (p, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002709 }
paul718e3742002-12-13 20:15:29 +00002710
paul718e3742002-12-13 20:15:29 +00002711 /* Free implicit route.*/
2712 if (same)
Vincent Bernatfed643f2012-10-23 16:00:42 +00002713 {
2714 if (IS_ZEBRA_DEBUG_RIB)
2715 {
2716 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
2717 __func__, rn, same);
David Lamparterf7bf4152013-10-22 17:10:21 +00002718 rib_dump (p, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002719 }
paul4d38fdb2005-04-28 17:35:14 +00002720 rib_delnode (rn, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002721 }
paul4d38fdb2005-04-28 17:35:14 +00002722
2723 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002724 return 0;
2725}
2726
hassoebf1ead2005-09-21 14:58:20 +00002727/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002728int
2729rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
G.Balajif768f362011-11-26 22:10:39 +04002730 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002731{
2732 struct route_table *table;
2733 struct route_node *rn;
2734 struct rib *rib;
2735 struct rib *fib = NULL;
2736 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002737 struct nexthop *nexthop, *tnexthop;
2738 int recursing;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002739 char buf1[INET6_ADDRSTRLEN];
2740 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002741
2742 /* Apply mask. */
2743 apply_mask_ipv6 (p);
2744
2745 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002746 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002747 if (! table)
2748 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002749
paul718e3742002-12-13 20:15:29 +00002750 /* Lookup route node. */
2751 rn = route_node_lookup (table, (struct prefix *) p);
2752 if (! rn)
2753 {
2754 if (IS_ZEBRA_DEBUG_KERNEL)
2755 {
2756 if (gate)
ajsb6178002004-12-07 21:12:56 +00002757 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002758 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002759 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002760 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002761 ifindex);
2762 else
ajsb6178002004-12-07 21:12:56 +00002763 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002764 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002765 p->prefixlen,
2766 ifindex);
2767 }
2768 return ZEBRA_ERR_RTNOEXIST;
2769 }
2770
2771 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002772 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002773 {
Paul Jakma6d691122006-07-27 21:49:00 +00002774 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2775 continue;
2776
paul718e3742002-12-13 20:15:29 +00002777 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2778 fib = rib;
2779
hassoebf1ead2005-09-21 14:58:20 +00002780 if (rib->type != type)
2781 continue;
2782 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002783 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002784 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002785 if (nexthop->ifindex != ifindex)
2786 continue;
hassoebf1ead2005-09-21 14:58:20 +00002787 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002788 {
hassoebf1ead2005-09-21 14:58:20 +00002789 rib->refcnt--;
2790 route_unlock_node (rn);
2791 route_unlock_node (rn);
2792 return 0;
paul718e3742002-12-13 20:15:29 +00002793 }
hassoebf1ead2005-09-21 14:58:20 +00002794 same = rib;
2795 break;
paul718e3742002-12-13 20:15:29 +00002796 }
hassoebf1ead2005-09-21 14:58:20 +00002797 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002798 else
2799 {
2800 if (gate == NULL)
2801 {
2802 same = rib;
2803 break;
2804 }
2805 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2806 if (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate))
2807 {
2808 same = rib;
2809 break;
2810 }
2811 if (same)
2812 break;
2813 }
paul718e3742002-12-13 20:15:29 +00002814 }
2815
2816 /* If same type of route can't be found and this message is from
2817 kernel. */
2818 if (! same)
2819 {
2820 if (fib && type == ZEBRA_ROUTE_KERNEL)
2821 {
2822 /* Unset flags. */
2823 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2824 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2825
2826 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2827 }
2828 else
2829 {
2830 if (IS_ZEBRA_DEBUG_KERNEL)
2831 {
2832 if (gate)
ajsb6178002004-12-07 21:12:56 +00002833 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002834 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002835 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002836 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002837 ifindex,
2838 type);
2839 else
ajsb6178002004-12-07 21:12:56 +00002840 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002841 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002842 p->prefixlen,
2843 ifindex,
2844 type);
2845 }
2846 route_unlock_node (rn);
2847 return ZEBRA_ERR_RTNOEXIST;
2848 }
2849 }
2850
2851 if (same)
2852 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002853
paul718e3742002-12-13 20:15:29 +00002854 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002855 return 0;
2856}
David Lamparter6b0655a2014-06-04 06:53:35 +02002857
paul718e3742002-12-13 20:15:29 +00002858/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002859static void
paul718e3742002-12-13 20:15:29 +00002860static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2861{
2862 struct rib *rib;
2863 struct route_table *table;
2864 struct route_node *rn;
2865
2866 /* Lookup table. */
2867 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2868 if (! table)
2869 return;
2870
2871 /* Lookup existing route */
2872 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002873 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002874 {
2875 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2876 continue;
2877
2878 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2879 break;
2880 }
paul718e3742002-12-13 20:15:29 +00002881
2882 if (rib)
2883 {
2884 /* Same distance static route is there. Update it with new
2885 nexthop. */
paul718e3742002-12-13 20:15:29 +00002886 route_unlock_node (rn);
2887
2888 switch (si->type)
2889 {
2890 case STATIC_IPV6_GATEWAY:
2891 nexthop_ipv6_add (rib, &si->ipv6);
2892 break;
2893 case STATIC_IPV6_IFNAME:
2894 nexthop_ifname_add (rib, si->ifname);
2895 break;
2896 case STATIC_IPV6_GATEWAY_IFNAME:
2897 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2898 break;
2899 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002900 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002901 }
2902 else
2903 {
2904 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002905 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2906
paul718e3742002-12-13 20:15:29 +00002907 rib->type = ZEBRA_ROUTE_STATIC;
2908 rib->distance = si->distance;
2909 rib->metric = 0;
Dinesh G Duttd1b09912014-09-30 12:54:13 -07002910 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002911 rib->nexthop_num = 0;
2912
2913 switch (si->type)
2914 {
2915 case STATIC_IPV6_GATEWAY:
2916 nexthop_ipv6_add (rib, &si->ipv6);
2917 break;
2918 case STATIC_IPV6_IFNAME:
2919 nexthop_ifname_add (rib, si->ifname);
2920 break;
2921 case STATIC_IPV6_GATEWAY_IFNAME:
2922 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2923 break;
2924 }
2925
hasso81dfcaa2003-05-25 19:21:25 +00002926 /* Save the flags of this static routes (reject, blackhole) */
2927 rib->flags = si->flags;
2928
paul718e3742002-12-13 20:15:29 +00002929 /* Link this rib to the tree. */
2930 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002931 }
2932}
2933
paula1ac18c2005-06-28 17:17:12 +00002934static int
paul718e3742002-12-13 20:15:29 +00002935static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2936{
2937 if (nexthop->type == NEXTHOP_TYPE_IPV6
2938 && si->type == STATIC_IPV6_GATEWAY
2939 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2940 return 1;
2941 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2942 && si->type == STATIC_IPV6_IFNAME
2943 && strcmp (nexthop->ifname, si->ifname) == 0)
2944 return 1;
2945 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2946 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2947 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2948 && strcmp (nexthop->ifname, si->ifname) == 0)
2949 return 1;
paule8e19462006-01-19 20:16:55 +00002950 return 0;
paul718e3742002-12-13 20:15:29 +00002951}
2952
paula1ac18c2005-06-28 17:17:12 +00002953static void
paul718e3742002-12-13 20:15:29 +00002954static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2955{
2956 struct route_table *table;
2957 struct route_node *rn;
2958 struct rib *rib;
2959 struct nexthop *nexthop;
2960
2961 /* Lookup table. */
2962 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2963 if (! table)
2964 return;
2965
2966 /* Lookup existing route with type and distance. */
2967 rn = route_node_lookup (table, (struct prefix *) p);
2968 if (! rn)
2969 return;
2970
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002971 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002972 {
2973 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2974 continue;
2975
2976 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2977 break;
2978 }
2979
paul718e3742002-12-13 20:15:29 +00002980 if (! rib)
2981 {
2982 route_unlock_node (rn);
2983 return;
2984 }
2985
2986 /* Lookup nexthop. */
2987 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2988 if (static_ipv6_nexthop_same (nexthop, si))
2989 break;
2990
2991 /* Can't find nexthop. */
2992 if (! nexthop)
2993 {
2994 route_unlock_node (rn);
2995 return;
2996 }
2997
2998 /* Check nexthop. */
2999 if (rib->nexthop_num == 1)
3000 {
3001 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003002 }
3003 else
3004 {
paul6baeb982003-10-28 03:47:15 +00003005 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
3006 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00003007 nexthop_delete (rib, nexthop);
3008 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00003009 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003010 }
paul718e3742002-12-13 20:15:29 +00003011 /* Unlock node. */
3012 route_unlock_node (rn);
3013}
3014
3015/* Add static route into static route configuration. */
3016int
3017static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00003018 const char *ifname, u_char flags, u_char distance,
3019 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00003020{
3021 struct route_node *rn;
3022 struct static_ipv6 *si;
3023 struct static_ipv6 *pp;
3024 struct static_ipv6 *cp;
3025 struct route_table *stable;
3026
3027 /* Lookup table. */
3028 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
3029 if (! stable)
3030 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00003031
3032 if (!gate &&
3033 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
3034 return -1;
3035
3036 if (!ifname &&
3037 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
3038 return -1;
paul718e3742002-12-13 20:15:29 +00003039
3040 /* Lookup static route prefix. */
3041 rn = route_node_get (stable, p);
3042
3043 /* Do nothing if there is a same static route. */
3044 for (si = rn->info; si; si = si->next)
3045 {
3046 if (distance == si->distance
3047 && type == si->type
3048 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
3049 && (! ifname || strcmp (ifname, si->ifname) == 0))
3050 {
3051 route_unlock_node (rn);
3052 return 0;
3053 }
3054 }
3055
3056 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07003057 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
paul718e3742002-12-13 20:15:29 +00003058
3059 si->type = type;
3060 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00003061 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00003062
3063 switch (type)
3064 {
3065 case STATIC_IPV6_GATEWAY:
3066 si->ipv6 = *gate;
3067 break;
3068 case STATIC_IPV6_IFNAME:
3069 si->ifname = XSTRDUP (0, ifname);
3070 break;
3071 case STATIC_IPV6_GATEWAY_IFNAME:
3072 si->ipv6 = *gate;
3073 si->ifname = XSTRDUP (0, ifname);
3074 break;
3075 }
3076
3077 /* Add new static route information to the tree with sort by
3078 distance value and gateway address. */
3079 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
3080 {
3081 if (si->distance < cp->distance)
3082 break;
3083 if (si->distance > cp->distance)
3084 continue;
3085 }
3086
3087 /* Make linked list. */
3088 if (pp)
3089 pp->next = si;
3090 else
3091 rn->info = si;
3092 if (cp)
3093 cp->prev = si;
3094 si->prev = pp;
3095 si->next = cp;
3096
3097 /* Install into rib. */
3098 static_install_ipv6 (p, si);
3099
3100 return 1;
3101}
3102
3103/* Delete static route from static route configuration. */
3104int
3105static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00003106 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00003107{
3108 struct route_node *rn;
3109 struct static_ipv6 *si;
3110 struct route_table *stable;
3111
3112 /* Lookup table. */
3113 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
3114 if (! stable)
3115 return -1;
3116
3117 /* Lookup static route prefix. */
3118 rn = route_node_lookup (stable, p);
3119 if (! rn)
3120 return 0;
3121
3122 /* Find same static route is the tree */
3123 for (si = rn->info; si; si = si->next)
3124 if (distance == si->distance
3125 && type == si->type
3126 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
3127 && (! ifname || strcmp (ifname, si->ifname) == 0))
3128 break;
3129
3130 /* Can't find static route. */
3131 if (! si)
3132 {
3133 route_unlock_node (rn);
3134 return 0;
3135 }
3136
3137 /* Install into rib. */
3138 static_uninstall_ipv6 (p, si);
3139
3140 /* Unlink static route from linked list. */
3141 if (si->prev)
3142 si->prev->next = si->next;
3143 else
3144 rn->info = si->next;
3145 if (si->next)
3146 si->next->prev = si->prev;
3147
3148 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00003149 if (ifname)
3150 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00003151 XFREE (MTYPE_STATIC_IPV6, si);
3152
3153 return 1;
3154}
3155#endif /* HAVE_IPV6 */
David Lamparter6b0655a2014-06-04 06:53:35 +02003156
paul718e3742002-12-13 20:15:29 +00003157/* RIB update function. */
3158void
paula1ac18c2005-06-28 17:17:12 +00003159rib_update (void)
paul718e3742002-12-13 20:15:29 +00003160{
3161 struct route_node *rn;
3162 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00003163
paul718e3742002-12-13 20:15:29 +00003164 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
3165 if (table)
3166 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003167 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003168 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003169
3170 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
3171 if (table)
3172 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003173 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003174 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003175}
3176
David Lamparter6b0655a2014-06-04 06:53:35 +02003177
paul718e3742002-12-13 20:15:29 +00003178/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00003179static void
paul718e3742002-12-13 20:15:29 +00003180rib_weed_table (struct route_table *table)
3181{
3182 struct route_node *rn;
3183 struct rib *rib;
3184 struct rib *next;
3185
3186 if (table)
3187 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003188 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003189 {
Paul Jakma6d691122006-07-27 21:49:00 +00003190 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3191 continue;
3192
paulb21b19c2003-06-15 01:28:29 +00003193 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00003194 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00003195 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003196 }
3197}
3198
3199/* Delete all routes from non main table. */
3200void
paula1ac18c2005-06-28 17:17:12 +00003201rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00003202{
3203 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3204 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3205}
David Lamparter6b0655a2014-06-04 06:53:35 +02003206
paul718e3742002-12-13 20:15:29 +00003207/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00003208static void
paul718e3742002-12-13 20:15:29 +00003209rib_sweep_table (struct route_table *table)
3210{
3211 struct route_node *rn;
3212 struct rib *rib;
3213 struct rib *next;
3214 int ret = 0;
3215
3216 if (table)
3217 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003218 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003219 {
Paul Jakma6d691122006-07-27 21:49:00 +00003220 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3221 continue;
3222
paul718e3742002-12-13 20:15:29 +00003223 if (rib->type == ZEBRA_ROUTE_KERNEL &&
3224 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
3225 {
3226 ret = rib_uninstall_kernel (rn, rib);
3227 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00003228 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003229 }
3230 }
3231}
3232
3233/* Sweep all RIB tables. */
3234void
paula1ac18c2005-06-28 17:17:12 +00003235rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00003236{
3237 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3238 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3239}
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003240
3241/* Remove specific by protocol routes from 'table'. */
3242static unsigned long
3243rib_score_proto_table (u_char proto, struct route_table *table)
3244{
3245 struct route_node *rn;
3246 struct rib *rib;
3247 struct rib *next;
3248 unsigned long n = 0;
3249
3250 if (table)
3251 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003252 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003253 {
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003254 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3255 continue;
3256 if (rib->type == proto)
3257 {
3258 rib_delnode (rn, rib);
3259 n++;
3260 }
3261 }
3262
3263 return n;
3264}
3265
3266/* Remove specific by protocol routes. */
3267unsigned long
3268rib_score_proto (u_char proto)
3269{
3270 return rib_score_proto_table (proto, vrf_table (AFI_IP, SAFI_UNICAST, 0))
3271 +rib_score_proto_table (proto, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3272}
3273
paul718e3742002-12-13 20:15:29 +00003274/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00003275static void
paul718e3742002-12-13 20:15:29 +00003276rib_close_table (struct route_table *table)
3277{
3278 struct route_node *rn;
3279 struct rib *rib;
3280
3281 if (table)
3282 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003283 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00003284 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003285 if (!CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
3286 continue;
3287
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00003288 zfpm_trigger_update (rn, NULL);
3289
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003290 if (! RIB_SYSTEM_ROUTE (rib))
3291 rib_uninstall_kernel (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00003292 }
paul718e3742002-12-13 20:15:29 +00003293}
3294
3295/* Close all RIB tables. */
3296void
paula1ac18c2005-06-28 17:17:12 +00003297rib_close (void)
paul718e3742002-12-13 20:15:29 +00003298{
3299 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3300 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3301}
David Lamparter6b0655a2014-06-04 06:53:35 +02003302
paul718e3742002-12-13 20:15:29 +00003303/* Routing information base initialize. */
3304void
paula1ac18c2005-06-28 17:17:12 +00003305rib_init (void)
paul718e3742002-12-13 20:15:29 +00003306{
paul4d38fdb2005-04-28 17:35:14 +00003307 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00003308 /* VRF initialization. */
3309 vrf_init ();
3310}
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003311
3312/*
3313 * vrf_id_get_next
3314 *
3315 * Get the first vrf id that is greater than the given vrf id if any.
3316 *
3317 * Returns TRUE if a vrf id was found, FALSE otherwise.
3318 */
3319static inline int
3320vrf_id_get_next (uint32_t id, uint32_t *next_id_p)
3321{
3322 while (++id < vector_active (vrf_vector))
3323 {
3324 if (vrf_lookup (id))
3325 {
3326 *next_id_p = id;
3327 return 1;
3328 }
3329 }
3330
3331 return 0;
3332}
3333
3334/*
3335 * rib_tables_iter_next
3336 *
3337 * Returns the next table in the iteration.
3338 */
3339struct route_table *
3340rib_tables_iter_next (rib_tables_iter_t *iter)
3341{
3342 struct route_table *table;
3343
3344 /*
3345 * Array that helps us go over all AFI/SAFI combinations via one
3346 * index.
3347 */
3348 static struct {
3349 afi_t afi;
3350 safi_t safi;
3351 } afi_safis[] = {
3352 { AFI_IP, SAFI_UNICAST },
3353 { AFI_IP, SAFI_MULTICAST },
3354 { AFI_IP6, SAFI_UNICAST },
3355 { AFI_IP6, SAFI_MULTICAST },
3356 };
3357
3358 table = NULL;
3359
3360 switch (iter->state)
3361 {
3362
3363 case RIB_TABLES_ITER_S_INIT:
3364 iter->vrf_id = 0;
3365 iter->afi_safi_ix = -1;
3366
3367 /* Fall through */
3368
3369 case RIB_TABLES_ITER_S_ITERATING:
3370 iter->afi_safi_ix++;
3371 while (1)
3372 {
3373
3374 while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
3375 {
3376 table = vrf_table (afi_safis[iter->afi_safi_ix].afi,
3377 afi_safis[iter->afi_safi_ix].safi,
3378 iter->vrf_id);
3379 if (table)
3380 break;
3381
3382 iter->afi_safi_ix++;
3383 }
3384
3385 /*
3386 * Found another table in this vrf.
3387 */
3388 if (table)
3389 break;
3390
3391 /*
3392 * Done with all tables in the current vrf, go to the next
3393 * one.
3394 */
3395 if (!vrf_id_get_next (iter->vrf_id, &iter->vrf_id))
3396 break;
3397
3398 iter->afi_safi_ix = 0;
3399 }
3400
3401 break;
3402
3403 case RIB_TABLES_ITER_S_DONE:
3404 return NULL;
3405 }
3406
3407 if (table)
3408 iter->state = RIB_TABLES_ITER_S_ITERATING;
3409 else
3410 iter->state = RIB_TABLES_ITER_S_DONE;
3411
3412 return table;
3413}