blob: a07036e5962b1eaaaca3be9d612e95fd3782621b [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* Routing Information Base.
2 * Copyright (C) 1997, 98, 99, 2001 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "prefix.h"
25#include "table.h"
26#include "memory.h"
27#include "str.h"
28#include "command.h"
29#include "if.h"
30#include "log.h"
31#include "sockunion.h"
paul4d38fdb2005-04-28 17:35:14 +000032#include "linklist.h"
33#include "thread.h"
34#include "workqueue.h"
Paul Jakma7514fb72007-05-02 16:05:35 +000035#include "prefix.h"
36#include "routemap.h"
paul718e3742002-12-13 20:15:29 +000037
38#include "zebra/rib.h"
39#include "zebra/rt.h"
40#include "zebra/zserv.h"
41#include "zebra/redistribute.h"
42#include "zebra/debug.h"
Avneesh Sachdev5adc2522012-11-13 22:48:59 +000043#include "zebra/zebra_fpm.h"
paul718e3742002-12-13 20:15:29 +000044
45/* Default rtm_table for all clients */
paulb21b19c2003-06-15 01:28:29 +000046extern struct zebra_t zebrad;
paul718e3742002-12-13 20:15:29 +000047
Paul Jakma457eb9a2006-07-27 19:59:58 +000048/* Hold time for RIB process, should be very minimal.
49 * it is useful to able to set it otherwise for testing, hence exported
50 * as global here for test-rig code.
51 */
52int rib_process_hold_time = 10;
53
paul718e3742002-12-13 20:15:29 +000054/* Each route type's string and default distance value. */
Stephen Hemmingerd145bc02008-08-17 17:41:37 +010055static const struct
paul718e3742002-12-13 20:15:29 +000056{
57 int key;
58 int distance;
Paul Jakma57345092011-12-25 17:52:09 +010059} route_info[ZEBRA_ROUTE_MAX] =
paul718e3742002-12-13 20:15:29 +000060{
Paul Jakma57345092011-12-25 17:52:09 +010061 [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0},
62 [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0},
63 [ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0},
64 [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1},
65 [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120},
66 [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120},
67 [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110},
68 [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110},
69 [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115},
70 [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */},
71 [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 95},
David Lamparter7052f222009-08-27 00:28:28 +020072 /* no entry/default: 150 */
paul718e3742002-12-13 20:15:29 +000073};
David Lamparter6b0655a2014-06-04 06:53:35 +020074
paul718e3742002-12-13 20:15:29 +000075/* Vector for routing table. */
Stephen Hemmingerd145bc02008-08-17 17:41:37 +010076static vector vrf_vector;
paul718e3742002-12-13 20:15:29 +000077
David Lamparter94813742014-04-24 20:22:53 +020078static void
79_rnode_zlog(const char *_func, struct route_node *rn, int priority,
80 const char *msgfmt, ...)
81{
82 char buf[INET6_ADDRSTRLEN + 4], *bptr;
83 char msgbuf[512];
84 va_list ap;
85
86 va_start(ap, msgfmt);
87 vsnprintf(msgbuf, sizeof(msgbuf), msgfmt, ap);
88 va_end(ap);
89
90 if (rn)
91 {
David Lamparterab2ba612015-01-22 19:02:13 +010092 rib_table_info_t *info = rn->table->info;
93
David Lamparter94813742014-04-24 20:22:53 +020094 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
95 bptr = buf + strlen(buf);
David Lamparterab2ba612015-01-22 19:02:13 +010096 snprintf(bptr, buf + sizeof(buf) - bptr, "/%d%s", rn->p.prefixlen,
97 info->safi == SAFI_MULTICAST ? " (MRIB)" : "");
David Lamparter94813742014-04-24 20:22:53 +020098 }
99 else
100 {
101 snprintf(buf, sizeof(buf), "{(route_node *) NULL}");
102 }
103
104 zlog (NULL, priority, "%s: %s: %s", _func, buf, msgbuf);
105}
106
107#define rnode_debug(node, ...) \
108 _rnode_zlog(__func__, node, LOG_DEBUG, __VA_ARGS__)
109#define rnode_info(node, ...) \
110 _rnode_zlog(__func__, node, LOG_INFO, __VA_ARGS__)
111
Avneesh Sachdev1b5ed1b2012-11-13 22:48:54 +0000112/*
113 * vrf_table_create
114 */
115static void
116vrf_table_create (struct vrf *vrf, afi_t afi, safi_t safi)
117{
118 rib_table_info_t *info;
119 struct route_table *table;
120
121 assert (!vrf->table[afi][safi]);
122
123 table = route_table_init ();
124 vrf->table[afi][safi] = table;
125
126 info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
127 info->vrf = vrf;
128 info->afi = afi;
129 info->safi = safi;
130 table->info = info;
131}
132
paul718e3742002-12-13 20:15:29 +0000133/* Allocate new VRF. */
paula1ac18c2005-06-28 17:17:12 +0000134static struct vrf *
hassofce954f2004-10-07 20:29:24 +0000135vrf_alloc (const char *name)
paul718e3742002-12-13 20:15:29 +0000136{
137 struct vrf *vrf;
138
139 vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
140
141 /* Put name. */
142 if (name)
143 vrf->name = XSTRDUP (MTYPE_VRF_NAME, name);
144
145 /* Allocate routing table and static table. */
Avneesh Sachdev1b5ed1b2012-11-13 22:48:54 +0000146 vrf_table_create (vrf, AFI_IP, SAFI_UNICAST);
147 vrf_table_create (vrf, AFI_IP6, SAFI_UNICAST);
paul718e3742002-12-13 20:15:29 +0000148 vrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
149 vrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
Avneesh Sachdev1b5ed1b2012-11-13 22:48:54 +0000150 vrf_table_create (vrf, AFI_IP, SAFI_MULTICAST);
151 vrf_table_create (vrf, AFI_IP6, SAFI_MULTICAST);
G.Balajicddf3912011-11-26 21:59:32 +0400152 vrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
153 vrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
154
paul718e3742002-12-13 20:15:29 +0000155
156 return vrf;
157}
158
paul718e3742002-12-13 20:15:29 +0000159/* Lookup VRF by identifier. */
160struct vrf *
161vrf_lookup (u_int32_t id)
162{
163 return vector_lookup (vrf_vector, id);
164}
165
paul718e3742002-12-13 20:15:29 +0000166/* Initialize VRF. */
paula1ac18c2005-06-28 17:17:12 +0000167static void
168vrf_init (void)
paul718e3742002-12-13 20:15:29 +0000169{
170 struct vrf *default_table;
171
172 /* Allocate VRF vector. */
173 vrf_vector = vector_init (1);
174
175 /* Allocate default main table. */
176 default_table = vrf_alloc ("Default-IP-Routing-Table");
177
178 /* Default table index must be 0. */
179 vector_set_index (vrf_vector, 0, default_table);
180}
181
182/* Lookup route table. */
183struct route_table *
184vrf_table (afi_t afi, safi_t safi, u_int32_t id)
185{
186 struct vrf *vrf;
187
188 vrf = vrf_lookup (id);
189 if (! vrf)
190 return NULL;
191
Leonid Rosenboim9499bf22012-12-06 20:17:41 +0000192 if( afi >= AFI_MAX || safi >= SAFI_MAX )
193 return NULL;
194
paul718e3742002-12-13 20:15:29 +0000195 return vrf->table[afi][safi];
196}
197
198/* Lookup static route table. */
199struct route_table *
200vrf_static_table (afi_t afi, safi_t safi, u_int32_t id)
201{
202 struct vrf *vrf;
203
204 vrf = vrf_lookup (id);
205 if (! vrf)
206 return NULL;
207
Leonid Rosenboim9499bf22012-12-06 20:17:41 +0000208 if( afi >= AFI_MAX || safi >= SAFI_MAX )
209 return NULL;
210
paul718e3742002-12-13 20:15:29 +0000211 return vrf->stable[afi][safi];
212}
David Lamparter6b0655a2014-06-04 06:53:35 +0200213
Avneesh Sachdev78deec42012-11-13 22:48:56 +0000214/*
215 * nexthop_type_to_str
216 */
217const char *
218nexthop_type_to_str (enum nexthop_types_t nh_type)
219{
220 static const char *desc[] = {
221 "none",
222 "Directly connected",
223 "Interface route",
224 "IPv4 nexthop",
225 "IPv4 nexthop with ifindex",
226 "IPv4 nexthop with ifname",
227 "IPv6 nexthop",
228 "IPv6 nexthop with ifindex",
229 "IPv6 nexthop with ifname",
230 "Null0 nexthop",
231 };
232
233 if (nh_type >= ZEBRA_NUM_OF (desc))
234 return "<Invalid nh type>";
235
236 return desc[nh_type];
237}
238
Christian Frankefa713d92013-07-05 15:35:37 +0000239/* Add nexthop to the end of a nexthop list. */
paula1ac18c2005-06-28 17:17:12 +0000240static void
Christian Frankefa713d92013-07-05 15:35:37 +0000241_nexthop_add (struct nexthop **target, struct nexthop *nexthop)
paul718e3742002-12-13 20:15:29 +0000242{
243 struct nexthop *last;
244
Christian Frankefa713d92013-07-05 15:35:37 +0000245 for (last = *target; last && last->next; last = last->next)
paul718e3742002-12-13 20:15:29 +0000246 ;
247 if (last)
248 last->next = nexthop;
249 else
Christian Frankefa713d92013-07-05 15:35:37 +0000250 *target = nexthop;
paul718e3742002-12-13 20:15:29 +0000251 nexthop->prev = last;
Christian Frankefa713d92013-07-05 15:35:37 +0000252}
paul718e3742002-12-13 20:15:29 +0000253
Christian Frankefa713d92013-07-05 15:35:37 +0000254/* Add nexthop to the end of a rib node's nexthop list */
255static void
256nexthop_add (struct rib *rib, struct nexthop *nexthop)
257{
258 _nexthop_add(&rib->nexthop, nexthop);
paul718e3742002-12-13 20:15:29 +0000259 rib->nexthop_num++;
260}
261
262/* Delete specified nexthop from the list. */
paula1ac18c2005-06-28 17:17:12 +0000263static void
paul718e3742002-12-13 20:15:29 +0000264nexthop_delete (struct rib *rib, struct nexthop *nexthop)
265{
266 if (nexthop->next)
267 nexthop->next->prev = nexthop->prev;
268 if (nexthop->prev)
269 nexthop->prev->next = nexthop->next;
270 else
271 rib->nexthop = nexthop->next;
272 rib->nexthop_num--;
273}
274
Christian Frankefa713d92013-07-05 15:35:37 +0000275static void nexthops_free(struct nexthop *nexthop);
276
paul718e3742002-12-13 20:15:29 +0000277/* Free nexthop. */
paula1ac18c2005-06-28 17:17:12 +0000278static void
paul718e3742002-12-13 20:15:29 +0000279nexthop_free (struct nexthop *nexthop)
280{
paula4b70762003-05-16 17:19:48 +0000281 if (nexthop->ifname)
282 XFREE (0, nexthop->ifname);
Christian Frankefa713d92013-07-05 15:35:37 +0000283 if (nexthop->resolved)
284 nexthops_free(nexthop->resolved);
paul718e3742002-12-13 20:15:29 +0000285 XFREE (MTYPE_NEXTHOP, nexthop);
286}
287
Christian Frankefa713d92013-07-05 15:35:37 +0000288/* Frees a list of nexthops */
289static void
290nexthops_free (struct nexthop *nexthop)
291{
292 struct nexthop *nh, *next;
293
294 for (nh = nexthop; nh; nh = next)
295 {
296 next = nh->next;
297 nexthop_free (nh);
298 }
299}
300
paul718e3742002-12-13 20:15:29 +0000301struct nexthop *
302nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
303{
304 struct nexthop *nexthop;
305
Stephen Hemminger393deb92008-08-18 14:13:29 -0700306 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000307 nexthop->type = NEXTHOP_TYPE_IFINDEX;
308 nexthop->ifindex = ifindex;
309
310 nexthop_add (rib, nexthop);
311
312 return nexthop;
313}
314
315struct nexthop *
316nexthop_ifname_add (struct rib *rib, char *ifname)
317{
318 struct nexthop *nexthop;
319
Stephen Hemminger393deb92008-08-18 14:13:29 -0700320 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000321 nexthop->type = NEXTHOP_TYPE_IFNAME;
paula4b70762003-05-16 17:19:48 +0000322 nexthop->ifname = XSTRDUP (0, ifname);
paul718e3742002-12-13 20:15:29 +0000323
324 nexthop_add (rib, nexthop);
325
326 return nexthop;
327}
328
329struct nexthop *
Paul Jakma7514fb72007-05-02 16:05:35 +0000330nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src)
paul718e3742002-12-13 20:15:29 +0000331{
332 struct nexthop *nexthop;
333
Stephen Hemminger393deb92008-08-18 14:13:29 -0700334 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000335 nexthop->type = NEXTHOP_TYPE_IPV4;
336 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000337 if (src)
338 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000339
340 nexthop_add (rib, nexthop);
341
342 return nexthop;
343}
344
Josh Bailey26e2ae32012-03-22 01:09:21 -0700345struct nexthop *
paul718e3742002-12-13 20:15:29 +0000346nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
Paul Jakma7514fb72007-05-02 16:05:35 +0000347 struct in_addr *src, unsigned int ifindex)
paul718e3742002-12-13 20:15:29 +0000348{
349 struct nexthop *nexthop;
350
Stephen Hemminger393deb92008-08-18 14:13:29 -0700351 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000352 nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
353 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000354 if (src)
355 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000356 nexthop->ifindex = ifindex;
357
358 nexthop_add (rib, nexthop);
359
360 return nexthop;
361}
362
363#ifdef HAVE_IPV6
364struct nexthop *
365nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
366{
367 struct nexthop *nexthop;
368
Stephen Hemminger393deb92008-08-18 14:13:29 -0700369 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000370 nexthop->type = NEXTHOP_TYPE_IPV6;
371 nexthop->gate.ipv6 = *ipv6;
372
373 nexthop_add (rib, nexthop);
374
375 return nexthop;
376}
377
paula1ac18c2005-06-28 17:17:12 +0000378static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000379nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
380 char *ifname)
381{
382 struct nexthop *nexthop;
383
Stephen Hemminger393deb92008-08-18 14:13:29 -0700384 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000385 nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
386 nexthop->gate.ipv6 = *ipv6;
387 nexthop->ifname = XSTRDUP (0, ifname);
388
389 nexthop_add (rib, nexthop);
390
391 return nexthop;
392}
393
paula1ac18c2005-06-28 17:17:12 +0000394static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000395nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
396 unsigned int ifindex)
397{
398 struct nexthop *nexthop;
399
Stephen Hemminger393deb92008-08-18 14:13:29 -0700400 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000401 nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
402 nexthop->gate.ipv6 = *ipv6;
403 nexthop->ifindex = ifindex;
404
405 nexthop_add (rib, nexthop);
406
407 return nexthop;
408}
409#endif /* HAVE_IPV6 */
410
paul595db7f2003-05-25 21:35:06 +0000411struct nexthop *
412nexthop_blackhole_add (struct rib *rib)
413{
414 struct nexthop *nexthop;
415
Stephen Hemminger393deb92008-08-18 14:13:29 -0700416 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul595db7f2003-05-25 21:35:06 +0000417 nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
418 SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
419
420 nexthop_add (rib, nexthop);
421
422 return nexthop;
423}
424
Christian Frankefa713d92013-07-05 15:35:37 +0000425/* This method checks whether a recursive nexthop has at
426 * least one resolved nexthop in the fib.
427 */
428int
429nexthop_has_fib_child(struct nexthop *nexthop)
430{
431 struct nexthop *nh;
432
433 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
434 return 0;
435
436 for (nh = nexthop->resolved; nh; nh = nh->next)
437 if (CHECK_FLAG (nh->flags, NEXTHOP_FLAG_FIB))
438 return 1;
439
440 return 0;
441}
442
paul718e3742002-12-13 20:15:29 +0000443/* If force flag is not set, do not modify falgs at all for uninstall
444 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000445static int
paul718e3742002-12-13 20:15:29 +0000446nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
447 struct route_node *top)
448{
449 struct prefix_ipv4 p;
450 struct route_table *table;
451 struct route_node *rn;
452 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000453 int resolved;
paul718e3742002-12-13 20:15:29 +0000454 struct nexthop *newhop;
Christian Frankefa713d92013-07-05 15:35:37 +0000455 struct nexthop *resolved_hop;
paul718e3742002-12-13 20:15:29 +0000456
457 if (nexthop->type == NEXTHOP_TYPE_IPV4)
458 nexthop->ifindex = 0;
459
460 if (set)
Christian Frankefa713d92013-07-05 15:35:37 +0000461 {
462 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
463 nexthops_free(nexthop->resolved);
464 nexthop->resolved = NULL;
465 }
paul718e3742002-12-13 20:15:29 +0000466
467 /* Make lookup prefix. */
468 memset (&p, 0, sizeof (struct prefix_ipv4));
469 p.family = AF_INET;
470 p.prefixlen = IPV4_MAX_PREFIXLEN;
471 p.prefix = nexthop->gate.ipv4;
472
473 /* Lookup table. */
474 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
475 if (! table)
476 return 0;
477
478 rn = route_node_match (table, (struct prefix *) &p);
479 while (rn)
480 {
481 route_unlock_node (rn);
482
David Warda50c1072009-12-03 15:34:39 +0300483 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000484 if (rn == top)
485 return 0;
486
487 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000488 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100489 {
490 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
491 continue;
492 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
493 break;
494 }
paul718e3742002-12-13 20:15:29 +0000495
496 /* If there is no selected route or matched route is EGP, go up
497 tree. */
498 if (! match
499 || match->type == ZEBRA_ROUTE_BGP)
500 {
501 do {
502 rn = rn->parent;
503 } while (rn && rn->info == NULL);
504 if (rn)
505 route_lock_node (rn);
506 }
507 else
508 {
Christian Franke48a53dc2013-07-05 15:35:38 +0000509 /* If the longest prefix match for the nexthop yields
510 * a blackhole, mark it as inactive. */
511 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE)
512 || CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT))
513 return 0;
514
paul718e3742002-12-13 20:15:29 +0000515 if (match->type == ZEBRA_ROUTE_CONNECT)
516 {
517 /* Directly point connected route. */
518 newhop = match->nexthop;
519 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
520 nexthop->ifindex = newhop->ifindex;
521
522 return 1;
523 }
524 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
525 {
Christian Frankefa713d92013-07-05 15:35:37 +0000526 resolved = 0;
paul718e3742002-12-13 20:15:29 +0000527 for (newhop = match->nexthop; newhop; newhop = newhop->next)
528 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
529 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
530 {
531 if (set)
532 {
533 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
Christian Frankefa713d92013-07-05 15:35:37 +0000534
535 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
536 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
Christian Frankec3e6b592013-07-05 15:35:40 +0000537 /* If the resolving route specifies a gateway, use it */
538 if (newhop->type == NEXTHOP_TYPE_IPV4
539 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX
540 || newhop->type == NEXTHOP_TYPE_IPV4_IFNAME)
541 {
542 resolved_hop->type = newhop->type;
543 resolved_hop->gate.ipv4 = newhop->gate.ipv4;
Christian Frankefa713d92013-07-05 15:35:37 +0000544
Christian Frankec3e6b592013-07-05 15:35:40 +0000545 if (newhop->ifindex)
546 {
547 resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
548 resolved_hop->ifindex = newhop->ifindex;
549 }
550 }
Christian Frankefa713d92013-07-05 15:35:37 +0000551
Christian Frankec3e6b592013-07-05 15:35:40 +0000552 /* If the resolving route is an interface route,
553 * it means the gateway we are looking up is connected
554 * to that interface. (The actual network is _not_ onlink).
555 * Therefore, the resolved route should have the original
556 * gateway as nexthop as it is directly connected.
557 *
558 * On Linux, we have to set the onlink netlink flag because
559 * otherwise, the kernel won't accept the route. */
paul718e3742002-12-13 20:15:29 +0000560 if (newhop->type == NEXTHOP_TYPE_IFINDEX
Christian Frankec3e6b592013-07-05 15:35:40 +0000561 || newhop->type == NEXTHOP_TYPE_IFNAME)
562 {
563 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
564 resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
565 resolved_hop->gate.ipv4 = nexthop->gate.ipv4;
566 resolved_hop->ifindex = newhop->ifindex;
567 }
Christian Frankefa713d92013-07-05 15:35:37 +0000568
569 _nexthop_add(&nexthop->resolved, resolved_hop);
paul718e3742002-12-13 20:15:29 +0000570 }
Christian Frankefa713d92013-07-05 15:35:37 +0000571 resolved = 1;
paul718e3742002-12-13 20:15:29 +0000572 }
Christian Frankefa713d92013-07-05 15:35:37 +0000573 return resolved;
paul718e3742002-12-13 20:15:29 +0000574 }
575 else
576 {
577 return 0;
578 }
579 }
580 }
581 return 0;
582}
583
584#ifdef HAVE_IPV6
585/* If force flag is not set, do not modify falgs at all for uninstall
586 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000587static int
paul718e3742002-12-13 20:15:29 +0000588nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
589 struct route_node *top)
590{
591 struct prefix_ipv6 p;
592 struct route_table *table;
593 struct route_node *rn;
594 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000595 int resolved;
paul718e3742002-12-13 20:15:29 +0000596 struct nexthop *newhop;
Christian Frankefa713d92013-07-05 15:35:37 +0000597 struct nexthop *resolved_hop;
paul718e3742002-12-13 20:15:29 +0000598
599 if (nexthop->type == NEXTHOP_TYPE_IPV6)
600 nexthop->ifindex = 0;
601
602 if (set)
Christian Frankefa713d92013-07-05 15:35:37 +0000603 {
604 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
605 nexthops_free(nexthop->resolved);
606 nexthop->resolved = NULL;
607 }
paul718e3742002-12-13 20:15:29 +0000608
609 /* Make lookup prefix. */
610 memset (&p, 0, sizeof (struct prefix_ipv6));
611 p.family = AF_INET6;
612 p.prefixlen = IPV6_MAX_PREFIXLEN;
613 p.prefix = nexthop->gate.ipv6;
614
615 /* Lookup table. */
616 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
617 if (! table)
618 return 0;
619
620 rn = route_node_match (table, (struct prefix *) &p);
621 while (rn)
622 {
623 route_unlock_node (rn);
624
David Warda50c1072009-12-03 15:34:39 +0300625 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000626 if (rn == top)
627 return 0;
628
629 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000630 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100631 {
632 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
633 continue;
634 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
635 break;
636 }
paul718e3742002-12-13 20:15:29 +0000637
638 /* If there is no selected route or matched route is EGP, go up
639 tree. */
640 if (! match
641 || match->type == ZEBRA_ROUTE_BGP)
642 {
643 do {
644 rn = rn->parent;
645 } while (rn && rn->info == NULL);
646 if (rn)
647 route_lock_node (rn);
648 }
649 else
650 {
Christian Franke48a53dc2013-07-05 15:35:38 +0000651 /* If the longest prefix match for the nexthop yields
652 * a blackhole, mark it as inactive. */
653 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE)
654 || CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT))
655 return 0;
656
paul718e3742002-12-13 20:15:29 +0000657 if (match->type == ZEBRA_ROUTE_CONNECT)
658 {
659 /* Directly point connected route. */
660 newhop = match->nexthop;
661
662 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
663 nexthop->ifindex = newhop->ifindex;
664
665 return 1;
666 }
667 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
668 {
Christian Frankefa713d92013-07-05 15:35:37 +0000669 resolved = 0;
paul718e3742002-12-13 20:15:29 +0000670 for (newhop = match->nexthop; newhop; newhop = newhop->next)
671 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
672 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
673 {
674 if (set)
675 {
676 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
Christian Frankefa713d92013-07-05 15:35:37 +0000677
678 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
679 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
Christian Frankec3e6b592013-07-05 15:35:40 +0000680 /* See nexthop_active_ipv4 for a description how the
681 * resolved nexthop is constructed. */
paul718e3742002-12-13 20:15:29 +0000682 if (newhop->type == NEXTHOP_TYPE_IPV6
683 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
684 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
Christian Frankec3e6b592013-07-05 15:35:40 +0000685 {
686 resolved_hop->type = newhop->type;
687 resolved_hop->gate.ipv6 = newhop->gate.ipv6;
688
689 if (newhop->ifindex)
690 {
691 resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
692 resolved_hop->ifindex = newhop->ifindex;
693 }
694 }
Christian Frankefa713d92013-07-05 15:35:37 +0000695
paul718e3742002-12-13 20:15:29 +0000696 if (newhop->type == NEXTHOP_TYPE_IFINDEX
Christian Frankec3e6b592013-07-05 15:35:40 +0000697 || newhop->type == NEXTHOP_TYPE_IFNAME)
698 {
699 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
700 resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
701 resolved_hop->gate.ipv6 = nexthop->gate.ipv6;
702 resolved_hop->ifindex = newhop->ifindex;
703 }
Christian Frankefa713d92013-07-05 15:35:37 +0000704
705 _nexthop_add(&nexthop->resolved, resolved_hop);
paul718e3742002-12-13 20:15:29 +0000706 }
Christian Frankefa713d92013-07-05 15:35:37 +0000707 resolved = 1;
paul718e3742002-12-13 20:15:29 +0000708 }
Christian Frankefa713d92013-07-05 15:35:37 +0000709 return resolved;
paul718e3742002-12-13 20:15:29 +0000710 }
711 else
712 {
713 return 0;
714 }
715 }
716 }
717 return 0;
718}
719#endif /* HAVE_IPV6 */
720
721struct rib *
Everton Marques83d71122014-09-19 16:39:34 -0300722rib_match_ipv4_safi (struct in_addr addr, safi_t safi, int skip_bgp)
Everton Marques3dea1782014-09-22 19:35:51 -0300723{
724 struct route_table *table;
725 struct route_node *rn;
726 struct rib *match;
727 struct nexthop *newhop, *tnewhop;
728 int recursing;
729
730 /* Lookup table. */
731 table = vrf_table (AFI_IP, safi, 0);
732 if (! table)
733 return 0;
734
735 rn = route_node_match_ipv4 (table, &addr);
736
737 while (rn)
738 {
739 route_unlock_node (rn);
740
741 /* Pick up selected route. */
742 RNODE_FOREACH_RIB (rn, match)
743 {
744 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
745 continue;
746 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
747 break;
748 }
749
750 /* If there is no selected route or matched route is EGP, go up
751 tree. */
Everton Marques83d71122014-09-19 16:39:34 -0300752 if (!match || (skip_bgp && (match->type == ZEBRA_ROUTE_BGP)))
Everton Marques3dea1782014-09-22 19:35:51 -0300753 {
754 do {
755 rn = rn->parent;
756 } while (rn && rn->info == NULL);
757 if (rn)
758 route_lock_node (rn);
759 }
760 else
761 {
762 if (match->type == ZEBRA_ROUTE_CONNECT)
763 /* Directly point connected route. */
764 return match;
765 else
766 {
767 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
768 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
769 return match;
770 return NULL;
771 }
772 }
773 }
774 return NULL;
775}
776
777struct rib *
paul718e3742002-12-13 20:15:29 +0000778rib_lookup_ipv4 (struct prefix_ipv4 *p)
779{
780 struct route_table *table;
781 struct route_node *rn;
782 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000783 struct nexthop *nexthop, *tnexthop;
784 int recursing;
paul718e3742002-12-13 20:15:29 +0000785
786 /* Lookup table. */
787 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
788 if (! table)
789 return 0;
790
791 rn = route_node_lookup (table, (struct prefix *) p);
792
793 /* No route for this prefix. */
794 if (! rn)
795 return NULL;
796
797 /* Unlock node. */
798 route_unlock_node (rn);
799
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000800 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100801 {
802 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
803 continue;
804 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
805 break;
806 }
paul718e3742002-12-13 20:15:29 +0000807
808 if (! match || match->type == ZEBRA_ROUTE_BGP)
809 return NULL;
810
811 if (match->type == ZEBRA_ROUTE_CONNECT)
812 return match;
813
Christian Frankefa713d92013-07-05 15:35:37 +0000814 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +0000815 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
816 return match;
817
818 return NULL;
819}
820
Denis Ovsienkodc958242007-08-13 16:03:06 +0000821/*
822 * This clone function, unlike its original rib_lookup_ipv4(), checks
823 * if specified IPv4 route record (prefix/mask -> gate) exists in
824 * the whole RIB and has ZEBRA_FLAG_SELECTED set.
825 *
826 * Return values:
827 * -1: error
828 * 0: exact match found
829 * 1: a match was found with a different gate
830 * 2: connected route found
831 * 3: no matches found
832 */
833int
834rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
835{
836 struct route_table *table;
837 struct route_node *rn;
838 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000839 struct nexthop *nexthop, *tnexthop;
840 int recursing;
841 int nexthops_active;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000842
843 /* Lookup table. */
844 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
845 if (! table)
846 return ZEBRA_RIB_LOOKUP_ERROR;
847
848 /* Scan the RIB table for exactly matching RIB entry. */
849 rn = route_node_lookup (table, (struct prefix *) p);
850
851 /* No route for this prefix. */
852 if (! rn)
853 return ZEBRA_RIB_NOTFOUND;
854
855 /* Unlock node. */
856 route_unlock_node (rn);
857
858 /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000859 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100860 {
861 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
862 continue;
863 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
864 break;
865 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000866
867 /* None such found :( */
868 if (!match)
869 return ZEBRA_RIB_NOTFOUND;
870
871 if (match->type == ZEBRA_ROUTE_CONNECT)
872 return ZEBRA_RIB_FOUND_CONNECTED;
873
874 /* Ok, we have a cood candidate, let's check it's nexthop list... */
Christian Frankefa713d92013-07-05 15:35:37 +0000875 nexthops_active = 0;
876 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000877 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000878 {
Christian Frankefa713d92013-07-05 15:35:37 +0000879 nexthops_active = 1;
880 if (nexthop->gate.ipv4.s_addr == sockunion2ip (qgate))
881 return ZEBRA_RIB_FOUND_EXACT;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000882 if (IS_ZEBRA_DEBUG_RIB)
Christian Frankefa713d92013-07-05 15:35:37 +0000883 {
884 char gate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
885 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
886 inet_ntop (AF_INET, &sockunion2ip(qgate), qgate_buf, INET_ADDRSTRLEN);
887 zlog_debug ("%s: qgate == %s, %s == %s", __func__,
888 qgate_buf, recursing ? "rgate" : "gate", gate_buf);
889 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000890 }
Christian Frankefa713d92013-07-05 15:35:37 +0000891
892 if (nexthops_active)
893 return ZEBRA_RIB_FOUND_NOGATE;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000894
895 return ZEBRA_RIB_NOTFOUND;
896}
897
paul718e3742002-12-13 20:15:29 +0000898#ifdef HAVE_IPV6
899struct rib *
900rib_match_ipv6 (struct in6_addr *addr)
901{
902 struct prefix_ipv6 p;
903 struct route_table *table;
904 struct route_node *rn;
905 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000906 struct nexthop *newhop, *tnewhop;
907 int recursing;
paul718e3742002-12-13 20:15:29 +0000908
909 /* Lookup table. */
910 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
911 if (! table)
912 return 0;
913
914 memset (&p, 0, sizeof (struct prefix_ipv6));
915 p.family = AF_INET6;
916 p.prefixlen = IPV6_MAX_PREFIXLEN;
917 IPV6_ADDR_COPY (&p.prefix, addr);
918
919 rn = route_node_match (table, (struct prefix *) &p);
920
921 while (rn)
922 {
923 route_unlock_node (rn);
924
925 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000926 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100927 {
928 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
929 continue;
930 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
931 break;
932 }
paul718e3742002-12-13 20:15:29 +0000933
934 /* If there is no selected route or matched route is EGP, go up
935 tree. */
936 if (! match
937 || match->type == ZEBRA_ROUTE_BGP)
938 {
939 do {
940 rn = rn->parent;
941 } while (rn && rn->info == NULL);
942 if (rn)
943 route_lock_node (rn);
944 }
945 else
946 {
947 if (match->type == ZEBRA_ROUTE_CONNECT)
948 /* Directly point connected route. */
949 return match;
950 else
951 {
Christian Frankefa713d92013-07-05 15:35:37 +0000952 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
paul718e3742002-12-13 20:15:29 +0000953 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
954 return match;
955 return NULL;
956 }
957 }
958 }
959 return NULL;
960}
961#endif /* HAVE_IPV6 */
962
Paul Jakma7514fb72007-05-02 16:05:35 +0000963#define RIB_SYSTEM_ROUTE(R) \
964 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
965
Denis Ovsienkodc958242007-08-13 16:03:06 +0000966/* This function verifies reachability of one given nexthop, which can be
967 * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
968 * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
969 * nexthop->ifindex will be updated appropriately as well.
970 * An existing route map can turn (otherwise active) nexthop into inactive, but
971 * not vice versa.
972 *
973 * The return value is the final value of 'ACTIVE' flag.
974 */
975
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300976static unsigned
paul718e3742002-12-13 20:15:29 +0000977nexthop_active_check (struct route_node *rn, struct rib *rib,
978 struct nexthop *nexthop, int set)
979{
Christian Frankef3a17322013-07-05 15:35:41 +0000980 rib_table_info_t *info = rn->table->info;
paul718e3742002-12-13 20:15:29 +0000981 struct interface *ifp;
Paul Jakma7514fb72007-05-02 16:05:35 +0000982 route_map_result_t ret = RMAP_MATCH;
983 extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
984 struct route_map *rmap;
985 int family;
paul718e3742002-12-13 20:15:29 +0000986
Paul Jakma7514fb72007-05-02 16:05:35 +0000987 family = 0;
paul718e3742002-12-13 20:15:29 +0000988 switch (nexthop->type)
989 {
990 case NEXTHOP_TYPE_IFINDEX:
991 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000992 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000993 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
994 else
995 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
996 break;
paul718e3742002-12-13 20:15:29 +0000997 case NEXTHOP_TYPE_IPV6_IFNAME:
Paul Jakma7514fb72007-05-02 16:05:35 +0000998 family = AFI_IP6;
999 case NEXTHOP_TYPE_IFNAME:
paul718e3742002-12-13 20:15:29 +00001000 ifp = if_lookup_by_name (nexthop->ifname);
Andrew J. Schorr3f087672008-01-08 20:12:46 +00001001 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001002 {
1003 if (set)
1004 nexthop->ifindex = ifp->ifindex;
1005 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1006 }
1007 else
1008 {
1009 if (set)
1010 nexthop->ifindex = 0;
1011 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1012 }
1013 break;
1014 case NEXTHOP_TYPE_IPV4:
1015 case NEXTHOP_TYPE_IPV4_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +00001016 family = AFI_IP;
paul718e3742002-12-13 20:15:29 +00001017 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
1018 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1019 else
1020 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1021 break;
1022#ifdef HAVE_IPV6
1023 case NEXTHOP_TYPE_IPV6:
Paul Jakma7514fb72007-05-02 16:05:35 +00001024 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +00001025 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
1026 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1027 else
1028 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1029 break;
1030 case NEXTHOP_TYPE_IPV6_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +00001031 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +00001032 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
1033 {
1034 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +00001035 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001036 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1037 else
1038 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1039 }
1040 else
1041 {
1042 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
1043 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1044 else
1045 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1046 }
1047 break;
1048#endif /* HAVE_IPV6 */
paul595db7f2003-05-25 21:35:06 +00001049 case NEXTHOP_TYPE_BLACKHOLE:
1050 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1051 break;
paul718e3742002-12-13 20:15:29 +00001052 default:
1053 break;
1054 }
Paul Jakma7514fb72007-05-02 16:05:35 +00001055 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1056 return 0;
1057
Christian Frankef3a17322013-07-05 15:35:41 +00001058 /* XXX: What exactly do those checks do? Do we support
1059 * e.g. IPv4 routes with IPv6 nexthops or vice versa? */
Paul Jakma7514fb72007-05-02 16:05:35 +00001060 if (RIB_SYSTEM_ROUTE(rib) ||
1061 (family == AFI_IP && rn->p.family != AF_INET) ||
1062 (family == AFI_IP6 && rn->p.family != AF_INET6))
1063 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1064
Christian Frankef3a17322013-07-05 15:35:41 +00001065 /* The original code didn't determine the family correctly
1066 * e.g. for NEXTHOP_TYPE_IFINDEX. Retrieve the correct afi
1067 * from the rib_table_info in those cases.
1068 * Possibly it may be better to use only the rib_table_info
1069 * in every case.
1070 */
1071 if (!family)
1072 family = info->afi;
1073
Paul Jakma7514fb72007-05-02 16:05:35 +00001074 rmap = 0;
1075 if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
1076 proto_rm[family][rib->type])
1077 rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
1078 if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
1079 rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
1080 if (rmap) {
1081 ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, nexthop);
1082 }
1083
1084 if (ret == RMAP_DENYMATCH)
1085 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
paul718e3742002-12-13 20:15:29 +00001086 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1087}
1088
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001089/* Iterate over all nexthops of the given RIB entry and refresh their
1090 * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
1091 * nexthop is found to toggle the ACTIVE flag, the whole rib structure
1092 * is flagged with ZEBRA_FLAG_CHANGED. The 4th 'set' argument is
1093 * transparently passed to nexthop_active_check().
1094 *
1095 * Return value is the new number of active nexthops.
1096 */
1097
paula1ac18c2005-06-28 17:17:12 +00001098static int
paul718e3742002-12-13 20:15:29 +00001099nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
1100{
1101 struct nexthop *nexthop;
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001102 unsigned int prev_active, prev_index, new_active;
paul718e3742002-12-13 20:15:29 +00001103
1104 rib->nexthop_active_num = 0;
1105 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1106
1107 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001108 {
1109 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001110 prev_index = nexthop->ifindex;
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001111 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
1112 rib->nexthop_active_num++;
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001113 if (prev_active != new_active ||
1114 prev_index != nexthop->ifindex)
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001115 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1116 }
paul718e3742002-12-13 20:15:29 +00001117 return rib->nexthop_active_num;
1118}
paul6baeb982003-10-28 03:47:15 +00001119
David Lamparter6b0655a2014-06-04 06:53:35 +02001120
paul718e3742002-12-13 20:15:29 +00001121
paula1ac18c2005-06-28 17:17:12 +00001122static void
paul718e3742002-12-13 20:15:29 +00001123rib_install_kernel (struct route_node *rn, struct rib *rib)
1124{
1125 int ret = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001126 struct nexthop *nexthop, *tnexthop;
1127 int recursing;
paul718e3742002-12-13 20:15:29 +00001128
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001129 /*
1130 * Make sure we update the FPM any time we send new information to
1131 * the kernel.
1132 */
1133 zfpm_trigger_update (rn, "installing in kernel");
paul718e3742002-12-13 20:15:29 +00001134 switch (PREFIX_FAMILY (&rn->p))
1135 {
1136 case AF_INET:
1137 ret = kernel_add_ipv4 (&rn->p, rib);
1138 break;
1139#ifdef HAVE_IPV6
1140 case AF_INET6:
1141 ret = kernel_add_ipv6 (&rn->p, rib);
1142 break;
1143#endif /* HAVE_IPV6 */
1144 }
1145
Denis Ovsienkodc958242007-08-13 16:03:06 +00001146 /* This condition is never met, if we are using rt_socket.c */
paul718e3742002-12-13 20:15:29 +00001147 if (ret < 0)
1148 {
Christian Frankefa713d92013-07-05 15:35:37 +00001149 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +00001150 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1151 }
1152}
1153
1154/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001155static int
paul718e3742002-12-13 20:15:29 +00001156rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
1157{
1158 int ret = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001159 struct nexthop *nexthop, *tnexthop;
1160 int recursing;
paul718e3742002-12-13 20:15:29 +00001161
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001162 /*
1163 * Make sure we update the FPM any time we send new information to
1164 * the kernel.
1165 */
1166 zfpm_trigger_update (rn, "uninstalling from kernel");
1167
paul718e3742002-12-13 20:15:29 +00001168 switch (PREFIX_FAMILY (&rn->p))
1169 {
1170 case AF_INET:
1171 ret = kernel_delete_ipv4 (&rn->p, rib);
1172 break;
1173#ifdef HAVE_IPV6
1174 case AF_INET6:
1175 ret = kernel_delete_ipv6 (&rn->p, rib);
1176 break;
1177#endif /* HAVE_IPV6 */
1178 }
1179
Christian Frankefa713d92013-07-05 15:35:37 +00001180 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +00001181 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1182
1183 return ret;
1184}
1185
1186/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001187static void
paul718e3742002-12-13 20:15:29 +00001188rib_uninstall (struct route_node *rn, struct rib *rib)
1189{
1190 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1191 {
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001192 zfpm_trigger_update (rn, "rib_uninstall");
1193
paul718e3742002-12-13 20:15:29 +00001194 redistribute_delete (&rn->p, rib);
1195 if (! RIB_SYSTEM_ROUTE (rib))
1196 rib_uninstall_kernel (rn, rib);
1197 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
1198 }
1199}
1200
Paul Jakma6d691122006-07-27 21:49:00 +00001201static void rib_unlink (struct route_node *, struct rib *);
1202
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001203/*
1204 * rib_can_delete_dest
1205 *
1206 * Returns TRUE if the given dest can be deleted from the table.
1207 */
1208static int
1209rib_can_delete_dest (rib_dest_t *dest)
1210{
1211 if (dest->routes)
1212 {
1213 return 0;
1214 }
1215
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001216 /*
1217 * Don't delete the dest if we have to update the FPM about this
1218 * prefix.
1219 */
1220 if (CHECK_FLAG (dest->flags, RIB_DEST_UPDATE_FPM) ||
1221 CHECK_FLAG (dest->flags, RIB_DEST_SENT_TO_FPM))
1222 return 0;
1223
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001224 return 1;
1225}
1226
1227/*
1228 * rib_gc_dest
1229 *
1230 * Garbage collect the rib dest corresponding to the given route node
1231 * if appropriate.
1232 *
1233 * Returns TRUE if the dest was deleted, FALSE otherwise.
1234 */
1235int
1236rib_gc_dest (struct route_node *rn)
1237{
1238 rib_dest_t *dest;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001239
1240 dest = rib_dest_from_rnode (rn);
1241 if (!dest)
1242 return 0;
1243
1244 if (!rib_can_delete_dest (dest))
1245 return 0;
1246
1247 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001248 rnode_debug (rn, "removing dest from table");
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001249
1250 dest->rnode = NULL;
1251 XFREE (MTYPE_RIB_DEST, dest);
1252 rn->info = NULL;
1253
1254 /*
1255 * Release the one reference that we keep on the route node.
1256 */
1257 route_unlock_node (rn);
1258 return 1;
1259}
1260
paul718e3742002-12-13 20:15:29 +00001261/* Core function for processing routing information base. */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001262static void
1263rib_process (struct route_node *rn)
paul718e3742002-12-13 20:15:29 +00001264{
1265 struct rib *rib;
1266 struct rib *next;
1267 struct rib *fib = NULL;
1268 struct rib *select = NULL;
Paul Jakma6d691122006-07-27 21:49:00 +00001269 struct rib *del = NULL;
pauld753e9e2003-01-22 19:45:50 +00001270 int installed = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001271 struct nexthop *nexthop = NULL, *tnexthop;
1272 int recursing;
Balaji95116332014-10-23 15:25:25 +00001273 rib_table_info_t *info;
1274
paul4d38fdb2005-04-28 17:35:14 +00001275 assert (rn);
Balaji95116332014-10-23 15:25:25 +00001276
1277 info = rn->table->info;
1278
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001279 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00001280 {
paul718e3742002-12-13 20:15:29 +00001281 /* Currently installed rib. */
1282 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Paul Jakma6d691122006-07-27 21:49:00 +00001283 {
1284 assert (fib == NULL);
1285 fib = rib;
1286 }
1287
1288 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1289 * which we need to do do further work with below.
1290 */
1291 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1292 {
1293 if (rib != fib)
1294 {
1295 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001296 rnode_debug (rn, "rn %p, removing rib %p", rn, rib);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001297 rib_unlink (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001298 }
1299 else
1300 del = rib;
1301
1302 continue;
1303 }
paul4d38fdb2005-04-28 17:35:14 +00001304
paul718e3742002-12-13 20:15:29 +00001305 /* Skip unreachable nexthop. */
1306 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +00001307 continue;
paul718e3742002-12-13 20:15:29 +00001308
Balaji95116332014-10-23 15:25:25 +00001309 if (info->safi == SAFI_MULTICAST)
1310 continue;
1311
paul718e3742002-12-13 20:15:29 +00001312 /* Infinit distance. */
1313 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +00001314 continue;
paul718e3742002-12-13 20:15:29 +00001315
paulaf887b52006-01-18 14:52:52 +00001316 /* Newly selected rib, the common case. */
1317 if (!select)
1318 {
1319 select = rib;
1320 continue;
1321 }
1322
1323 /* filter route selection in following order:
paulaf887b52006-01-18 14:52:52 +00001324 * - connected beats other types
paula8d9c1f2006-01-25 06:31:04 +00001325 * - lower distance beats higher
paulaf887b52006-01-18 14:52:52 +00001326 * - lower metric beats higher for equal distance
1327 * - last, hence oldest, route wins tie break.
1328 */
paula1038a12006-01-30 14:08:51 +00001329
1330 /* Connected routes. Pick the last connected
1331 * route of the set of lowest metric connected routes.
1332 */
paula8d9c1f2006-01-25 06:31:04 +00001333 if (rib->type == ZEBRA_ROUTE_CONNECT)
1334 {
paula1038a12006-01-30 14:08:51 +00001335 if (select->type != ZEBRA_ROUTE_CONNECT
paula8d9c1f2006-01-25 06:31:04 +00001336 || rib->metric <= select->metric)
paula1038a12006-01-30 14:08:51 +00001337 select = rib;
1338 continue;
paula8d9c1f2006-01-25 06:31:04 +00001339 }
1340 else if (select->type == ZEBRA_ROUTE_CONNECT)
1341 continue;
1342
1343 /* higher distance loses */
1344 if (rib->distance > select->distance)
1345 continue;
1346
1347 /* lower wins */
1348 if (rib->distance < select->distance)
1349 {
paulaf887b52006-01-18 14:52:52 +00001350 select = rib;
paula8d9c1f2006-01-25 06:31:04 +00001351 continue;
1352 }
1353
1354 /* metric tie-breaks equal distance */
1355 if (rib->metric <= select->metric)
1356 select = rib;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001357 } /* RNODE_FOREACH_RIB_SAFE */
Denis Ovsienkodc958242007-08-13 16:03:06 +00001358
1359 /* After the cycle is finished, the following pointers will be set:
1360 * select --- the winner RIB entry, if any was found, otherwise NULL
1361 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1362 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1363 * rib --- NULL
1364 */
1365
1366 /* Same RIB entry is selected. Update FIB and finish. */
paul718e3742002-12-13 20:15:29 +00001367 if (select && select == fib)
1368 {
Paul Jakma6d691122006-07-27 21:49:00 +00001369 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001370 rnode_debug (rn, "Updating existing route, select %p, fib %p",
1371 select, fib);
paul718e3742002-12-13 20:15:29 +00001372 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +00001373 {
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001374 zfpm_trigger_update (rn, "updating existing route");
1375
paul4d38fdb2005-04-28 17:35:14 +00001376 redistribute_delete (&rn->p, select);
1377 if (! RIB_SYSTEM_ROUTE (select))
1378 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001379
paul4d38fdb2005-04-28 17:35:14 +00001380 /* Set real nexthop. */
1381 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +00001382
paul4d38fdb2005-04-28 17:35:14 +00001383 if (! RIB_SYSTEM_ROUTE (select))
1384 rib_install_kernel (rn, select);
1385 redistribute_add (&rn->p, select);
1386 }
pauld753e9e2003-01-22 19:45:50 +00001387 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001388 {
1389 /* Housekeeping code to deal with
1390 race conditions in kernel with linux
1391 netlink reporting interface up before IPv4 or IPv6 protocol
1392 is ready to add routes.
1393 This makes sure the routes are IN the kernel.
1394 */
pauld753e9e2003-01-22 19:45:50 +00001395
Christian Frankefa713d92013-07-05 15:35:37 +00001396 for (ALL_NEXTHOPS_RO(select->nexthop, nexthop, tnexthop, recursing))
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001397 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
paul4d38fdb2005-04-28 17:35:14 +00001398 {
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001399 installed = 1;
1400 break;
paul4d38fdb2005-04-28 17:35:14 +00001401 }
1402 if (! installed)
1403 rib_install_kernel (rn, select);
1404 }
Paul Jakma6d691122006-07-27 21:49:00 +00001405 goto end;
paul718e3742002-12-13 20:15:29 +00001406 }
1407
Denis Ovsienkodc958242007-08-13 16:03:06 +00001408 /* At this point we either haven't found the best RIB entry or it is
1409 * different from what we currently intend to flag with SELECTED. In both
1410 * cases, if a RIB block is present in FIB, it should be withdrawn.
1411 */
paul718e3742002-12-13 20:15:29 +00001412 if (fib)
1413 {
Paul Jakma6d691122006-07-27 21:49:00 +00001414 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001415 rnode_debug (rn, "Removing existing route, fib %p", fib);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001416
1417 zfpm_trigger_update (rn, "removing existing route");
1418
paul718e3742002-12-13 20:15:29 +00001419 redistribute_delete (&rn->p, fib);
1420 if (! RIB_SYSTEM_ROUTE (fib))
1421 rib_uninstall_kernel (rn, fib);
1422 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1423
1424 /* Set real nexthop. */
1425 nexthop_active_update (rn, fib, 1);
1426 }
1427
Denis Ovsienkodc958242007-08-13 16:03:06 +00001428 /* Regardless of some RIB entry being SELECTED or not before, now we can
1429 * tell, that if a new winner exists, FIB is still not updated with this
1430 * data, but ready to be.
1431 */
paul718e3742002-12-13 20:15:29 +00001432 if (select)
1433 {
Paul Jakma6d691122006-07-27 21:49:00 +00001434 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001435 rnode_debug (rn, "Adding route, select %p", select);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001436
1437 zfpm_trigger_update (rn, "new route selected");
1438
paul718e3742002-12-13 20:15:29 +00001439 /* Set real nexthop. */
1440 nexthop_active_update (rn, select, 1);
1441
1442 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001443 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001444 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1445 redistribute_add (&rn->p, select);
1446 }
paul4d38fdb2005-04-28 17:35:14 +00001447
Paul Jakma6d691122006-07-27 21:49:00 +00001448 /* FIB route was removed, should be deleted */
1449 if (del)
1450 {
1451 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001452 rnode_debug (rn, "Deleting fib %p, rn %p", del, rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001453 rib_unlink (rn, del);
1454 }
paul4d38fdb2005-04-28 17:35:14 +00001455
Paul Jakma6d691122006-07-27 21:49:00 +00001456end:
1457 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lamparter94813742014-04-24 20:22:53 +02001458 rnode_debug (rn, "rn %p dequeued", rn);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001459
1460 /*
1461 * Check if the dest can be deleted now.
1462 */
1463 rib_gc_dest (rn);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001464}
1465
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001466/* Take a list of route_node structs and return 1, if there was a record
1467 * picked from it and processed by rib_process(). Don't process more,
1468 * than one RN record; operate only in the specified sub-queue.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001469 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001470static unsigned int
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001471process_subq (struct list * subq, u_char qindex)
1472{
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001473 struct listnode *lnode = listhead (subq);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001474 struct route_node *rnode;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001475
1476 if (!lnode)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001477 return 0;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001478
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001479 rnode = listgetdata (lnode);
1480 rib_process (rnode);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001481
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001482 if (rnode->info)
1483 UNSET_FLAG (rib_dest_from_rnode (rnode)->flags, RIB_ROUTE_QUEUED (qindex));
1484
Chris Caputo67b94672009-07-18 04:02:26 +00001485#if 0
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001486 else
1487 {
1488 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1489 __func__, rnode, rnode->lock);
1490 zlog_backtrace(LOG_DEBUG);
1491 }
Chris Caputo67b94672009-07-18 04:02:26 +00001492#endif
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001493 route_unlock_node (rnode);
1494 list_delete_node (subq, lnode);
1495 return 1;
1496}
1497
1498/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1499 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1500 * is pointed to the meta queue structure.
1501 */
1502static wq_item_status
1503meta_queue_process (struct work_queue *dummy, void *data)
1504{
1505 struct meta_queue * mq = data;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001506 unsigned i;
1507
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001508 for (i = 0; i < MQ_SIZE; i++)
1509 if (process_subq (mq->subq[i], i))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001510 {
1511 mq->size--;
1512 break;
1513 }
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001514 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1515}
1516
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001517/*
1518 * Map from rib types to queue type (priority) in meta queue
1519 */
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001520static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
1521 [ZEBRA_ROUTE_SYSTEM] = 4,
1522 [ZEBRA_ROUTE_KERNEL] = 0,
1523 [ZEBRA_ROUTE_CONNECT] = 0,
1524 [ZEBRA_ROUTE_STATIC] = 1,
1525 [ZEBRA_ROUTE_RIP] = 2,
1526 [ZEBRA_ROUTE_RIPNG] = 2,
1527 [ZEBRA_ROUTE_OSPF] = 2,
1528 [ZEBRA_ROUTE_OSPF6] = 2,
1529 [ZEBRA_ROUTE_ISIS] = 2,
1530 [ZEBRA_ROUTE_BGP] = 3,
1531 [ZEBRA_ROUTE_HSLS] = 4,
Paul Jakma57345092011-12-25 17:52:09 +01001532 [ZEBRA_ROUTE_BABEL] = 2,
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001533};
1534
1535/* Look into the RN and queue it into one or more priority queues,
1536 * increasing the size for each data push done.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001537 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001538static void
1539rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001540{
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001541 struct rib *rib;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001542
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001543 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001544 {
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001545 u_char qindex = meta_queue_map[rib->type];
1546
1547 /* Invariant: at this point we always have rn->info set. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001548 if (CHECK_FLAG (rib_dest_from_rnode (rn)->flags,
1549 RIB_ROUTE_QUEUED (qindex)))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001550 {
1551 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lamparter94813742014-04-24 20:22:53 +02001552 rnode_debug (rn, "rn %p is already queued in sub-queue %u",
1553 rn, qindex);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001554 continue;
1555 }
1556
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001557 SET_FLAG (rib_dest_from_rnode (rn)->flags, RIB_ROUTE_QUEUED (qindex));
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001558 listnode_add (mq->subq[qindex], rn);
1559 route_lock_node (rn);
1560 mq->size++;
1561
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001562 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lamparter94813742014-04-24 20:22:53 +02001563 rnode_debug (rn, "queued rn %p into sub-queue %u",
1564 rn, qindex);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001565 }
paul4d38fdb2005-04-28 17:35:14 +00001566}
1567
Paul Jakma6d691122006-07-27 21:49:00 +00001568/* Add route_node to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001569static void
Paul Jakma6d691122006-07-27 21:49:00 +00001570rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
paul4d38fdb2005-04-28 17:35:14 +00001571{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001572 assert (zebra && rn);
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001573
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001574 /* Pointless to queue a route_node with no RIB entries to add or remove */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001575 if (!rnode_to_ribs (rn))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001576 {
1577 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1578 __func__, rn, rn->lock);
1579 zlog_backtrace(LOG_DEBUG);
1580 return;
1581 }
1582
1583 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lamparter94813742014-04-24 20:22:53 +02001584 rnode_info (rn, "work queue added");
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001585
1586 assert (zebra);
1587
1588 if (zebra->ribq == NULL)
1589 {
1590 zlog_err ("%s: work_queue does not exist!", __func__);
1591 return;
Paul Jakma6d691122006-07-27 21:49:00 +00001592 }
paul4d38fdb2005-04-28 17:35:14 +00001593
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001594 /*
1595 * The RIB queue should normally be either empty or holding the only
1596 * work_queue_item element. In the latter case this element would
1597 * hold a pointer to the meta queue structure, which must be used to
1598 * actually queue the route nodes to process. So create the MQ
1599 * holder, if necessary, then push the work into it in any case.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001600 * This semantics was introduced after 0.99.9 release.
1601 */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001602 if (!zebra->ribq->items->count)
1603 work_queue_add (zebra->ribq, zebra->mq);
1604
1605 rib_meta_queue_add (zebra->mq, rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001606
1607 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lamparter94813742014-04-24 20:22:53 +02001608 rnode_debug (rn, "rn %p queued", rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001609
1610 return;
paul4d38fdb2005-04-28 17:35:14 +00001611}
1612
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001613/* Create new meta queue.
1614 A destructor function doesn't seem to be necessary here.
1615 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001616static struct meta_queue *
1617meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001618{
1619 struct meta_queue *new;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001620 unsigned i;
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001621
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001622 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1623 assert(new);
1624
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001625 for (i = 0; i < MQ_SIZE; i++)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001626 {
1627 new->subq[i] = list_new ();
1628 assert(new->subq[i]);
1629 }
1630
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001631 return new;
1632}
1633
paul4d38fdb2005-04-28 17:35:14 +00001634/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001635static void
paul4d38fdb2005-04-28 17:35:14 +00001636rib_queue_init (struct zebra_t *zebra)
1637{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001638 assert (zebra);
1639
paul4d38fdb2005-04-28 17:35:14 +00001640 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001641 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001642 {
Paul Jakma6d691122006-07-27 21:49:00 +00001643 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001644 return;
1645 }
1646
1647 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001648 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001649 zebra->ribq->spec.errorfunc = NULL;
paul4d38fdb2005-04-28 17:35:14 +00001650 /* XXX: TODO: These should be runtime configurable via vty */
1651 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001652 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001653
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001654 if (!(zebra->mq = meta_queue_new ()))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001655 {
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001656 zlog_err ("%s: could not initialise meta queue!", __func__);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001657 return;
1658 }
1659 return;
paul718e3742002-12-13 20:15:29 +00001660}
1661
Paul Jakma6d691122006-07-27 21:49:00 +00001662/* RIB updates are processed via a queue of pointers to route_nodes.
1663 *
1664 * The queue length is bounded by the maximal size of the routing table,
1665 * as a route_node will not be requeued, if already queued.
1666 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001667 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1668 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1669 * and then submit route_node to queue for best-path selection later.
1670 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001671 *
1672 * Deleted RIBs are reaped during best-path selection.
1673 *
1674 * rib_addnode
1675 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001676 * |-------->| | best RIB, if required
1677 * | |
1678 * static_install->|->rib_addqueue...... -> rib_process
1679 * | |
1680 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001681 * |-> set RIB_ENTRY_REMOVE |
1682 * rib_delnode (RIB freed)
1683 *
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001684 * The 'info' pointer of a route_node points to a rib_dest_t
1685 * ('dest'). Queueing state for a route_node is kept on the dest. The
1686 * dest is created on-demand by rib_link() and is kept around at least
1687 * as long as there are ribs hanging off it (@see rib_gc_dest()).
Paul Jakma6d691122006-07-27 21:49:00 +00001688 *
1689 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1690 *
1691 * - route_nodes: refcounted by:
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001692 * - dest attached to route_node:
1693 * - managed by: rib_link/rib_gc_dest
Paul Jakma6d691122006-07-27 21:49:00 +00001694 * - route_node processing queue
1695 * - managed by: rib_addqueue, rib_process.
1696 *
1697 */
1698
paul718e3742002-12-13 20:15:29 +00001699/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001700static void
Paul Jakma6d691122006-07-27 21:49:00 +00001701rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001702{
1703 struct rib *head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001704 rib_dest_t *dest;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001705
paul4d38fdb2005-04-28 17:35:14 +00001706 assert (rib && rn);
1707
Paul Jakma6d691122006-07-27 21:49:00 +00001708 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001709 rnode_debug (rn, "rn %p, rib %p", rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001710
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001711 dest = rib_dest_from_rnode (rn);
1712 if (!dest)
Paul Jakma6d691122006-07-27 21:49:00 +00001713 {
1714 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001715 rnode_debug (rn, "adding dest to table");
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001716
1717 dest = XCALLOC (MTYPE_RIB_DEST, sizeof (rib_dest_t));
1718 route_lock_node (rn); /* rn route table reference */
1719 rn->info = dest;
1720 dest->rnode = rn;
1721 }
1722
1723 head = dest->routes;
1724 if (head)
1725 {
Paul Jakma6d691122006-07-27 21:49:00 +00001726 head->prev = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001727 }
paul718e3742002-12-13 20:15:29 +00001728 rib->next = head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001729 dest->routes = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001730 rib_queue_add (&zebrad, rn);
1731}
1732
1733static void
1734rib_addnode (struct route_node *rn, struct rib *rib)
1735{
1736 /* RIB node has been un-removed before route-node is processed.
1737 * route_node must hence already be on the queue for processing..
1738 */
1739 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1740 {
1741 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001742 rnode_debug (rn, "rn %p, un-removed rib %p", rn, rib);
1743
Paul Jakma6d691122006-07-27 21:49:00 +00001744 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1745 return;
1746 }
1747 rib_link (rn, rib);
1748}
1749
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001750/*
1751 * rib_unlink
1752 *
1753 * Detach a rib structure from a route_node.
1754 *
1755 * Note that a call to rib_unlink() should be followed by a call to
1756 * rib_gc_dest() at some point. This allows a rib_dest_t that is no
1757 * longer required to be deleted.
1758 */
Paul Jakma6d691122006-07-27 21:49:00 +00001759static void
1760rib_unlink (struct route_node *rn, struct rib *rib)
1761{
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001762 rib_dest_t *dest;
Paul Jakma6d691122006-07-27 21:49:00 +00001763
1764 assert (rn && rib);
1765
1766 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001767 rnode_debug (rn, "rn %p, rib %p", rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001768
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001769 dest = rib_dest_from_rnode (rn);
1770
Paul Jakma6d691122006-07-27 21:49:00 +00001771 if (rib->next)
1772 rib->next->prev = rib->prev;
1773
1774 if (rib->prev)
1775 rib->prev->next = rib->next;
1776 else
1777 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001778 dest->routes = rib->next;
Paul Jakma6d691122006-07-27 21:49:00 +00001779 }
1780
1781 /* free RIB and nexthops */
Christian Frankefa713d92013-07-05 15:35:37 +00001782 nexthops_free(rib->nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00001783 XFREE (MTYPE_RIB, rib);
1784
paul718e3742002-12-13 20:15:29 +00001785}
1786
paula1ac18c2005-06-28 17:17:12 +00001787static void
paul718e3742002-12-13 20:15:29 +00001788rib_delnode (struct route_node *rn, struct rib *rib)
1789{
Paul Jakma6d691122006-07-27 21:49:00 +00001790 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001791 rnode_debug (rn, "rn %p, rib %p, removing", rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001792 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1793 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001794}
1795
1796int
1797rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001798 struct in_addr *gate, struct in_addr *src,
1799 unsigned int ifindex, u_int32_t vrf_id,
G.Balajicddf3912011-11-26 21:59:32 +04001800 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001801{
1802 struct rib *rib;
1803 struct rib *same = NULL;
1804 struct route_table *table;
1805 struct route_node *rn;
1806 struct nexthop *nexthop;
1807
1808 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04001809 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00001810 if (! table)
1811 return 0;
1812
1813 /* Make it sure prefixlen is applied to the prefix. */
1814 apply_mask_ipv4 (p);
1815
1816 /* Set default distance by route type. */
1817 if (distance == 0)
1818 {
Balaji.G837d16c2012-09-26 14:09:10 +05301819 if ((unsigned)type >= array_size(route_info))
David Lamparter7052f222009-08-27 00:28:28 +02001820 distance = 150;
1821 else
1822 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00001823
1824 /* iBGP distance is 200. */
1825 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1826 distance = 200;
1827 }
1828
1829 /* Lookup route node.*/
1830 rn = route_node_get (table, (struct prefix *) p);
1831
1832 /* If same type of route are installed, treat it as a implicit
1833 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001834 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00001835 {
Paul Jakma6d691122006-07-27 21:49:00 +00001836 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1837 continue;
1838
hassoebf1ead2005-09-21 14:58:20 +00001839 if (rib->type != type)
1840 continue;
1841 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001842 {
1843 same = rib;
1844 break;
1845 }
hassoebf1ead2005-09-21 14:58:20 +00001846 /* Duplicate connected route comes in. */
1847 else if ((nexthop = rib->nexthop) &&
1848 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001849 nexthop->ifindex == ifindex &&
1850 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001851 {
1852 rib->refcnt++;
1853 return 0 ;
1854 }
paul718e3742002-12-13 20:15:29 +00001855 }
1856
1857 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001858 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001859 rib->type = type;
1860 rib->distance = distance;
1861 rib->flags = flags;
1862 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001863 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001864 rib->nexthop_num = 0;
1865 rib->uptime = time (NULL);
1866
1867 /* Nexthop settings. */
1868 if (gate)
1869 {
1870 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001871 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001872 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001873 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001874 }
1875 else
1876 nexthop_ifindex_add (rib, ifindex);
1877
1878 /* If this route is kernel route, set FIB flag to the route. */
1879 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1880 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1881 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1882
1883 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001884 if (IS_ZEBRA_DEBUG_RIB)
1885 zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
paul718e3742002-12-13 20:15:29 +00001886 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001887
paul718e3742002-12-13 20:15:29 +00001888 /* Free implicit route.*/
1889 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001890 {
1891 if (IS_ZEBRA_DEBUG_RIB)
1892 zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001893 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001894 }
paul4d38fdb2005-04-28 17:35:14 +00001895
1896 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001897 return 0;
1898}
1899
Denis Ovsienkodc958242007-08-13 16:03:06 +00001900/* This function dumps the contents of a given RIB entry into
1901 * standard debug log. Calling function name and IP prefix in
1902 * question are passed as 1st and 2nd arguments.
1903 */
1904
David Lamparterf7bf4152013-10-22 17:10:21 +00001905void _rib_dump (const char * func,
1906 union prefix46constptr pp, const struct rib * rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001907{
David Lamparterf7bf4152013-10-22 17:10:21 +00001908 const struct prefix *p = pp.p;
Vincent Bernatfed643f2012-10-23 16:00:42 +00001909 char straddr[INET6_ADDRSTRLEN];
Christian Frankefa713d92013-07-05 15:35:37 +00001910 struct nexthop *nexthop, *tnexthop;
1911 int recursing;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001912
Vincent Bernatfed643f2012-10-23 16:00:42 +00001913 inet_ntop (p->family, &p->u.prefix, straddr, INET6_ADDRSTRLEN);
Christian Frankefa713d92013-07-05 15:35:37 +00001914 zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr, p->prefixlen);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001915 zlog_debug
1916 (
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001917 "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
Denis Ovsienkodc958242007-08-13 16:03:06 +00001918 func,
1919 rib->refcnt,
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001920 (unsigned long) rib->uptime,
Denis Ovsienkodc958242007-08-13 16:03:06 +00001921 rib->type,
1922 rib->table
1923 );
1924 zlog_debug
1925 (
1926 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1927 func,
1928 rib->metric,
1929 rib->distance,
1930 rib->flags,
1931 rib->status
1932 );
1933 zlog_debug
1934 (
1935 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1936 func,
1937 rib->nexthop_num,
1938 rib->nexthop_active_num,
1939 rib->nexthop_fib_num
1940 );
Vincent Bernatfed643f2012-10-23 16:00:42 +00001941
Christian Frankefa713d92013-07-05 15:35:37 +00001942 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1943 {
Vincent Bernatfed643f2012-10-23 16:00:42 +00001944 inet_ntop (p->family, &nexthop->gate, straddr, INET6_ADDRSTRLEN);
Christian Frankefa713d92013-07-05 15:35:37 +00001945 zlog_debug
1946 (
1947 "%s: %s %s with flags %s%s%s",
1948 func,
1949 (recursing ? " NH" : "NH"),
1950 straddr,
1951 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1952 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1953 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1954 );
1955 }
Denis Ovsienkodc958242007-08-13 16:03:06 +00001956 zlog_debug ("%s: dump complete", func);
1957}
1958
1959/* This is an exported helper to rtm_read() to dump the strange
1960 * RIB entry found by rib_lookup_ipv4_route()
1961 */
1962
1963void rib_lookup_and_dump (struct prefix_ipv4 * p)
1964{
1965 struct route_table *table;
1966 struct route_node *rn;
1967 struct rib *rib;
1968 char prefix_buf[INET_ADDRSTRLEN];
1969
1970 /* Lookup table. */
1971 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1972 if (! table)
1973 {
1974 zlog_err ("%s: vrf_table() returned NULL", __func__);
1975 return;
1976 }
1977
1978 inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
1979 /* Scan the RIB table for exactly matching RIB entry. */
1980 rn = route_node_lookup (table, (struct prefix *) p);
1981
1982 /* No route for this prefix. */
1983 if (! rn)
1984 {
1985 zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
1986 return;
1987 }
1988
1989 /* Unlock node. */
1990 route_unlock_node (rn);
1991
1992 /* let's go */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001993 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001994 {
1995 zlog_debug
1996 (
1997 "%s: rn %p, rib %p: %s, %s",
1998 __func__,
1999 rn,
2000 rib,
2001 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
2002 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
2003 );
David Lamparterf7bf4152013-10-22 17:10:21 +00002004 rib_dump (p, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002005 }
2006}
2007
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002008/* Check if requested address assignment will fail due to another
2009 * route being installed by zebra in FIB already. Take necessary
2010 * actions, if needed: remove such a route from FIB and deSELECT
2011 * corresponding RIB entry. Then put affected RN into RIBQ head.
2012 */
2013void rib_lookup_and_pushup (struct prefix_ipv4 * p)
2014{
2015 struct route_table *table;
2016 struct route_node *rn;
2017 struct rib *rib;
2018 unsigned changed = 0;
2019
2020 if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
2021 {
2022 zlog_err ("%s: vrf_table() returned NULL", __func__);
2023 return;
2024 }
2025
2026 /* No matches would be the simplest case. */
2027 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
2028 return;
2029
2030 /* Unlock node. */
2031 route_unlock_node (rn);
2032
2033 /* Check all RIB entries. In case any changes have to be done, requeue
2034 * the RN into RIBQ head. If the routing message about the new connected
2035 * route (generated by the IP address we are going to assign very soon)
2036 * comes before the RIBQ is processed, the new RIB entry will join
2037 * RIBQ record already on head. This is necessary for proper revalidation
2038 * of the rest of the RIB.
2039 */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002040 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002041 {
2042 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
2043 ! RIB_SYSTEM_ROUTE (rib))
2044 {
2045 changed = 1;
2046 if (IS_ZEBRA_DEBUG_RIB)
2047 {
2048 char buf[INET_ADDRSTRLEN];
2049 inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
2050 zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
David Lamparterf7bf4152013-10-22 17:10:21 +00002051 rib_dump (&rn->p, rib);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002052 }
2053 rib_uninstall (rn, rib);
2054 }
2055 }
2056 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002057 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002058}
2059
paul718e3742002-12-13 20:15:29 +00002060int
G.Balajicddf3912011-11-26 21:59:32 +04002061rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002062{
2063 struct route_table *table;
2064 struct route_node *rn;
2065 struct rib *same;
2066 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00002067
paul718e3742002-12-13 20:15:29 +00002068 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04002069 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00002070 if (! table)
2071 return 0;
G.Balajicddf3912011-11-26 21:59:32 +04002072
paul718e3742002-12-13 20:15:29 +00002073 /* Make it sure prefixlen is applied to the prefix. */
2074 apply_mask_ipv4 (p);
2075
2076 /* Set default distance by route type. */
2077 if (rib->distance == 0)
2078 {
2079 rib->distance = route_info[rib->type].distance;
2080
2081 /* iBGP distance is 200. */
2082 if (rib->type == ZEBRA_ROUTE_BGP
2083 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
2084 rib->distance = 200;
2085 }
2086
2087 /* Lookup route node.*/
2088 rn = route_node_get (table, (struct prefix *) p);
2089
2090 /* If same type of route are installed, treat it as a implicit
2091 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002092 RNODE_FOREACH_RIB (rn, same)
paul718e3742002-12-13 20:15:29 +00002093 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00002094 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00002095 continue;
2096
paul718e3742002-12-13 20:15:29 +00002097 if (same->type == rib->type && same->table == rib->table
2098 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00002099 break;
paul718e3742002-12-13 20:15:29 +00002100 }
paul4d38fdb2005-04-28 17:35:14 +00002101
paul718e3742002-12-13 20:15:29 +00002102 /* If this route is kernel route, set FIB flag to the route. */
2103 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
2104 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2105 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2106
2107 /* Link new rib to node.*/
2108 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002109 if (IS_ZEBRA_DEBUG_RIB)
2110 {
2111 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
2112 __func__, rn, rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00002113 rib_dump (p, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002114 }
paul718e3742002-12-13 20:15:29 +00002115
paul718e3742002-12-13 20:15:29 +00002116 /* Free implicit route.*/
2117 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00002118 {
2119 if (IS_ZEBRA_DEBUG_RIB)
2120 {
2121 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
2122 __func__, rn, same);
David Lamparterf7bf4152013-10-22 17:10:21 +00002123 rib_dump (p, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002124 }
paul4d38fdb2005-04-28 17:35:14 +00002125 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002126 }
paul4d38fdb2005-04-28 17:35:14 +00002127
2128 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002129 return 0;
2130}
2131
hassoebf1ead2005-09-21 14:58:20 +00002132/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002133int
2134rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
G.Balajicddf3912011-11-26 21:59:32 +04002135 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002136{
2137 struct route_table *table;
2138 struct route_node *rn;
2139 struct rib *rib;
2140 struct rib *fib = NULL;
2141 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002142 struct nexthop *nexthop, *tnexthop;
2143 int recursing;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002144 char buf1[INET_ADDRSTRLEN];
2145 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002146
2147 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04002148 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00002149 if (! table)
2150 return 0;
2151
2152 /* Apply mask. */
2153 apply_mask_ipv4 (p);
2154
Christian Frankeb52aef12013-11-27 17:06:15 +00002155 if (IS_ZEBRA_DEBUG_KERNEL)
2156 {
2157 if (gate)
2158 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
2159 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
2160 p->prefixlen,
2161 inet_ntoa (*gate),
2162 ifindex);
2163 else
2164 zlog_debug ("rib_delete_ipv4(): route delete %s/%d ifindex %d",
2165 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
2166 p->prefixlen,
2167 ifindex);
2168 }
paul5ec90d22003-06-19 01:41:37 +00002169
paul718e3742002-12-13 20:15:29 +00002170 /* Lookup route node. */
2171 rn = route_node_lookup (table, (struct prefix *) p);
2172 if (! rn)
2173 {
2174 if (IS_ZEBRA_DEBUG_KERNEL)
2175 {
2176 if (gate)
ajsb6178002004-12-07 21:12:56 +00002177 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002178 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002179 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002180 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002181 ifindex);
2182 else
ajsb6178002004-12-07 21:12:56 +00002183 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002184 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002185 p->prefixlen,
2186 ifindex);
2187 }
2188 return ZEBRA_ERR_RTNOEXIST;
2189 }
2190
2191 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002192 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002193 {
Paul Jakma6d691122006-07-27 21:49:00 +00002194 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2195 continue;
2196
paul718e3742002-12-13 20:15:29 +00002197 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2198 fib = rib;
2199
hassoebf1ead2005-09-21 14:58:20 +00002200 if (rib->type != type)
2201 continue;
2202 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002203 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002204 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002205 if (nexthop->ifindex != ifindex)
2206 continue;
hassoebf1ead2005-09-21 14:58:20 +00002207 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002208 {
hassoebf1ead2005-09-21 14:58:20 +00002209 rib->refcnt--;
2210 route_unlock_node (rn);
2211 route_unlock_node (rn);
2212 return 0;
paul718e3742002-12-13 20:15:29 +00002213 }
hassoebf1ead2005-09-21 14:58:20 +00002214 same = rib;
2215 break;
paul718e3742002-12-13 20:15:29 +00002216 }
hassoebf1ead2005-09-21 14:58:20 +00002217 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002218 else
paul5ec90d22003-06-19 01:41:37 +00002219 {
Christian Frankefa713d92013-07-05 15:35:37 +00002220 if (gate == NULL)
2221 {
2222 same = rib;
2223 break;
2224 }
2225 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2226 if (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate))
2227 {
2228 same = rib;
2229 break;
2230 }
2231 if (same)
2232 break;
2233 }
paul718e3742002-12-13 20:15:29 +00002234 }
paul718e3742002-12-13 20:15:29 +00002235 /* If same type of route can't be found and this message is from
2236 kernel. */
2237 if (! same)
2238 {
2239 if (fib && type == ZEBRA_ROUTE_KERNEL)
2240 {
2241 /* Unset flags. */
2242 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2243 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2244
2245 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2246 }
2247 else
2248 {
2249 if (IS_ZEBRA_DEBUG_KERNEL)
2250 {
2251 if (gate)
ajsb6178002004-12-07 21:12:56 +00002252 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002253 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002254 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002255 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002256 ifindex,
2257 type);
2258 else
ajsb6178002004-12-07 21:12:56 +00002259 zlog_debug ("route %s/%d 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,
2262 ifindex,
2263 type);
2264 }
2265 route_unlock_node (rn);
2266 return ZEBRA_ERR_RTNOEXIST;
2267 }
2268 }
paul4d38fdb2005-04-28 17:35:14 +00002269
paul718e3742002-12-13 20:15:29 +00002270 if (same)
2271 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002272
paul718e3742002-12-13 20:15:29 +00002273 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002274 return 0;
2275}
David Lamparter6b0655a2014-06-04 06:53:35 +02002276
paul718e3742002-12-13 20:15:29 +00002277/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002278static void
Everton Marques33d86db2014-07-14 11:19:00 -03002279static_install_ipv4 (safi_t safi, struct prefix *p, struct static_ipv4 *si)
paul718e3742002-12-13 20:15:29 +00002280{
2281 struct rib *rib;
2282 struct route_node *rn;
2283 struct route_table *table;
2284
2285 /* Lookup table. */
Everton Marques33d86db2014-07-14 11:19:00 -03002286 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00002287 if (! table)
2288 return;
2289
2290 /* Lookup existing route */
2291 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002292 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002293 {
2294 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2295 continue;
2296
2297 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2298 break;
2299 }
paul718e3742002-12-13 20:15:29 +00002300
2301 if (rib)
2302 {
2303 /* Same distance static route is there. Update it with new
2304 nexthop. */
paul718e3742002-12-13 20:15:29 +00002305 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002306 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002307 {
2308 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002309 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002310 break;
2311 case STATIC_IPV4_IFNAME:
2312 nexthop_ifname_add (rib, si->gate.ifname);
2313 break;
2314 case STATIC_IPV4_BLACKHOLE:
2315 nexthop_blackhole_add (rib);
2316 break;
paul4d38fdb2005-04-28 17:35:14 +00002317 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002318 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002319 }
2320 else
2321 {
2322 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002323 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2324
paul718e3742002-12-13 20:15:29 +00002325 rib->type = ZEBRA_ROUTE_STATIC;
2326 rib->distance = si->distance;
2327 rib->metric = 0;
Nolan Leakeb0145dd2012-09-13 17:17:31 +00002328 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002329 rib->nexthop_num = 0;
2330
2331 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002332 {
2333 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002334 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002335 break;
2336 case STATIC_IPV4_IFNAME:
2337 nexthop_ifname_add (rib, si->gate.ifname);
2338 break;
2339 case STATIC_IPV4_BLACKHOLE:
2340 nexthop_blackhole_add (rib);
2341 break;
2342 }
paul718e3742002-12-13 20:15:29 +00002343
hasso81dfcaa2003-05-25 19:21:25 +00002344 /* Save the flags of this static routes (reject, blackhole) */
2345 rib->flags = si->flags;
2346
paul718e3742002-12-13 20:15:29 +00002347 /* Link this rib to the tree. */
2348 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002349 }
2350}
2351
paula1ac18c2005-06-28 17:17:12 +00002352static int
paul718e3742002-12-13 20:15:29 +00002353static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2354{
2355 if (nexthop->type == NEXTHOP_TYPE_IPV4
2356 && si->type == STATIC_IPV4_GATEWAY
2357 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2358 return 1;
2359 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2360 && si->type == STATIC_IPV4_IFNAME
2361 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2362 return 1;
paul595db7f2003-05-25 21:35:06 +00002363 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2364 && si->type == STATIC_IPV4_BLACKHOLE)
2365 return 1;
paule8e19462006-01-19 20:16:55 +00002366 return 0;
paul718e3742002-12-13 20:15:29 +00002367}
2368
2369/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002370static void
Everton Marques33d86db2014-07-14 11:19:00 -03002371static_uninstall_ipv4 (safi_t safi, struct prefix *p, struct static_ipv4 *si)
paul718e3742002-12-13 20:15:29 +00002372{
2373 struct route_node *rn;
2374 struct rib *rib;
2375 struct nexthop *nexthop;
2376 struct route_table *table;
2377
2378 /* Lookup table. */
Everton Marques33d86db2014-07-14 11:19:00 -03002379 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00002380 if (! table)
2381 return;
paul4d38fdb2005-04-28 17:35:14 +00002382
paul718e3742002-12-13 20:15:29 +00002383 /* Lookup existing route with type and distance. */
2384 rn = route_node_lookup (table, p);
2385 if (! rn)
2386 return;
2387
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002388 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002389 {
2390 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2391 continue;
2392
2393 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2394 break;
2395 }
paul718e3742002-12-13 20:15:29 +00002396
2397 if (! rib)
2398 {
2399 route_unlock_node (rn);
2400 return;
2401 }
2402
2403 /* Lookup nexthop. */
2404 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2405 if (static_ipv4_nexthop_same (nexthop, si))
2406 break;
2407
2408 /* Can't find nexthop. */
2409 if (! nexthop)
2410 {
2411 route_unlock_node (rn);
2412 return;
2413 }
2414
2415 /* Check nexthop. */
2416 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002417 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002418 else
2419 {
paul6baeb982003-10-28 03:47:15 +00002420 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2421 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002422 nexthop_delete (rib, nexthop);
2423 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002424 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002425 }
paul718e3742002-12-13 20:15:29 +00002426 /* Unlock node. */
2427 route_unlock_node (rn);
2428}
2429
paul718e3742002-12-13 20:15:29 +00002430int
Everton Marques33d86db2014-07-14 11:19:00 -03002431static_add_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate,
2432 const char *ifname, u_char flags, u_char distance,
2433 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002434{
2435 u_char type = 0;
2436 struct route_node *rn;
2437 struct static_ipv4 *si;
2438 struct static_ipv4 *pp;
2439 struct static_ipv4 *cp;
2440 struct static_ipv4 *update = NULL;
2441 struct route_table *stable;
2442
2443 /* Lookup table. */
Everton Marques33d86db2014-07-14 11:19:00 -03002444 stable = vrf_static_table (AFI_IP, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002445 if (! stable)
2446 return -1;
2447
2448 /* Lookup static route prefix. */
2449 rn = route_node_get (stable, p);
2450
2451 /* Make flags. */
2452 if (gate)
2453 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002454 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002455 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002456 else
2457 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002458
2459 /* Do nothing if there is a same static route. */
2460 for (si = rn->info; si; si = si->next)
2461 {
2462 if (type == si->type
2463 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2464 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2465 {
2466 if (distance == si->distance)
2467 {
2468 route_unlock_node (rn);
2469 return 0;
2470 }
2471 else
2472 update = si;
2473 }
2474 }
2475
Paul Jakma3c0755d2006-12-08 00:53:14 +00002476 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002477 if (update)
Everton Marques33d86db2014-07-14 11:19:00 -03002478 static_delete_ipv4_safi (safi, p, gate, ifname, update->distance, vrf_id);
paul718e3742002-12-13 20:15:29 +00002479
2480 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002481 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
paul718e3742002-12-13 20:15:29 +00002482
2483 si->type = type;
2484 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002485 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002486
2487 if (gate)
2488 si->gate.ipv4 = *gate;
2489 if (ifname)
2490 si->gate.ifname = XSTRDUP (0, ifname);
2491
2492 /* Add new static route information to the tree with sort by
2493 distance value and gateway address. */
2494 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2495 {
2496 if (si->distance < cp->distance)
2497 break;
2498 if (si->distance > cp->distance)
2499 continue;
2500 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2501 {
2502 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2503 break;
2504 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2505 continue;
2506 }
2507 }
2508
2509 /* Make linked list. */
2510 if (pp)
2511 pp->next = si;
2512 else
2513 rn->info = si;
2514 if (cp)
2515 cp->prev = si;
2516 si->prev = pp;
2517 si->next = cp;
2518
2519 /* Install into rib. */
Everton Marques33d86db2014-07-14 11:19:00 -03002520 static_install_ipv4 (safi, p, si);
paul718e3742002-12-13 20:15:29 +00002521
2522 return 1;
2523}
2524
paul718e3742002-12-13 20:15:29 +00002525int
Everton Marques33d86db2014-07-14 11:19:00 -03002526static_delete_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate,
2527 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002528{
2529 u_char type = 0;
2530 struct route_node *rn;
2531 struct static_ipv4 *si;
2532 struct route_table *stable;
2533
2534 /* Lookup table. */
Everton Marques33d86db2014-07-14 11:19:00 -03002535 stable = vrf_static_table (AFI_IP, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002536 if (! stable)
2537 return -1;
2538
2539 /* Lookup static route prefix. */
2540 rn = route_node_lookup (stable, p);
2541 if (! rn)
2542 return 0;
2543
2544 /* Make flags. */
2545 if (gate)
2546 type = STATIC_IPV4_GATEWAY;
2547 else if (ifname)
2548 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002549 else
2550 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002551
2552 /* Find same static route is the tree */
2553 for (si = rn->info; si; si = si->next)
2554 if (type == si->type
2555 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2556 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2557 break;
2558
2559 /* Can't find static route. */
2560 if (! si)
2561 {
2562 route_unlock_node (rn);
2563 return 0;
2564 }
2565
2566 /* Install into rib. */
Everton Marques33d86db2014-07-14 11:19:00 -03002567 static_uninstall_ipv4 (safi, p, si);
paul718e3742002-12-13 20:15:29 +00002568
2569 /* Unlink static route from linked list. */
2570 if (si->prev)
2571 si->prev->next = si->next;
2572 else
2573 rn->info = si->next;
2574 if (si->next)
2575 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002576 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002577
2578 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002579 if (ifname)
2580 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002581 XFREE (MTYPE_STATIC_IPV4, si);
2582
paul143a3852003-09-29 20:06:13 +00002583 route_unlock_node (rn);
2584
paul718e3742002-12-13 20:15:29 +00002585 return 1;
2586}
2587
paul718e3742002-12-13 20:15:29 +00002588#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00002589static int
paul718e3742002-12-13 20:15:29 +00002590rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2591 struct in6_addr *gate, unsigned int ifindex, int table)
2592{
hasso726f9b22003-05-25 21:04:54 +00002593 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2594#if defined (MUSICA) || defined (LINUX)
2595 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2596 if (p->prefixlen == 96)
2597 return 0;
2598#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00002599 return 1;
hasso726f9b22003-05-25 21:04:54 +00002600 }
paul718e3742002-12-13 20:15:29 +00002601 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
2602 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
2603 {
2604 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
2605 return 1;
2606 }
2607 return 0;
2608}
2609
2610int
2611rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00002612 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
G.Balajif768f362011-11-26 22:10:39 +04002613 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002614{
2615 struct rib *rib;
2616 struct rib *same = NULL;
2617 struct route_table *table;
2618 struct route_node *rn;
2619 struct nexthop *nexthop;
2620
paul718e3742002-12-13 20:15:29 +00002621 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002622 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002623 if (! table)
2624 return 0;
2625
2626 /* Make sure mask is applied. */
2627 apply_mask_ipv6 (p);
2628
2629 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002630 if (!distance)
2631 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002632
2633 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2634 distance = 200;
2635
2636 /* Filter bogus route. */
2637 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
2638 return 0;
2639
2640 /* Lookup route node.*/
2641 rn = route_node_get (table, (struct prefix *) p);
2642
2643 /* If same type of route are installed, treat it as a implicit
2644 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002645 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002646 {
Paul Jakma6d691122006-07-27 21:49:00 +00002647 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2648 continue;
2649
hassoebf1ead2005-09-21 14:58:20 +00002650 if (rib->type != type)
2651 continue;
2652 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002653 {
2654 same = rib;
paul718e3742002-12-13 20:15:29 +00002655 break;
2656 }
hassoebf1ead2005-09-21 14:58:20 +00002657 else if ((nexthop = rib->nexthop) &&
2658 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2659 nexthop->ifindex == ifindex)
2660 {
2661 rib->refcnt++;
2662 return 0;
2663 }
paul718e3742002-12-13 20:15:29 +00002664 }
2665
2666 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002667 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2668
paul718e3742002-12-13 20:15:29 +00002669 rib->type = type;
2670 rib->distance = distance;
2671 rib->flags = flags;
2672 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00002673 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00002674 rib->nexthop_num = 0;
2675 rib->uptime = time (NULL);
2676
2677 /* Nexthop settings. */
2678 if (gate)
2679 {
2680 if (ifindex)
2681 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2682 else
2683 nexthop_ipv6_add (rib, gate);
2684 }
2685 else
2686 nexthop_ifindex_add (rib, ifindex);
2687
2688 /* If this route is kernel route, set FIB flag to the route. */
2689 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2690 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2691 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2692
2693 /* Link new rib to node.*/
2694 rib_addnode (rn, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002695 if (IS_ZEBRA_DEBUG_RIB)
2696 {
2697 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
2698 __func__, rn, rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00002699 rib_dump (p, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002700 }
paul718e3742002-12-13 20:15:29 +00002701
paul718e3742002-12-13 20:15:29 +00002702 /* Free implicit route.*/
2703 if (same)
Vincent Bernatfed643f2012-10-23 16:00:42 +00002704 {
2705 if (IS_ZEBRA_DEBUG_RIB)
2706 {
2707 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
2708 __func__, rn, same);
David Lamparterf7bf4152013-10-22 17:10:21 +00002709 rib_dump (p, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002710 }
paul4d38fdb2005-04-28 17:35:14 +00002711 rib_delnode (rn, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002712 }
paul4d38fdb2005-04-28 17:35:14 +00002713
2714 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002715 return 0;
2716}
2717
hassoebf1ead2005-09-21 14:58:20 +00002718/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002719int
2720rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
G.Balajif768f362011-11-26 22:10:39 +04002721 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002722{
2723 struct route_table *table;
2724 struct route_node *rn;
2725 struct rib *rib;
2726 struct rib *fib = NULL;
2727 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002728 struct nexthop *nexthop, *tnexthop;
2729 int recursing;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002730 char buf1[INET6_ADDRSTRLEN];
2731 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002732
2733 /* Apply mask. */
2734 apply_mask_ipv6 (p);
2735
2736 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002737 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002738 if (! table)
2739 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002740
paul718e3742002-12-13 20:15:29 +00002741 /* Lookup route node. */
2742 rn = route_node_lookup (table, (struct prefix *) p);
2743 if (! rn)
2744 {
2745 if (IS_ZEBRA_DEBUG_KERNEL)
2746 {
2747 if (gate)
ajsb6178002004-12-07 21:12:56 +00002748 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002749 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002750 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002751 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002752 ifindex);
2753 else
ajsb6178002004-12-07 21:12:56 +00002754 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002755 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002756 p->prefixlen,
2757 ifindex);
2758 }
2759 return ZEBRA_ERR_RTNOEXIST;
2760 }
2761
2762 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002763 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002764 {
Paul Jakma6d691122006-07-27 21:49:00 +00002765 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2766 continue;
2767
paul718e3742002-12-13 20:15:29 +00002768 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2769 fib = rib;
2770
hassoebf1ead2005-09-21 14:58:20 +00002771 if (rib->type != type)
2772 continue;
2773 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002774 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002775 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002776 if (nexthop->ifindex != ifindex)
2777 continue;
hassoebf1ead2005-09-21 14:58:20 +00002778 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002779 {
hassoebf1ead2005-09-21 14:58:20 +00002780 rib->refcnt--;
2781 route_unlock_node (rn);
2782 route_unlock_node (rn);
2783 return 0;
paul718e3742002-12-13 20:15:29 +00002784 }
hassoebf1ead2005-09-21 14:58:20 +00002785 same = rib;
2786 break;
paul718e3742002-12-13 20:15:29 +00002787 }
hassoebf1ead2005-09-21 14:58:20 +00002788 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002789 else
2790 {
2791 if (gate == NULL)
2792 {
2793 same = rib;
2794 break;
2795 }
2796 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2797 if (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate))
2798 {
2799 same = rib;
2800 break;
2801 }
2802 if (same)
2803 break;
2804 }
paul718e3742002-12-13 20:15:29 +00002805 }
2806
2807 /* If same type of route can't be found and this message is from
2808 kernel. */
2809 if (! same)
2810 {
2811 if (fib && type == ZEBRA_ROUTE_KERNEL)
2812 {
2813 /* Unset flags. */
2814 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2815 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2816
2817 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2818 }
2819 else
2820 {
2821 if (IS_ZEBRA_DEBUG_KERNEL)
2822 {
2823 if (gate)
ajsb6178002004-12-07 21:12:56 +00002824 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002825 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002826 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002827 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002828 ifindex,
2829 type);
2830 else
ajsb6178002004-12-07 21:12:56 +00002831 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002832 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002833 p->prefixlen,
2834 ifindex,
2835 type);
2836 }
2837 route_unlock_node (rn);
2838 return ZEBRA_ERR_RTNOEXIST;
2839 }
2840 }
2841
2842 if (same)
2843 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002844
paul718e3742002-12-13 20:15:29 +00002845 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002846 return 0;
2847}
David Lamparter6b0655a2014-06-04 06:53:35 +02002848
paul718e3742002-12-13 20:15:29 +00002849/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002850static void
paul718e3742002-12-13 20:15:29 +00002851static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2852{
2853 struct rib *rib;
2854 struct route_table *table;
2855 struct route_node *rn;
2856
2857 /* Lookup table. */
2858 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2859 if (! table)
2860 return;
2861
2862 /* Lookup existing route */
2863 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002864 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002865 {
2866 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2867 continue;
2868
2869 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2870 break;
2871 }
paul718e3742002-12-13 20:15:29 +00002872
2873 if (rib)
2874 {
2875 /* Same distance static route is there. Update it with new
2876 nexthop. */
paul718e3742002-12-13 20:15:29 +00002877 route_unlock_node (rn);
2878
2879 switch (si->type)
2880 {
2881 case STATIC_IPV6_GATEWAY:
2882 nexthop_ipv6_add (rib, &si->ipv6);
2883 break;
2884 case STATIC_IPV6_IFNAME:
2885 nexthop_ifname_add (rib, si->ifname);
2886 break;
2887 case STATIC_IPV6_GATEWAY_IFNAME:
2888 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2889 break;
2890 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002891 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002892 }
2893 else
2894 {
2895 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002896 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2897
paul718e3742002-12-13 20:15:29 +00002898 rib->type = ZEBRA_ROUTE_STATIC;
2899 rib->distance = si->distance;
2900 rib->metric = 0;
Dinesh G Duttd1b09912014-09-30 12:54:13 -07002901 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002902 rib->nexthop_num = 0;
2903
2904 switch (si->type)
2905 {
2906 case STATIC_IPV6_GATEWAY:
2907 nexthop_ipv6_add (rib, &si->ipv6);
2908 break;
2909 case STATIC_IPV6_IFNAME:
2910 nexthop_ifname_add (rib, si->ifname);
2911 break;
2912 case STATIC_IPV6_GATEWAY_IFNAME:
2913 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2914 break;
2915 }
2916
hasso81dfcaa2003-05-25 19:21:25 +00002917 /* Save the flags of this static routes (reject, blackhole) */
2918 rib->flags = si->flags;
2919
paul718e3742002-12-13 20:15:29 +00002920 /* Link this rib to the tree. */
2921 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002922 }
2923}
2924
paula1ac18c2005-06-28 17:17:12 +00002925static int
paul718e3742002-12-13 20:15:29 +00002926static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2927{
2928 if (nexthop->type == NEXTHOP_TYPE_IPV6
2929 && si->type == STATIC_IPV6_GATEWAY
2930 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2931 return 1;
2932 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2933 && si->type == STATIC_IPV6_IFNAME
2934 && strcmp (nexthop->ifname, si->ifname) == 0)
2935 return 1;
2936 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2937 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2938 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2939 && strcmp (nexthop->ifname, si->ifname) == 0)
2940 return 1;
paule8e19462006-01-19 20:16:55 +00002941 return 0;
paul718e3742002-12-13 20:15:29 +00002942}
2943
paula1ac18c2005-06-28 17:17:12 +00002944static void
paul718e3742002-12-13 20:15:29 +00002945static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2946{
2947 struct route_table *table;
2948 struct route_node *rn;
2949 struct rib *rib;
2950 struct nexthop *nexthop;
2951
2952 /* Lookup table. */
2953 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2954 if (! table)
2955 return;
2956
2957 /* Lookup existing route with type and distance. */
2958 rn = route_node_lookup (table, (struct prefix *) p);
2959 if (! rn)
2960 return;
2961
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002962 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002963 {
2964 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2965 continue;
2966
2967 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2968 break;
2969 }
2970
paul718e3742002-12-13 20:15:29 +00002971 if (! rib)
2972 {
2973 route_unlock_node (rn);
2974 return;
2975 }
2976
2977 /* Lookup nexthop. */
2978 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2979 if (static_ipv6_nexthop_same (nexthop, si))
2980 break;
2981
2982 /* Can't find nexthop. */
2983 if (! nexthop)
2984 {
2985 route_unlock_node (rn);
2986 return;
2987 }
2988
2989 /* Check nexthop. */
2990 if (rib->nexthop_num == 1)
2991 {
2992 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002993 }
2994 else
2995 {
paul6baeb982003-10-28 03:47:15 +00002996 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2997 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002998 nexthop_delete (rib, nexthop);
2999 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00003000 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003001 }
paul718e3742002-12-13 20:15:29 +00003002 /* Unlock node. */
3003 route_unlock_node (rn);
3004}
3005
3006/* Add static route into static route configuration. */
3007int
3008static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00003009 const char *ifname, u_char flags, u_char distance,
3010 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00003011{
3012 struct route_node *rn;
3013 struct static_ipv6 *si;
3014 struct static_ipv6 *pp;
3015 struct static_ipv6 *cp;
3016 struct route_table *stable;
3017
3018 /* Lookup table. */
3019 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
3020 if (! stable)
3021 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00003022
3023 if (!gate &&
3024 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
3025 return -1;
3026
3027 if (!ifname &&
3028 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
3029 return -1;
paul718e3742002-12-13 20:15:29 +00003030
3031 /* Lookup static route prefix. */
3032 rn = route_node_get (stable, p);
3033
3034 /* Do nothing if there is a same static route. */
3035 for (si = rn->info; si; si = si->next)
3036 {
3037 if (distance == si->distance
3038 && type == si->type
3039 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
3040 && (! ifname || strcmp (ifname, si->ifname) == 0))
3041 {
3042 route_unlock_node (rn);
3043 return 0;
3044 }
3045 }
3046
3047 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07003048 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
paul718e3742002-12-13 20:15:29 +00003049
3050 si->type = type;
3051 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00003052 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00003053
3054 switch (type)
3055 {
3056 case STATIC_IPV6_GATEWAY:
3057 si->ipv6 = *gate;
3058 break;
3059 case STATIC_IPV6_IFNAME:
3060 si->ifname = XSTRDUP (0, ifname);
3061 break;
3062 case STATIC_IPV6_GATEWAY_IFNAME:
3063 si->ipv6 = *gate;
3064 si->ifname = XSTRDUP (0, ifname);
3065 break;
3066 }
3067
3068 /* Add new static route information to the tree with sort by
3069 distance value and gateway address. */
3070 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
3071 {
3072 if (si->distance < cp->distance)
3073 break;
3074 if (si->distance > cp->distance)
3075 continue;
3076 }
3077
3078 /* Make linked list. */
3079 if (pp)
3080 pp->next = si;
3081 else
3082 rn->info = si;
3083 if (cp)
3084 cp->prev = si;
3085 si->prev = pp;
3086 si->next = cp;
3087
3088 /* Install into rib. */
3089 static_install_ipv6 (p, si);
3090
3091 return 1;
3092}
3093
3094/* Delete static route from static route configuration. */
3095int
3096static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00003097 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00003098{
3099 struct route_node *rn;
3100 struct static_ipv6 *si;
3101 struct route_table *stable;
3102
3103 /* Lookup table. */
3104 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
3105 if (! stable)
3106 return -1;
3107
3108 /* Lookup static route prefix. */
3109 rn = route_node_lookup (stable, p);
3110 if (! rn)
3111 return 0;
3112
3113 /* Find same static route is the tree */
3114 for (si = rn->info; si; si = si->next)
3115 if (distance == si->distance
3116 && type == si->type
3117 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
3118 && (! ifname || strcmp (ifname, si->ifname) == 0))
3119 break;
3120
3121 /* Can't find static route. */
3122 if (! si)
3123 {
3124 route_unlock_node (rn);
3125 return 0;
3126 }
3127
3128 /* Install into rib. */
3129 static_uninstall_ipv6 (p, si);
3130
3131 /* Unlink static route from linked list. */
3132 if (si->prev)
3133 si->prev->next = si->next;
3134 else
3135 rn->info = si->next;
3136 if (si->next)
3137 si->next->prev = si->prev;
3138
3139 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00003140 if (ifname)
3141 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00003142 XFREE (MTYPE_STATIC_IPV6, si);
3143
3144 return 1;
3145}
3146#endif /* HAVE_IPV6 */
David Lamparter6b0655a2014-06-04 06:53:35 +02003147
paul718e3742002-12-13 20:15:29 +00003148/* RIB update function. */
3149void
paula1ac18c2005-06-28 17:17:12 +00003150rib_update (void)
paul718e3742002-12-13 20:15:29 +00003151{
3152 struct route_node *rn;
3153 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00003154
paul718e3742002-12-13 20:15:29 +00003155 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
3156 if (table)
3157 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003158 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003159 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003160
3161 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
3162 if (table)
3163 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003164 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003165 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003166}
3167
David Lamparter6b0655a2014-06-04 06:53:35 +02003168
paul718e3742002-12-13 20:15:29 +00003169/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00003170static void
paul718e3742002-12-13 20:15:29 +00003171rib_weed_table (struct route_table *table)
3172{
3173 struct route_node *rn;
3174 struct rib *rib;
3175 struct rib *next;
3176
3177 if (table)
3178 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003179 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003180 {
Paul Jakma6d691122006-07-27 21:49:00 +00003181 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3182 continue;
3183
paulb21b19c2003-06-15 01:28:29 +00003184 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00003185 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00003186 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003187 }
3188}
3189
3190/* Delete all routes from non main table. */
3191void
paula1ac18c2005-06-28 17:17:12 +00003192rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00003193{
3194 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3195 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3196}
David Lamparter6b0655a2014-06-04 06:53:35 +02003197
paul718e3742002-12-13 20:15:29 +00003198/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00003199static void
paul718e3742002-12-13 20:15:29 +00003200rib_sweep_table (struct route_table *table)
3201{
3202 struct route_node *rn;
3203 struct rib *rib;
3204 struct rib *next;
3205 int ret = 0;
3206
3207 if (table)
3208 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003209 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003210 {
Paul Jakma6d691122006-07-27 21:49:00 +00003211 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3212 continue;
3213
paul718e3742002-12-13 20:15:29 +00003214 if (rib->type == ZEBRA_ROUTE_KERNEL &&
3215 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
3216 {
3217 ret = rib_uninstall_kernel (rn, rib);
3218 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00003219 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003220 }
3221 }
3222}
3223
3224/* Sweep all RIB tables. */
3225void
paula1ac18c2005-06-28 17:17:12 +00003226rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00003227{
3228 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3229 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3230}
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003231
3232/* Remove specific by protocol routes from 'table'. */
3233static unsigned long
3234rib_score_proto_table (u_char proto, struct route_table *table)
3235{
3236 struct route_node *rn;
3237 struct rib *rib;
3238 struct rib *next;
3239 unsigned long n = 0;
3240
3241 if (table)
3242 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003243 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003244 {
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003245 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3246 continue;
3247 if (rib->type == proto)
3248 {
3249 rib_delnode (rn, rib);
3250 n++;
3251 }
3252 }
3253
3254 return n;
3255}
3256
3257/* Remove specific by protocol routes. */
3258unsigned long
3259rib_score_proto (u_char proto)
3260{
3261 return rib_score_proto_table (proto, vrf_table (AFI_IP, SAFI_UNICAST, 0))
3262 +rib_score_proto_table (proto, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3263}
3264
paul718e3742002-12-13 20:15:29 +00003265/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00003266static void
paul718e3742002-12-13 20:15:29 +00003267rib_close_table (struct route_table *table)
3268{
3269 struct route_node *rn;
3270 struct rib *rib;
3271
3272 if (table)
3273 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003274 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00003275 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003276 if (!CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
3277 continue;
3278
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00003279 zfpm_trigger_update (rn, NULL);
3280
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003281 if (! RIB_SYSTEM_ROUTE (rib))
3282 rib_uninstall_kernel (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00003283 }
paul718e3742002-12-13 20:15:29 +00003284}
3285
3286/* Close all RIB tables. */
3287void
paula1ac18c2005-06-28 17:17:12 +00003288rib_close (void)
paul718e3742002-12-13 20:15:29 +00003289{
3290 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3291 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3292}
David Lamparter6b0655a2014-06-04 06:53:35 +02003293
paul718e3742002-12-13 20:15:29 +00003294/* Routing information base initialize. */
3295void
paula1ac18c2005-06-28 17:17:12 +00003296rib_init (void)
paul718e3742002-12-13 20:15:29 +00003297{
paul4d38fdb2005-04-28 17:35:14 +00003298 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00003299 /* VRF initialization. */
3300 vrf_init ();
3301}
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003302
3303/*
3304 * vrf_id_get_next
3305 *
3306 * Get the first vrf id that is greater than the given vrf id if any.
3307 *
3308 * Returns TRUE if a vrf id was found, FALSE otherwise.
3309 */
3310static inline int
3311vrf_id_get_next (uint32_t id, uint32_t *next_id_p)
3312{
3313 while (++id < vector_active (vrf_vector))
3314 {
3315 if (vrf_lookup (id))
3316 {
3317 *next_id_p = id;
3318 return 1;
3319 }
3320 }
3321
3322 return 0;
3323}
3324
3325/*
3326 * rib_tables_iter_next
3327 *
3328 * Returns the next table in the iteration.
3329 */
3330struct route_table *
3331rib_tables_iter_next (rib_tables_iter_t *iter)
3332{
3333 struct route_table *table;
3334
3335 /*
3336 * Array that helps us go over all AFI/SAFI combinations via one
3337 * index.
3338 */
3339 static struct {
3340 afi_t afi;
3341 safi_t safi;
3342 } afi_safis[] = {
3343 { AFI_IP, SAFI_UNICAST },
3344 { AFI_IP, SAFI_MULTICAST },
3345 { AFI_IP6, SAFI_UNICAST },
3346 { AFI_IP6, SAFI_MULTICAST },
3347 };
3348
3349 table = NULL;
3350
3351 switch (iter->state)
3352 {
3353
3354 case RIB_TABLES_ITER_S_INIT:
3355 iter->vrf_id = 0;
3356 iter->afi_safi_ix = -1;
3357
3358 /* Fall through */
3359
3360 case RIB_TABLES_ITER_S_ITERATING:
3361 iter->afi_safi_ix++;
3362 while (1)
3363 {
3364
3365 while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
3366 {
3367 table = vrf_table (afi_safis[iter->afi_safi_ix].afi,
3368 afi_safis[iter->afi_safi_ix].safi,
3369 iter->vrf_id);
3370 if (table)
3371 break;
3372
3373 iter->afi_safi_ix++;
3374 }
3375
3376 /*
3377 * Found another table in this vrf.
3378 */
3379 if (table)
3380 break;
3381
3382 /*
3383 * Done with all tables in the current vrf, go to the next
3384 * one.
3385 */
3386 if (!vrf_id_get_next (iter->vrf_id, &iter->vrf_id))
3387 break;
3388
3389 iter->afi_safi_ix = 0;
3390 }
3391
3392 break;
3393
3394 case RIB_TABLES_ITER_S_DONE:
3395 return NULL;
3396 }
3397
3398 if (table)
3399 iter->state = RIB_TABLES_ITER_S_ITERATING;
3400 else
3401 iter->state = RIB_TABLES_ITER_S_DONE;
3402
3403 return table;
3404}