blob: 9ca02904ed0df9b187d5132188a34d8c53528927 [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"
Feng Lu41f44a22015-05-22 11:39:56 +020037#include "vrf.h"
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -050038#include "nexthop.h"
paul718e3742002-12-13 20:15:29 +000039
40#include "zebra/rib.h"
41#include "zebra/rt.h"
42#include "zebra/zserv.h"
43#include "zebra/redistribute.h"
44#include "zebra/debug.h"
Avneesh Sachdev5adc2522012-11-13 22:48:59 +000045#include "zebra/zebra_fpm.h"
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -050046#include "zebra/zebra_rnh.h"
paul718e3742002-12-13 20:15:29 +000047
48/* Default rtm_table for all clients */
paulb21b19c2003-06-15 01:28:29 +000049extern struct zebra_t zebrad;
paul718e3742002-12-13 20:15:29 +000050
Paul Jakma457eb9a2006-07-27 19:59:58 +000051/* Hold time for RIB process, should be very minimal.
52 * it is useful to able to set it otherwise for testing, hence exported
53 * as global here for test-rig code.
54 */
55int rib_process_hold_time = 10;
56
paul718e3742002-12-13 20:15:29 +000057/* Each route type's string and default distance value. */
Stephen Hemmingerd145bc02008-08-17 17:41:37 +010058static const struct
paul718e3742002-12-13 20:15:29 +000059{
60 int key;
61 int distance;
Paul Jakma57345092011-12-25 17:52:09 +010062} route_info[ZEBRA_ROUTE_MAX] =
paul718e3742002-12-13 20:15:29 +000063{
Paul Jakma57345092011-12-25 17:52:09 +010064 [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0},
65 [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0},
66 [ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0},
67 [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1},
68 [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120},
69 [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120},
70 [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110},
71 [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110},
72 [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115},
73 [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */},
74 [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 95},
Timo Teräsdafa05e2017-01-19 17:27:01 +020075 [ZEBRA_ROUTE_NHRP] = {ZEBRA_ROUTE_NHRP, 10},
David Lamparter7052f222009-08-27 00:28:28 +020076 /* no entry/default: 150 */
paul718e3742002-12-13 20:15:29 +000077};
David Lamparter6b0655a2014-06-04 06:53:35 +020078
David Lamparterbd078122015-01-06 19:53:24 +010079/* RPF lookup behaviour */
80static enum multicast_mode ipv4_multicast_mode = MCAST_NO_CONFIG;
81
David Lampartereed3c482015-03-03 08:51:53 +010082static void __attribute__((format (printf, 4, 5)))
David Lamparter94813742014-04-24 20:22:53 +020083_rnode_zlog(const char *_func, struct route_node *rn, int priority,
84 const char *msgfmt, ...)
85{
Feng Lu0d0686f2015-05-22 11:40:02 +020086 char prefix[PREFIX_STRLEN], buf[256];
David Lamparter94813742014-04-24 20:22:53 +020087 char msgbuf[512];
88 va_list ap;
89
90 va_start(ap, msgfmt);
91 vsnprintf(msgbuf, sizeof(msgbuf), msgfmt, ap);
92 va_end(ap);
93
94 if (rn)
95 {
David Lamparterab2ba612015-01-22 19:02:13 +010096 rib_table_info_t *info = rn->table->info;
97
Feng Lu0d0686f2015-05-22 11:40:02 +020098 snprintf(buf, sizeof(buf), "%s%s vrf %u",
99 prefix2str(&rn->p, prefix, sizeof(prefix)),
100 info->safi == SAFI_MULTICAST ? " (MRIB)" : "",
101 info->zvrf->vrf_id);
David Lamparter94813742014-04-24 20:22:53 +0200102 }
103 else
104 {
105 snprintf(buf, sizeof(buf), "{(route_node *) NULL}");
106 }
107
108 zlog (NULL, priority, "%s: %s: %s", _func, buf, msgbuf);
109}
110
111#define rnode_debug(node, ...) \
112 _rnode_zlog(__func__, node, LOG_DEBUG, __VA_ARGS__)
113#define rnode_info(node, ...) \
114 _rnode_zlog(__func__, node, LOG_INFO, __VA_ARGS__)
115
Christian Frankefa713d92013-07-05 15:35:37 +0000116/* Add nexthop to the end of a rib node's nexthop list */
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500117void
118rib_nexthop_add (struct rib *rib, struct nexthop *nexthop)
Christian Frankefa713d92013-07-05 15:35:37 +0000119{
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500120 nexthop_add(&rib->nexthop, nexthop);
paul718e3742002-12-13 20:15:29 +0000121 rib->nexthop_num++;
122}
123
124/* Delete specified nexthop from the list. */
paula1ac18c2005-06-28 17:17:12 +0000125static void
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500126rib_nexthop_delete (struct rib *rib, struct nexthop *nexthop)
paul718e3742002-12-13 20:15:29 +0000127{
128 if (nexthop->next)
129 nexthop->next->prev = nexthop->prev;
130 if (nexthop->prev)
131 nexthop->prev->next = nexthop->next;
132 else
133 rib->nexthop = nexthop->next;
134 rib->nexthop_num--;
135}
136
paul718e3742002-12-13 20:15:29 +0000137struct nexthop *
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500138rib_nexthop_ifindex_add (struct rib *rib, ifindex_t ifindex)
paul718e3742002-12-13 20:15:29 +0000139{
140 struct nexthop *nexthop;
141
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500142 nexthop = nexthop_new ();
paul718e3742002-12-13 20:15:29 +0000143 nexthop->type = NEXTHOP_TYPE_IFINDEX;
144 nexthop->ifindex = ifindex;
145
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500146 rib_nexthop_add (rib, nexthop);
paul718e3742002-12-13 20:15:29 +0000147
148 return nexthop;
149}
150
151struct nexthop *
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500152rib_nexthop_ifname_add (struct rib *rib, char *ifname)
paul718e3742002-12-13 20:15:29 +0000153{
154 struct nexthop *nexthop;
155
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500156 nexthop = nexthop_new ();
paul718e3742002-12-13 20:15:29 +0000157 nexthop->type = NEXTHOP_TYPE_IFNAME;
David Lamparter23757db2016-02-24 06:26:02 +0100158 nexthop->ifname = XSTRDUP (MTYPE_TMP, ifname);
paul718e3742002-12-13 20:15:29 +0000159
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500160 rib_nexthop_add (rib, nexthop);
paul718e3742002-12-13 20:15:29 +0000161
162 return nexthop;
163}
164
165struct nexthop *
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500166rib_nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src)
paul718e3742002-12-13 20:15:29 +0000167{
168 struct nexthop *nexthop;
169
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500170 nexthop = nexthop_new ();
paul718e3742002-12-13 20:15:29 +0000171 nexthop->type = NEXTHOP_TYPE_IPV4;
172 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000173 if (src)
174 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000175
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500176 rib_nexthop_add (rib, nexthop);
paul718e3742002-12-13 20:15:29 +0000177
178 return nexthop;
179}
180
Josh Bailey26e2ae32012-03-22 01:09:21 -0700181struct nexthop *
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500182rib_nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
183 struct in_addr *src, ifindex_t ifindex)
paul718e3742002-12-13 20:15:29 +0000184{
185 struct nexthop *nexthop;
186
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500187 nexthop = nexthop_new ();
paul718e3742002-12-13 20:15:29 +0000188 nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
189 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000190 if (src)
191 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000192 nexthop->ifindex = ifindex;
193
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500194 rib_nexthop_add (rib, nexthop);
paul718e3742002-12-13 20:15:29 +0000195
196 return nexthop;
197}
198
paul718e3742002-12-13 20:15:29 +0000199struct nexthop *
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500200rib_nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
paul718e3742002-12-13 20:15:29 +0000201{
202 struct nexthop *nexthop;
203
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500204 nexthop = nexthop_new ();
paul718e3742002-12-13 20:15:29 +0000205 nexthop->type = NEXTHOP_TYPE_IPV6;
206 nexthop->gate.ipv6 = *ipv6;
207
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500208 rib_nexthop_add (rib, nexthop);
paul718e3742002-12-13 20:15:29 +0000209
210 return nexthop;
211}
212
paula1ac18c2005-06-28 17:17:12 +0000213static struct nexthop *
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500214rib_nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
215 char *ifname)
paul718e3742002-12-13 20:15:29 +0000216{
217 struct nexthop *nexthop;
218
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500219 nexthop = nexthop_new ();
paul718e3742002-12-13 20:15:29 +0000220 nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
221 nexthop->gate.ipv6 = *ipv6;
David Lamparter23757db2016-02-24 06:26:02 +0100222 nexthop->ifname = XSTRDUP (MTYPE_TMP, ifname);
paul718e3742002-12-13 20:15:29 +0000223
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500224 rib_nexthop_add (rib, nexthop);
paul718e3742002-12-13 20:15:29 +0000225
226 return nexthop;
227}
228
Ayan Banerjee34c5d892015-11-09 20:14:53 -0500229struct nexthop *
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500230rib_nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
231 ifindex_t ifindex)
paul718e3742002-12-13 20:15:29 +0000232{
233 struct nexthop *nexthop;
234
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500235 nexthop = nexthop_new ();
paul718e3742002-12-13 20:15:29 +0000236 nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
237 nexthop->gate.ipv6 = *ipv6;
238 nexthop->ifindex = ifindex;
239
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500240 rib_nexthop_add (rib, nexthop);
paul718e3742002-12-13 20:15:29 +0000241
242 return nexthop;
243}
paul718e3742002-12-13 20:15:29 +0000244
paul595db7f2003-05-25 21:35:06 +0000245struct nexthop *
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500246rib_nexthop_blackhole_add (struct rib *rib)
paul595db7f2003-05-25 21:35:06 +0000247{
248 struct nexthop *nexthop;
249
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500250 nexthop = nexthop_new ();
paul595db7f2003-05-25 21:35:06 +0000251 nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
252 SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
253
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500254 rib_nexthop_add (rib, nexthop);
paul595db7f2003-05-25 21:35:06 +0000255
256 return nexthop;
257}
258
Christian Frankefa713d92013-07-05 15:35:37 +0000259/* This method checks whether a recursive nexthop has at
260 * least one resolved nexthop in the fib.
261 */
262int
263nexthop_has_fib_child(struct nexthop *nexthop)
264{
265 struct nexthop *nh;
266
267 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
268 return 0;
269
270 for (nh = nexthop->resolved; nh; nh = nh->next)
271 if (CHECK_FLAG (nh->flags, NEXTHOP_FLAG_FIB))
272 return 1;
273
274 return 0;
275}
276
paul718e3742002-12-13 20:15:29 +0000277/* If force flag is not set, do not modify falgs at all for uninstall
278 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000279static int
paul718e3742002-12-13 20:15:29 +0000280nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
281 struct route_node *top)
282{
283 struct prefix_ipv4 p;
284 struct route_table *table;
285 struct route_node *rn;
286 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000287 int resolved;
paul718e3742002-12-13 20:15:29 +0000288 struct nexthop *newhop;
Christian Frankefa713d92013-07-05 15:35:37 +0000289 struct nexthop *resolved_hop;
paul718e3742002-12-13 20:15:29 +0000290
291 if (nexthop->type == NEXTHOP_TYPE_IPV4)
292 nexthop->ifindex = 0;
293
294 if (set)
Christian Frankefa713d92013-07-05 15:35:37 +0000295 {
296 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
297 nexthops_free(nexthop->resolved);
298 nexthop->resolved = NULL;
Timo Teräsb11f3b52015-11-02 16:50:07 +0200299 rib->nexthop_mtu = 0;
Christian Frankefa713d92013-07-05 15:35:37 +0000300 }
paul718e3742002-12-13 20:15:29 +0000301
302 /* Make lookup prefix. */
303 memset (&p, 0, sizeof (struct prefix_ipv4));
304 p.family = AF_INET;
305 p.prefixlen = IPV4_MAX_PREFIXLEN;
306 p.prefix = nexthop->gate.ipv4;
307
308 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200309 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, rib->vrf_id);
paul718e3742002-12-13 20:15:29 +0000310 if (! table)
311 return 0;
312
313 rn = route_node_match (table, (struct prefix *) &p);
314 while (rn)
315 {
316 route_unlock_node (rn);
317
David Warda50c1072009-12-03 15:34:39 +0300318 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000319 if (rn == top)
320 return 0;
321
322 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000323 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100324 {
325 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
326 continue;
Timo Teräs325823a2016-01-15 17:36:31 +0200327 if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB))
Stephen Hemminger16814f92008-08-17 17:39:31 +0100328 break;
329 }
paul718e3742002-12-13 20:15:29 +0000330
331 /* If there is no selected route or matched route is EGP, go up
332 tree. */
333 if (! match
334 || match->type == ZEBRA_ROUTE_BGP)
335 {
336 do {
337 rn = rn->parent;
338 } while (rn && rn->info == NULL);
339 if (rn)
340 route_lock_node (rn);
341 }
342 else
343 {
Christian Franke48a53dc2013-07-05 15:35:38 +0000344 /* If the longest prefix match for the nexthop yields
345 * a blackhole, mark it as inactive. */
346 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE)
347 || CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT))
348 return 0;
349
paul718e3742002-12-13 20:15:29 +0000350 if (match->type == ZEBRA_ROUTE_CONNECT)
351 {
352 /* Directly point connected route. */
353 newhop = match->nexthop;
354 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
355 nexthop->ifindex = newhop->ifindex;
356
357 return 1;
358 }
359 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
360 {
Christian Frankefa713d92013-07-05 15:35:37 +0000361 resolved = 0;
paul718e3742002-12-13 20:15:29 +0000362 for (newhop = match->nexthop; newhop; newhop = newhop->next)
363 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
364 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
365 {
366 if (set)
367 {
368 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
Christian Frankefa713d92013-07-05 15:35:37 +0000369
370 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
371 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
Christian Frankec3e6b592013-07-05 15:35:40 +0000372 /* If the resolving route specifies a gateway, use it */
373 if (newhop->type == NEXTHOP_TYPE_IPV4
374 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX
375 || newhop->type == NEXTHOP_TYPE_IPV4_IFNAME)
376 {
377 resolved_hop->type = newhop->type;
378 resolved_hop->gate.ipv4 = newhop->gate.ipv4;
Timo Teräs82a66352016-01-15 17:36:30 +0200379 resolved_hop->ifindex = newhop->ifindex;
Christian Frankec3e6b592013-07-05 15:35:40 +0000380 }
Christian Frankefa713d92013-07-05 15:35:37 +0000381
Timo Teräs82a66352016-01-15 17:36:30 +0200382 /* If the resolving route is an interface route, it
383 * means the gateway we are looking up is connected
384 * to that interface. Therefore, the resolved route
385 * should have the original gateway as nexthop as it
386 * is directly connected. */
paul718e3742002-12-13 20:15:29 +0000387 if (newhop->type == NEXTHOP_TYPE_IFINDEX
Christian Frankec3e6b592013-07-05 15:35:40 +0000388 || newhop->type == NEXTHOP_TYPE_IFNAME)
389 {
Christian Frankec3e6b592013-07-05 15:35:40 +0000390 resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
391 resolved_hop->gate.ipv4 = nexthop->gate.ipv4;
392 resolved_hop->ifindex = newhop->ifindex;
393 }
Christian Frankefa713d92013-07-05 15:35:37 +0000394
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500395 nexthop_add(&nexthop->resolved, resolved_hop);
paul718e3742002-12-13 20:15:29 +0000396 }
Christian Frankefa713d92013-07-05 15:35:37 +0000397 resolved = 1;
paul718e3742002-12-13 20:15:29 +0000398 }
Timo Teräsb11f3b52015-11-02 16:50:07 +0200399 if (resolved && set)
400 rib->nexthop_mtu = match->mtu;
Christian Frankefa713d92013-07-05 15:35:37 +0000401 return resolved;
paul718e3742002-12-13 20:15:29 +0000402 }
403 else
404 {
405 return 0;
406 }
407 }
408 }
409 return 0;
410}
411
paul718e3742002-12-13 20:15:29 +0000412/* If force flag is not set, do not modify falgs at all for uninstall
413 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000414static int
paul718e3742002-12-13 20:15:29 +0000415nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
416 struct route_node *top)
417{
418 struct prefix_ipv6 p;
419 struct route_table *table;
420 struct route_node *rn;
421 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000422 int resolved;
paul718e3742002-12-13 20:15:29 +0000423 struct nexthop *newhop;
Christian Frankefa713d92013-07-05 15:35:37 +0000424 struct nexthop *resolved_hop;
paul718e3742002-12-13 20:15:29 +0000425
426 if (nexthop->type == NEXTHOP_TYPE_IPV6)
427 nexthop->ifindex = 0;
428
429 if (set)
Christian Frankefa713d92013-07-05 15:35:37 +0000430 {
431 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
432 nexthops_free(nexthop->resolved);
433 nexthop->resolved = NULL;
434 }
paul718e3742002-12-13 20:15:29 +0000435
436 /* Make lookup prefix. */
437 memset (&p, 0, sizeof (struct prefix_ipv6));
438 p.family = AF_INET6;
439 p.prefixlen = IPV6_MAX_PREFIXLEN;
440 p.prefix = nexthop->gate.ipv6;
441
442 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200443 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, rib->vrf_id);
paul718e3742002-12-13 20:15:29 +0000444 if (! table)
445 return 0;
446
447 rn = route_node_match (table, (struct prefix *) &p);
448 while (rn)
449 {
450 route_unlock_node (rn);
451
David Warda50c1072009-12-03 15:34:39 +0300452 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000453 if (rn == top)
454 return 0;
455
456 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000457 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100458 {
459 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
460 continue;
Timo Teräs325823a2016-01-15 17:36:31 +0200461 if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB))
Stephen Hemminger16814f92008-08-17 17:39:31 +0100462 break;
463 }
paul718e3742002-12-13 20:15:29 +0000464
465 /* If there is no selected route or matched route is EGP, go up
466 tree. */
467 if (! match
468 || match->type == ZEBRA_ROUTE_BGP)
469 {
470 do {
471 rn = rn->parent;
472 } while (rn && rn->info == NULL);
473 if (rn)
474 route_lock_node (rn);
475 }
476 else
477 {
Christian Franke48a53dc2013-07-05 15:35:38 +0000478 /* If the longest prefix match for the nexthop yields
479 * a blackhole, mark it as inactive. */
480 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE)
481 || CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT))
482 return 0;
483
paul718e3742002-12-13 20:15:29 +0000484 if (match->type == ZEBRA_ROUTE_CONNECT)
485 {
486 /* Directly point connected route. */
487 newhop = match->nexthop;
488
489 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
490 nexthop->ifindex = newhop->ifindex;
491
492 return 1;
493 }
494 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
495 {
Christian Frankefa713d92013-07-05 15:35:37 +0000496 resolved = 0;
paul718e3742002-12-13 20:15:29 +0000497 for (newhop = match->nexthop; newhop; newhop = newhop->next)
498 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
499 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
500 {
501 if (set)
502 {
503 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
Christian Frankefa713d92013-07-05 15:35:37 +0000504
505 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
506 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
Christian Frankec3e6b592013-07-05 15:35:40 +0000507 /* See nexthop_active_ipv4 for a description how the
508 * resolved nexthop is constructed. */
paul718e3742002-12-13 20:15:29 +0000509 if (newhop->type == NEXTHOP_TYPE_IPV6
510 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
511 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
Christian Frankec3e6b592013-07-05 15:35:40 +0000512 {
513 resolved_hop->type = newhop->type;
514 resolved_hop->gate.ipv6 = newhop->gate.ipv6;
515
516 if (newhop->ifindex)
517 {
518 resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
519 resolved_hop->ifindex = newhop->ifindex;
520 }
521 }
Christian Frankefa713d92013-07-05 15:35:37 +0000522
paul718e3742002-12-13 20:15:29 +0000523 if (newhop->type == NEXTHOP_TYPE_IFINDEX
Christian Frankec3e6b592013-07-05 15:35:40 +0000524 || newhop->type == NEXTHOP_TYPE_IFNAME)
525 {
526 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
527 resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
528 resolved_hop->gate.ipv6 = nexthop->gate.ipv6;
529 resolved_hop->ifindex = newhop->ifindex;
530 }
Christian Frankefa713d92013-07-05 15:35:37 +0000531
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500532 nexthop_add(&nexthop->resolved, resolved_hop);
paul718e3742002-12-13 20:15:29 +0000533 }
Christian Frankefa713d92013-07-05 15:35:37 +0000534 resolved = 1;
paul718e3742002-12-13 20:15:29 +0000535 }
Christian Frankefa713d92013-07-05 15:35:37 +0000536 return resolved;
paul718e3742002-12-13 20:15:29 +0000537 }
538 else
539 {
540 return 0;
541 }
542 }
543 }
544 return 0;
545}
paul718e3742002-12-13 20:15:29 +0000546
547struct rib *
David Lamparter24480d42015-01-22 19:09:36 +0100548rib_match_ipv4_safi (struct in_addr addr, safi_t safi, int skip_bgp,
Feng Lu0d0686f2015-05-22 11:40:02 +0200549 struct route_node **rn_out, vrf_id_t vrf_id)
Everton Marques3dea1782014-09-22 19:35:51 -0300550{
551 struct route_table *table;
552 struct route_node *rn;
553 struct rib *match;
554 struct nexthop *newhop, *tnewhop;
555 int recursing;
556
557 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200558 table = zebra_vrf_table (AFI_IP, safi, vrf_id);
Everton Marques3dea1782014-09-22 19:35:51 -0300559 if (! table)
560 return 0;
561
562 rn = route_node_match_ipv4 (table, &addr);
563
564 while (rn)
565 {
566 route_unlock_node (rn);
567
568 /* Pick up selected route. */
569 RNODE_FOREACH_RIB (rn, match)
570 {
571 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
572 continue;
Timo Teräs325823a2016-01-15 17:36:31 +0200573 if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB))
Everton Marques3dea1782014-09-22 19:35:51 -0300574 break;
575 }
576
577 /* If there is no selected route or matched route is EGP, go up
578 tree. */
Everton Marques83d71122014-09-19 16:39:34 -0300579 if (!match || (skip_bgp && (match->type == ZEBRA_ROUTE_BGP)))
Everton Marques3dea1782014-09-22 19:35:51 -0300580 {
581 do {
582 rn = rn->parent;
583 } while (rn && rn->info == NULL);
584 if (rn)
585 route_lock_node (rn);
586 }
587 else
588 {
David Lamparter24480d42015-01-22 19:09:36 +0100589 if (match->type != ZEBRA_ROUTE_CONNECT)
Everton Marques3dea1782014-09-22 19:35:51 -0300590 {
David Lamparter24480d42015-01-22 19:09:36 +0100591 int found = 0;
Everton Marques3dea1782014-09-22 19:35:51 -0300592 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
593 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
David Lamparter24480d42015-01-22 19:09:36 +0100594 {
595 found = 1;
596 break;
597 }
598 if (!found)
599 return NULL;
Everton Marques3dea1782014-09-22 19:35:51 -0300600 }
David Lamparter24480d42015-01-22 19:09:36 +0100601
602 if (rn_out)
603 *rn_out = rn;
604 return match;
Everton Marques3dea1782014-09-22 19:35:51 -0300605 }
606 }
607 return NULL;
608}
609
610struct rib *
Feng Lu0d0686f2015-05-22 11:40:02 +0200611rib_match_ipv4_multicast (struct in_addr addr, struct route_node **rn_out,
612 vrf_id_t vrf_id)
David Lamparterbd078122015-01-06 19:53:24 +0100613{
614 struct rib *rib = NULL, *mrib = NULL, *urib = NULL;
615 struct route_node *m_rn = NULL, *u_rn = NULL;
616 int skip_bgp = 0; /* bool */
617
618 switch (ipv4_multicast_mode)
619 {
620 case MCAST_MRIB_ONLY:
Feng Lu0d0686f2015-05-22 11:40:02 +0200621 return rib_match_ipv4_safi (addr, SAFI_MULTICAST, skip_bgp, rn_out,
622 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100623 case MCAST_URIB_ONLY:
Feng Lu0d0686f2015-05-22 11:40:02 +0200624 return rib_match_ipv4_safi (addr, SAFI_UNICAST, skip_bgp, rn_out,
625 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100626 case MCAST_NO_CONFIG:
627 case MCAST_MIX_MRIB_FIRST:
Feng Lu0d0686f2015-05-22 11:40:02 +0200628 rib = mrib = rib_match_ipv4_safi (addr, SAFI_MULTICAST, skip_bgp, &m_rn,
629 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100630 if (!mrib)
Feng Lu0d0686f2015-05-22 11:40:02 +0200631 rib = urib = rib_match_ipv4_safi (addr, SAFI_UNICAST, skip_bgp, &u_rn,
632 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100633 break;
634 case MCAST_MIX_DISTANCE:
Feng Lu0d0686f2015-05-22 11:40:02 +0200635 mrib = rib_match_ipv4_safi (addr, SAFI_MULTICAST, skip_bgp, &m_rn,
636 vrf_id);
637 urib = rib_match_ipv4_safi (addr, SAFI_UNICAST, skip_bgp, &u_rn,
638 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100639 if (mrib && urib)
640 rib = urib->distance < mrib->distance ? urib : mrib;
641 else if (mrib)
642 rib = mrib;
643 else if (urib)
644 rib = urib;
645 break;
646 case MCAST_MIX_PFXLEN:
Feng Lu0d0686f2015-05-22 11:40:02 +0200647 mrib = rib_match_ipv4_safi (addr, SAFI_MULTICAST, skip_bgp, &m_rn,
648 vrf_id);
649 urib = rib_match_ipv4_safi (addr, SAFI_UNICAST, skip_bgp, &u_rn,
650 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100651 if (mrib && urib)
652 rib = u_rn->p.prefixlen > m_rn->p.prefixlen ? urib : mrib;
653 else if (mrib)
654 rib = mrib;
655 else if (urib)
656 rib = urib;
657 break;
658 }
659
660 if (rn_out)
661 *rn_out = (rib == mrib) ? m_rn : u_rn;
662
663 if (IS_ZEBRA_DEBUG_RIB)
664 {
665 char buf[BUFSIZ];
666 inet_ntop (AF_INET, &addr, buf, BUFSIZ);
667
Feng Lu0d0686f2015-05-22 11:40:02 +0200668 zlog_debug("%s: %s vrf %u: found %s, using %s",
669 __func__, buf, vrf_id,
David Lamparterbd078122015-01-06 19:53:24 +0100670 mrib ? (urib ? "MRIB+URIB" : "MRIB") :
671 urib ? "URIB" : "nothing",
672 rib == urib ? "URIB" : rib == mrib ? "MRIB" : "none");
673 }
674 return rib;
675}
676
677void
678multicast_mode_ipv4_set (enum multicast_mode mode)
679{
680 if (IS_ZEBRA_DEBUG_RIB)
681 zlog_debug("%s: multicast lookup mode set (%d)", __func__, mode);
682 ipv4_multicast_mode = mode;
683}
684
685enum multicast_mode
686multicast_mode_ipv4_get (void)
687{
688 return ipv4_multicast_mode;
689}
690
691struct rib *
Feng Lu0d0686f2015-05-22 11:40:02 +0200692rib_lookup_ipv4 (struct prefix_ipv4 *p, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000693{
694 struct route_table *table;
695 struct route_node *rn;
696 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000697 struct nexthop *nexthop, *tnexthop;
698 int recursing;
paul718e3742002-12-13 20:15:29 +0000699
700 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200701 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +0000702 if (! table)
703 return 0;
704
705 rn = route_node_lookup (table, (struct prefix *) p);
706
707 /* No route for this prefix. */
708 if (! rn)
709 return NULL;
710
711 /* Unlock node. */
712 route_unlock_node (rn);
713
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000714 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100715 {
716 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
717 continue;
Timo Teräs325823a2016-01-15 17:36:31 +0200718 if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB))
Stephen Hemminger16814f92008-08-17 17:39:31 +0100719 break;
720 }
paul718e3742002-12-13 20:15:29 +0000721
722 if (! match || match->type == ZEBRA_ROUTE_BGP)
723 return NULL;
724
725 if (match->type == ZEBRA_ROUTE_CONNECT)
726 return match;
727
Christian Frankefa713d92013-07-05 15:35:37 +0000728 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +0000729 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
730 return match;
731
732 return NULL;
733}
734
Denis Ovsienkodc958242007-08-13 16:03:06 +0000735/*
736 * This clone function, unlike its original rib_lookup_ipv4(), checks
737 * if specified IPv4 route record (prefix/mask -> gate) exists in
738 * the whole RIB and has ZEBRA_FLAG_SELECTED set.
739 *
740 * Return values:
741 * -1: error
742 * 0: exact match found
743 * 1: a match was found with a different gate
744 * 2: connected route found
745 * 3: no matches found
746 */
747int
Feng Lu0d0686f2015-05-22 11:40:02 +0200748rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate,
749 vrf_id_t vrf_id)
Denis Ovsienkodc958242007-08-13 16:03:06 +0000750{
751 struct route_table *table;
752 struct route_node *rn;
753 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000754 struct nexthop *nexthop, *tnexthop;
755 int recursing;
756 int nexthops_active;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000757
758 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200759 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
Denis Ovsienkodc958242007-08-13 16:03:06 +0000760 if (! table)
761 return ZEBRA_RIB_LOOKUP_ERROR;
762
763 /* Scan the RIB table for exactly matching RIB entry. */
764 rn = route_node_lookup (table, (struct prefix *) p);
765
766 /* No route for this prefix. */
767 if (! rn)
768 return ZEBRA_RIB_NOTFOUND;
769
770 /* Unlock node. */
771 route_unlock_node (rn);
772
773 /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000774 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100775 {
776 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
777 continue;
Timo Teräs325823a2016-01-15 17:36:31 +0200778 if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB))
Stephen Hemminger16814f92008-08-17 17:39:31 +0100779 break;
780 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000781
782 /* None such found :( */
783 if (!match)
784 return ZEBRA_RIB_NOTFOUND;
785
786 if (match->type == ZEBRA_ROUTE_CONNECT)
787 return ZEBRA_RIB_FOUND_CONNECTED;
788
789 /* Ok, we have a cood candidate, let's check it's nexthop list... */
Christian Frankefa713d92013-07-05 15:35:37 +0000790 nexthops_active = 0;
791 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000792 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000793 {
Christian Frankefa713d92013-07-05 15:35:37 +0000794 nexthops_active = 1;
795 if (nexthop->gate.ipv4.s_addr == sockunion2ip (qgate))
796 return ZEBRA_RIB_FOUND_EXACT;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000797 if (IS_ZEBRA_DEBUG_RIB)
Christian Frankefa713d92013-07-05 15:35:37 +0000798 {
799 char gate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
800 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
801 inet_ntop (AF_INET, &sockunion2ip(qgate), qgate_buf, INET_ADDRSTRLEN);
802 zlog_debug ("%s: qgate == %s, %s == %s", __func__,
803 qgate_buf, recursing ? "rgate" : "gate", gate_buf);
804 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000805 }
Christian Frankefa713d92013-07-05 15:35:37 +0000806
807 if (nexthops_active)
808 return ZEBRA_RIB_FOUND_NOGATE;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000809
810 return ZEBRA_RIB_NOTFOUND;
811}
812
paul718e3742002-12-13 20:15:29 +0000813struct rib *
Feng Lu0d0686f2015-05-22 11:40:02 +0200814rib_match_ipv6 (struct in6_addr *addr, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000815{
816 struct prefix_ipv6 p;
817 struct route_table *table;
818 struct route_node *rn;
819 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000820 struct nexthop *newhop, *tnewhop;
821 int recursing;
paul718e3742002-12-13 20:15:29 +0000822
823 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200824 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +0000825 if (! table)
826 return 0;
827
828 memset (&p, 0, sizeof (struct prefix_ipv6));
829 p.family = AF_INET6;
830 p.prefixlen = IPV6_MAX_PREFIXLEN;
831 IPV6_ADDR_COPY (&p.prefix, addr);
832
833 rn = route_node_match (table, (struct prefix *) &p);
834
835 while (rn)
836 {
837 route_unlock_node (rn);
838
839 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000840 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100841 {
842 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
843 continue;
Timo Teräs325823a2016-01-15 17:36:31 +0200844 if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB))
Stephen Hemminger16814f92008-08-17 17:39:31 +0100845 break;
846 }
paul718e3742002-12-13 20:15:29 +0000847
848 /* If there is no selected route or matched route is EGP, go up
849 tree. */
850 if (! match
851 || match->type == ZEBRA_ROUTE_BGP)
852 {
853 do {
854 rn = rn->parent;
855 } while (rn && rn->info == NULL);
856 if (rn)
857 route_lock_node (rn);
858 }
859 else
860 {
861 if (match->type == ZEBRA_ROUTE_CONNECT)
862 /* Directly point connected route. */
863 return match;
864 else
865 {
Christian Frankefa713d92013-07-05 15:35:37 +0000866 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
paul718e3742002-12-13 20:15:29 +0000867 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
868 return match;
869 return NULL;
870 }
871 }
872 }
873 return NULL;
874}
paul718e3742002-12-13 20:15:29 +0000875
Paul Jakma7514fb72007-05-02 16:05:35 +0000876#define RIB_SYSTEM_ROUTE(R) \
877 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
878
Denis Ovsienkodc958242007-08-13 16:03:06 +0000879/* This function verifies reachability of one given nexthop, which can be
880 * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
881 * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
882 * nexthop->ifindex will be updated appropriately as well.
883 * An existing route map can turn (otherwise active) nexthop into inactive, but
884 * not vice versa.
885 *
886 * The return value is the final value of 'ACTIVE' flag.
887 */
888
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300889static unsigned
paul718e3742002-12-13 20:15:29 +0000890nexthop_active_check (struct route_node *rn, struct rib *rib,
891 struct nexthop *nexthop, int set)
892{
Christian Frankef3a17322013-07-05 15:35:41 +0000893 rib_table_info_t *info = rn->table->info;
paul718e3742002-12-13 20:15:29 +0000894 struct interface *ifp;
Paul Jakma7514fb72007-05-02 16:05:35 +0000895 route_map_result_t ret = RMAP_MATCH;
896 extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
897 struct route_map *rmap;
898 int family;
paul718e3742002-12-13 20:15:29 +0000899
Paul Jakma7514fb72007-05-02 16:05:35 +0000900 family = 0;
paul718e3742002-12-13 20:15:29 +0000901 switch (nexthop->type)
902 {
903 case NEXTHOP_TYPE_IFINDEX:
Feng Lu0d0686f2015-05-22 11:40:02 +0200904 ifp = if_lookup_by_index_vrf (nexthop->ifindex, rib->vrf_id);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000905 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000906 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
907 else
908 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
909 break;
paul718e3742002-12-13 20:15:29 +0000910 case NEXTHOP_TYPE_IPV6_IFNAME:
Paul Jakma7514fb72007-05-02 16:05:35 +0000911 family = AFI_IP6;
912 case NEXTHOP_TYPE_IFNAME:
Feng Lu0d0686f2015-05-22 11:40:02 +0200913 ifp = if_lookup_by_name_vrf (nexthop->ifname, rib->vrf_id);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000914 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000915 {
916 if (set)
917 nexthop->ifindex = ifp->ifindex;
918 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
919 }
920 else
921 {
922 if (set)
923 nexthop->ifindex = 0;
924 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
925 }
926 break;
927 case NEXTHOP_TYPE_IPV4:
928 case NEXTHOP_TYPE_IPV4_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000929 family = AFI_IP;
paul718e3742002-12-13 20:15:29 +0000930 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
931 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
932 else
933 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
934 break;
paul718e3742002-12-13 20:15:29 +0000935 case NEXTHOP_TYPE_IPV6:
Paul Jakma7514fb72007-05-02 16:05:35 +0000936 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000937 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
938 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
939 else
940 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
941 break;
942 case NEXTHOP_TYPE_IPV6_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000943 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000944 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
945 {
Feng Lu0d0686f2015-05-22 11:40:02 +0200946 ifp = if_lookup_by_index_vrf (nexthop->ifindex, rib->vrf_id);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000947 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000948 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
949 else
950 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
951 }
952 else
953 {
954 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
955 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
956 else
957 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
958 }
959 break;
paul595db7f2003-05-25 21:35:06 +0000960 case NEXTHOP_TYPE_BLACKHOLE:
961 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
962 break;
paul718e3742002-12-13 20:15:29 +0000963 default:
964 break;
965 }
Paul Jakma7514fb72007-05-02 16:05:35 +0000966 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
967 return 0;
968
Christian Frankef3a17322013-07-05 15:35:41 +0000969 /* XXX: What exactly do those checks do? Do we support
970 * e.g. IPv4 routes with IPv6 nexthops or vice versa? */
Paul Jakma7514fb72007-05-02 16:05:35 +0000971 if (RIB_SYSTEM_ROUTE(rib) ||
972 (family == AFI_IP && rn->p.family != AF_INET) ||
973 (family == AFI_IP6 && rn->p.family != AF_INET6))
974 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
975
Christian Frankef3a17322013-07-05 15:35:41 +0000976 /* The original code didn't determine the family correctly
977 * e.g. for NEXTHOP_TYPE_IFINDEX. Retrieve the correct afi
978 * from the rib_table_info in those cases.
979 * Possibly it may be better to use only the rib_table_info
980 * in every case.
981 */
982 if (!family)
983 family = info->afi;
984
Paul Jakma7514fb72007-05-02 16:05:35 +0000985 rmap = 0;
986 if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
987 proto_rm[family][rib->type])
988 rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
989 if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
990 rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
991 if (rmap) {
Feng Lu1885d0a2015-05-22 11:40:04 +0200992 struct nexthop_vrfid nh_vrf = {nexthop, rib->vrf_id};
993 ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, &nh_vrf);
Paul Jakma7514fb72007-05-02 16:05:35 +0000994 }
995
996 if (ret == RMAP_DENYMATCH)
997 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
paul718e3742002-12-13 20:15:29 +0000998 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
999}
1000
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001001/* Iterate over all nexthops of the given RIB entry and refresh their
1002 * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
1003 * nexthop is found to toggle the ACTIVE flag, the whole rib structure
Timo Teräs7eb61362015-11-02 16:50:05 +02001004 * is flagged with RIB_ENTRY_CHANGED. The 4th 'set' argument is
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001005 * transparently passed to nexthop_active_check().
1006 *
1007 * Return value is the new number of active nexthops.
1008 */
1009
paula1ac18c2005-06-28 17:17:12 +00001010static int
paul718e3742002-12-13 20:15:29 +00001011nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
1012{
1013 struct nexthop *nexthop;
Paul Jakma9099f9b2016-01-18 10:12:10 +00001014 unsigned int prev_active, new_active;
1015 ifindex_t prev_index;
1016
paul718e3742002-12-13 20:15:29 +00001017 rib->nexthop_active_num = 0;
paul718e3742002-12-13 20:15:29 +00001018
1019 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001020 {
1021 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001022 prev_index = nexthop->ifindex;
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001023 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
1024 rib->nexthop_active_num++;
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001025 if (prev_active != new_active ||
1026 prev_index != nexthop->ifindex)
Timo Teräs7eb61362015-11-02 16:50:05 +02001027 SET_FLAG (rib->status, RIB_ENTRY_CHANGED);
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001028 }
paul718e3742002-12-13 20:15:29 +00001029 return rib->nexthop_active_num;
1030}
paul6baeb982003-10-28 03:47:15 +00001031
David Lamparter6b0655a2014-06-04 06:53:35 +02001032
paul718e3742002-12-13 20:15:29 +00001033
Timo Teräs0abf6792016-01-15 17:36:29 +02001034static int
1035rib_update_kernel (struct route_node *rn, struct rib *old, struct rib *new)
paul718e3742002-12-13 20:15:29 +00001036{
1037 int ret = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001038 struct nexthop *nexthop, *tnexthop;
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001039 rib_table_info_t *info = rn->table->info;
Christian Frankefa713d92013-07-05 15:35:37 +00001040 int recursing;
paul718e3742002-12-13 20:15:29 +00001041
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001042 if (info->safi != SAFI_UNICAST)
1043 {
Timo Teräs0abf6792016-01-15 17:36:29 +02001044 if (new)
1045 for (ALL_NEXTHOPS_RO(new->nexthop, nexthop, tnexthop, recursing))
1046 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1047 if (old)
1048 for (ALL_NEXTHOPS_RO(old->nexthop, nexthop, tnexthop, recursing))
1049 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1050 return 0;
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001051 }
1052
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001053 /*
1054 * Make sure we update the FPM any time we send new information to
1055 * the kernel.
1056 */
Timo Teräs0abf6792016-01-15 17:36:29 +02001057 zfpm_trigger_update (rn, "updating in kernel");
1058
1059 ret = kernel_route_rib (&rn->p, old, new);
paul718e3742002-12-13 20:15:29 +00001060
Denis Ovsienkodc958242007-08-13 16:03:06 +00001061 /* This condition is never met, if we are using rt_socket.c */
Timo Teräs0abf6792016-01-15 17:36:29 +02001062 if (ret < 0 && new)
Timo Teräs7e73eb72016-04-09 17:22:32 +03001063 {
Timo Teräs0abf6792016-01-15 17:36:29 +02001064 for (ALL_NEXTHOPS_RO(new->nexthop, nexthop, tnexthop, recursing))
1065 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
Timo Teräs7e73eb72016-04-09 17:22:32 +03001066 }
1067 else if (old && old != new)
1068 {
1069 for (ALL_NEXTHOPS_RO(old->nexthop, nexthop, tnexthop, recursing))
1070 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1071 }
paul718e3742002-12-13 20:15:29 +00001072
1073 return ret;
1074}
1075
1076/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001077static void
paul718e3742002-12-13 20:15:29 +00001078rib_uninstall (struct route_node *rn, struct rib *rib)
1079{
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001080 rib_table_info_t *info = rn->table->info;
1081
Timo Teräs325823a2016-01-15 17:36:31 +02001082 if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB))
paul718e3742002-12-13 20:15:29 +00001083 {
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001084 if (info->safi == SAFI_UNICAST)
1085 zfpm_trigger_update (rn, "rib_uninstall");
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001086
paul718e3742002-12-13 20:15:29 +00001087 redistribute_delete (&rn->p, rib);
1088 if (! RIB_SYSTEM_ROUTE (rib))
Timo Teräs0abf6792016-01-15 17:36:29 +02001089 rib_update_kernel (rn, rib, NULL);
paul718e3742002-12-13 20:15:29 +00001090 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
1091 }
1092}
1093
Paul Jakma6d691122006-07-27 21:49:00 +00001094static void rib_unlink (struct route_node *, struct rib *);
1095
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001096/*
1097 * rib_can_delete_dest
1098 *
1099 * Returns TRUE if the given dest can be deleted from the table.
1100 */
1101static int
1102rib_can_delete_dest (rib_dest_t *dest)
1103{
1104 if (dest->routes)
1105 {
1106 return 0;
1107 }
1108
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001109 /*
1110 * Don't delete the dest if we have to update the FPM about this
1111 * prefix.
1112 */
1113 if (CHECK_FLAG (dest->flags, RIB_DEST_UPDATE_FPM) ||
1114 CHECK_FLAG (dest->flags, RIB_DEST_SENT_TO_FPM))
1115 return 0;
1116
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001117 return 1;
1118}
1119
1120/*
1121 * rib_gc_dest
1122 *
1123 * Garbage collect the rib dest corresponding to the given route node
1124 * if appropriate.
1125 *
1126 * Returns TRUE if the dest was deleted, FALSE otherwise.
1127 */
1128int
1129rib_gc_dest (struct route_node *rn)
1130{
1131 rib_dest_t *dest;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001132
1133 dest = rib_dest_from_rnode (rn);
1134 if (!dest)
1135 return 0;
1136
1137 if (!rib_can_delete_dest (dest))
1138 return 0;
1139
1140 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001141 rnode_debug (rn, "removing dest from table");
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001142
1143 dest->rnode = NULL;
1144 XFREE (MTYPE_RIB_DEST, dest);
1145 rn->info = NULL;
1146
1147 /*
1148 * Release the one reference that we keep on the route node.
1149 */
1150 route_unlock_node (rn);
1151 return 1;
1152}
1153
Timo Teräs0abf6792016-01-15 17:36:29 +02001154/* Check if 'alternate' RIB entry is better than 'current'. */
1155static struct rib *
1156rib_choose_best (struct rib *current, struct rib *alternate)
1157{
1158 if (current == NULL)
1159 return alternate;
1160
1161 /* filter route selection in following order:
1162 * - connected beats other types
1163 * - lower distance beats higher
1164 * - lower metric beats higher for equal distance
1165 * - last, hence oldest, route wins tie break.
1166 */
1167
1168 /* Connected routes. Pick the last connected
1169 * route of the set of lowest metric connected routes.
1170 */
1171 if (alternate->type == ZEBRA_ROUTE_CONNECT)
1172 {
1173 if (current->type != ZEBRA_ROUTE_CONNECT
1174 || alternate->metric <= current->metric)
1175 return alternate;
1176
1177 return current;
1178 }
1179
1180 if (current->type == ZEBRA_ROUTE_CONNECT)
1181 return current;
1182
1183 /* higher distance loses */
1184 if (alternate->distance < current->distance)
1185 return alternate;
1186 if (current->distance < alternate->distance)
1187 return current;
1188
1189 /* metric tie-breaks equal distance */
1190 if (alternate->metric <= current->metric)
1191 return alternate;
1192
1193 return current;
1194}
1195
paul718e3742002-12-13 20:15:29 +00001196/* Core function for processing routing information base. */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001197static void
1198rib_process (struct route_node *rn)
paul718e3742002-12-13 20:15:29 +00001199{
1200 struct rib *rib;
1201 struct rib *next;
Timo Teräs325823a2016-01-15 17:36:31 +02001202 struct rib *old_selected = NULL;
1203 struct rib *new_selected = NULL;
Timo Teräs0abf6792016-01-15 17:36:29 +02001204 struct rib *old_fib = NULL;
1205 struct rib *new_fib = NULL;
pauld753e9e2003-01-22 19:45:50 +00001206 int installed = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001207 struct nexthop *nexthop = NULL, *tnexthop;
1208 int recursing;
Balaji95116332014-10-23 15:25:25 +00001209 rib_table_info_t *info;
1210
paul4d38fdb2005-04-28 17:35:14 +00001211 assert (rn);
Balaji95116332014-10-23 15:25:25 +00001212
1213 info = rn->table->info;
1214
Timo Teräs0abf6792016-01-15 17:36:29 +02001215 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00001216 {
Timo Teräs7e73eb72016-04-09 17:22:32 +03001217 UNSET_FLAG (rib->status, RIB_ENTRY_CHANGED);
1218
paul718e3742002-12-13 20:15:29 +00001219 /* Currently installed rib. */
1220 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Paul Jakma6d691122006-07-27 21:49:00 +00001221 {
Timo Teräs325823a2016-01-15 17:36:31 +02001222 assert (old_selected == NULL);
1223 old_selected = rib;
1224 }
1225 if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB))
1226 {
Timo Teräs0abf6792016-01-15 17:36:29 +02001227 assert (old_fib == NULL);
1228 old_fib = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001229 }
Timo Teräs0abf6792016-01-15 17:36:29 +02001230
1231 /* Skip deleted entries from selection */
Paul Jakma6d691122006-07-27 21:49:00 +00001232 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
Timo Teräs0abf6792016-01-15 17:36:29 +02001233 continue;
paul4d38fdb2005-04-28 17:35:14 +00001234
paul718e3742002-12-13 20:15:29 +00001235 /* Skip unreachable nexthop. */
1236 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +00001237 continue;
paul718e3742002-12-13 20:15:29 +00001238
1239 /* Infinit distance. */
1240 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +00001241 continue;
paul718e3742002-12-13 20:15:29 +00001242
Timo Teräs325823a2016-01-15 17:36:31 +02001243 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_FIB_OVERRIDE))
1244 new_fib = rib_choose_best(new_fib, rib);
1245 else
1246 new_selected = rib_choose_best(new_selected, rib);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001247 } /* RNODE_FOREACH_RIB_SAFE */
Denis Ovsienkodc958242007-08-13 16:03:06 +00001248
Timo Teräs325823a2016-01-15 17:36:31 +02001249 /* If no FIB override route, use the selected route also for FIB */
1250 if (new_fib == NULL)
1251 new_fib = new_selected;
1252
Denis Ovsienkodc958242007-08-13 16:03:06 +00001253 /* After the cycle is finished, the following pointers will be set:
Timo Teräs325823a2016-01-15 17:36:31 +02001254 * old_selected --- RIB entry currently having SELECTED
1255 * new_selected --- RIB entry that is newly SELECTED
1256 * old_fib --- RIB entry currently in kernel FIB
1257 * new_fib --- RIB entry that is newly to be in kernel FIB
1258 *
1259 * new_selected will get SELECTED flag, and is going to be redistributed
1260 * the zclients. new_fib (which can be new_selected) will be installed in kernel.
Denis Ovsienkodc958242007-08-13 16:03:06 +00001261 */
1262
Timo Teräs0abf6792016-01-15 17:36:29 +02001263 /* Set real nexthops. */
1264 if (new_fib)
1265 nexthop_active_update (rn, new_fib, 1);
Timo Teräs325823a2016-01-15 17:36:31 +02001266 if (new_selected && new_selected != new_fib)
Timo Teräs7e73eb72016-04-09 17:22:32 +03001267 nexthop_active_update (rn, new_selected, 1);
Timo Teräs0abf6792016-01-15 17:36:29 +02001268
1269 /* Update kernel if FIB entry has changed */
1270 if (old_fib != new_fib
1271 || (new_fib && CHECK_FLAG (new_fib->status, RIB_ENTRY_CHANGED)))
paul718e3742002-12-13 20:15:29 +00001272 {
Timo Teräs0abf6792016-01-15 17:36:29 +02001273 if (old_fib && old_fib != new_fib)
1274 {
Timo Teräs0abf6792016-01-15 17:36:29 +02001275 if (! RIB_SYSTEM_ROUTE (old_fib) && (! new_fib || RIB_SYSTEM_ROUTE (new_fib)))
1276 rib_update_kernel (rn, old_fib, NULL);
Timo Teräs325823a2016-01-15 17:36:31 +02001277 UNSET_FLAG (old_fib->status, RIB_ENTRY_SELECTED_FIB);
Timo Teräs0abf6792016-01-15 17:36:29 +02001278 }
1279
1280 if (new_fib)
1281 {
1282 /* Install new or replace existing FIB entry */
Timo Teräs325823a2016-01-15 17:36:31 +02001283 SET_FLAG (new_fib->status, RIB_ENTRY_SELECTED_FIB);
Timo Teräs0abf6792016-01-15 17:36:29 +02001284 if (! RIB_SYSTEM_ROUTE (new_fib))
1285 rib_update_kernel (rn, old_fib, new_fib);
1286 }
1287
1288 if (info->safi == SAFI_UNICAST)
1289 zfpm_trigger_update (rn, "updating existing route");
1290 }
1291 else if (old_fib == new_fib && new_fib && ! RIB_SYSTEM_ROUTE (new_fib))
1292 {
1293 /* Housekeeping code to deal with race conditions in kernel with
1294 * linux netlink reporting interface up before IPv4 or IPv6 protocol
1295 * is ready to add routes. This makes sure routes are IN the kernel.
1296 */
1297 for (ALL_NEXTHOPS_RO(new_fib->nexthop, nexthop, tnexthop, recursing))
1298 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1299 {
1300 installed = 1;
1301 break;
1302 }
1303 if (! installed)
1304 rib_update_kernel (rn, NULL, new_fib);
1305 }
1306
Timo Teräs325823a2016-01-15 17:36:31 +02001307 /* Redistribute SELECTED entry */
1308 if (old_selected != new_selected
1309 || (new_selected && CHECK_FLAG (new_selected->status, RIB_ENTRY_CHANGED)))
1310 {
1311 if (old_selected)
1312 {
1313 if (! new_selected)
1314 redistribute_delete (&rn->p, old_selected);
1315 if (old_selected != new_selected)
1316 UNSET_FLAG (old_selected->flags, ZEBRA_FLAG_SELECTED);
1317 }
1318
1319 if (new_selected)
1320 {
1321 /* Install new or replace existing redistributed entry */
1322 SET_FLAG (new_selected->flags, ZEBRA_FLAG_SELECTED);
1323 redistribute_add (&rn->p, new_selected);
1324 }
1325 }
1326
Timo Teräs0abf6792016-01-15 17:36:29 +02001327 /* Remove all RIB entries queued for removal */
1328 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
1329 {
1330 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
paul4d38fdb2005-04-28 17:35:14 +00001331 {
Timo Teräs0abf6792016-01-15 17:36:29 +02001332 if (IS_ZEBRA_DEBUG_RIB)
1333 rnode_debug (rn, "rn %p, removing rib %p",
1334 (void *)rn, (void *)rib);
1335 rib_unlink (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001336 }
paul718e3742002-12-13 20:15:29 +00001337 }
1338
Paul Jakma6d691122006-07-27 21:49:00 +00001339 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lampartereed3c482015-03-03 08:51:53 +01001340 rnode_debug (rn, "rn %p dequeued", (void *)rn);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001341
1342 /*
1343 * Check if the dest can be deleted now.
1344 */
1345 rib_gc_dest (rn);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001346}
1347
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001348/* Take a list of route_node structs and return 1, if there was a record
1349 * picked from it and processed by rib_process(). Don't process more,
1350 * than one RN record; operate only in the specified sub-queue.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001351 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001352static unsigned int
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001353process_subq (struct list * subq, u_char qindex)
1354{
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001355 struct listnode *lnode = listhead (subq);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001356 struct route_node *rnode;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001357
1358 if (!lnode)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001359 return 0;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001360
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001361 rnode = listgetdata (lnode);
1362 rib_process (rnode);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001363
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001364 if (rnode->info)
1365 UNSET_FLAG (rib_dest_from_rnode (rnode)->flags, RIB_ROUTE_QUEUED (qindex));
1366
Chris Caputo67b94672009-07-18 04:02:26 +00001367#if 0
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001368 else
1369 {
1370 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1371 __func__, rnode, rnode->lock);
1372 zlog_backtrace(LOG_DEBUG);
1373 }
Chris Caputo67b94672009-07-18 04:02:26 +00001374#endif
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001375 route_unlock_node (rnode);
1376 list_delete_node (subq, lnode);
1377 return 1;
1378}
1379
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05001380/*
1381 * All meta queues have been processed. Trigger next-hop evaluation.
1382 */
1383static void
1384meta_queue_process_complete (struct work_queue *dummy)
1385{
1386 zebra_evaluate_rnh_table(0, AF_INET);
1387#ifdef HAVE_IPV6
1388 zebra_evaluate_rnh_table(0, AF_INET6);
1389#endif /* HAVE_IPV6 */
1390}
1391
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001392/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1393 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1394 * is pointed to the meta queue structure.
1395 */
1396static wq_item_status
1397meta_queue_process (struct work_queue *dummy, void *data)
1398{
1399 struct meta_queue * mq = data;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001400 unsigned i;
1401
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001402 for (i = 0; i < MQ_SIZE; i++)
1403 if (process_subq (mq->subq[i], i))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001404 {
1405 mq->size--;
1406 break;
1407 }
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001408 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1409}
1410
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001411/*
1412 * Map from rib types to queue type (priority) in meta queue
1413 */
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001414static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
1415 [ZEBRA_ROUTE_SYSTEM] = 4,
1416 [ZEBRA_ROUTE_KERNEL] = 0,
1417 [ZEBRA_ROUTE_CONNECT] = 0,
1418 [ZEBRA_ROUTE_STATIC] = 1,
1419 [ZEBRA_ROUTE_RIP] = 2,
1420 [ZEBRA_ROUTE_RIPNG] = 2,
1421 [ZEBRA_ROUTE_OSPF] = 2,
1422 [ZEBRA_ROUTE_OSPF6] = 2,
1423 [ZEBRA_ROUTE_ISIS] = 2,
1424 [ZEBRA_ROUTE_BGP] = 3,
1425 [ZEBRA_ROUTE_HSLS] = 4,
Paul Jakma57345092011-12-25 17:52:09 +01001426 [ZEBRA_ROUTE_BABEL] = 2,
Timo Teräsdafa05e2017-01-19 17:27:01 +02001427 [ZEBRA_ROUTE_NHRP] = 2,
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001428};
1429
1430/* Look into the RN and queue it into one or more priority queues,
1431 * increasing the size for each data push done.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001432 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001433static void
1434rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001435{
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001436 struct rib *rib;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001437
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001438 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001439 {
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001440 u_char qindex = meta_queue_map[rib->type];
1441
1442 /* Invariant: at this point we always have rn->info set. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001443 if (CHECK_FLAG (rib_dest_from_rnode (rn)->flags,
1444 RIB_ROUTE_QUEUED (qindex)))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001445 {
1446 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lamparter94813742014-04-24 20:22:53 +02001447 rnode_debug (rn, "rn %p is already queued in sub-queue %u",
David Lampartereed3c482015-03-03 08:51:53 +01001448 (void *)rn, qindex);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001449 continue;
1450 }
1451
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001452 SET_FLAG (rib_dest_from_rnode (rn)->flags, RIB_ROUTE_QUEUED (qindex));
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001453 listnode_add (mq->subq[qindex], rn);
1454 route_lock_node (rn);
1455 mq->size++;
1456
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001457 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lamparter94813742014-04-24 20:22:53 +02001458 rnode_debug (rn, "queued rn %p into sub-queue %u",
David Lampartereed3c482015-03-03 08:51:53 +01001459 (void *)rn, qindex);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001460 }
paul4d38fdb2005-04-28 17:35:14 +00001461}
1462
Paul Jakma6d691122006-07-27 21:49:00 +00001463/* Add route_node to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001464static void
Paul Jakma6d691122006-07-27 21:49:00 +00001465rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
paul4d38fdb2005-04-28 17:35:14 +00001466{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001467 assert (zebra && rn);
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001468
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001469 /* Pointless to queue a route_node with no RIB entries to add or remove */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001470 if (!rnode_to_ribs (rn))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001471 {
1472 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
David Lampartereed3c482015-03-03 08:51:53 +01001473 __func__, (void *)rn, rn->lock);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001474 zlog_backtrace(LOG_DEBUG);
1475 return;
1476 }
1477
1478 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lamparter94813742014-04-24 20:22:53 +02001479 rnode_info (rn, "work queue added");
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001480
1481 assert (zebra);
1482
1483 if (zebra->ribq == NULL)
1484 {
1485 zlog_err ("%s: work_queue does not exist!", __func__);
1486 return;
Paul Jakma6d691122006-07-27 21:49:00 +00001487 }
paul4d38fdb2005-04-28 17:35:14 +00001488
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001489 /*
1490 * The RIB queue should normally be either empty or holding the only
1491 * work_queue_item element. In the latter case this element would
1492 * hold a pointer to the meta queue structure, which must be used to
1493 * actually queue the route nodes to process. So create the MQ
1494 * holder, if necessary, then push the work into it in any case.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001495 * This semantics was introduced after 0.99.9 release.
1496 */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001497 if (!zebra->ribq->items->count)
1498 work_queue_add (zebra->ribq, zebra->mq);
1499
1500 rib_meta_queue_add (zebra->mq, rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001501
1502 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lampartereed3c482015-03-03 08:51:53 +01001503 rnode_debug (rn, "rn %p queued", (void *)rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001504
1505 return;
paul4d38fdb2005-04-28 17:35:14 +00001506}
1507
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001508/* Create new meta queue.
1509 A destructor function doesn't seem to be necessary here.
1510 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001511static struct meta_queue *
1512meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001513{
1514 struct meta_queue *new;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001515 unsigned i;
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001516
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001517 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1518 assert(new);
1519
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001520 for (i = 0; i < MQ_SIZE; i++)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001521 {
1522 new->subq[i] = list_new ();
1523 assert(new->subq[i]);
1524 }
1525
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001526 return new;
1527}
1528
paul4d38fdb2005-04-28 17:35:14 +00001529/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001530static void
paul4d38fdb2005-04-28 17:35:14 +00001531rib_queue_init (struct zebra_t *zebra)
1532{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001533 assert (zebra);
1534
paul4d38fdb2005-04-28 17:35:14 +00001535 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001536 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001537 {
Paul Jakma6d691122006-07-27 21:49:00 +00001538 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001539 return;
1540 }
1541
1542 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001543 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001544 zebra->ribq->spec.errorfunc = NULL;
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05001545 zebra->ribq->spec.completion_func = &meta_queue_process_complete;
paul4d38fdb2005-04-28 17:35:14 +00001546 /* XXX: TODO: These should be runtime configurable via vty */
1547 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001548 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001549
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001550 if (!(zebra->mq = meta_queue_new ()))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001551 {
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001552 zlog_err ("%s: could not initialise meta queue!", __func__);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001553 return;
1554 }
1555 return;
paul718e3742002-12-13 20:15:29 +00001556}
1557
Paul Jakma6d691122006-07-27 21:49:00 +00001558/* RIB updates are processed via a queue of pointers to route_nodes.
1559 *
1560 * The queue length is bounded by the maximal size of the routing table,
1561 * as a route_node will not be requeued, if already queued.
1562 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001563 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05001564 * state, or static_install_route (when an existing RIB is updated)
Paul Jakma3c0755d2006-12-08 00:53:14 +00001565 * and then submit route_node to queue for best-path selection later.
1566 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001567 *
1568 * Deleted RIBs are reaped during best-path selection.
1569 *
1570 * rib_addnode
1571 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001572 * |-------->| | best RIB, if required
1573 * | |
1574 * static_install->|->rib_addqueue...... -> rib_process
1575 * | |
1576 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001577 * |-> set RIB_ENTRY_REMOVE |
1578 * rib_delnode (RIB freed)
1579 *
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001580 * The 'info' pointer of a route_node points to a rib_dest_t
1581 * ('dest'). Queueing state for a route_node is kept on the dest. The
1582 * dest is created on-demand by rib_link() and is kept around at least
1583 * as long as there are ribs hanging off it (@see rib_gc_dest()).
Paul Jakma6d691122006-07-27 21:49:00 +00001584 *
1585 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1586 *
1587 * - route_nodes: refcounted by:
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001588 * - dest attached to route_node:
1589 * - managed by: rib_link/rib_gc_dest
Paul Jakma6d691122006-07-27 21:49:00 +00001590 * - route_node processing queue
1591 * - managed by: rib_addqueue, rib_process.
1592 *
1593 */
1594
paul718e3742002-12-13 20:15:29 +00001595/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001596static void
Paul Jakma6d691122006-07-27 21:49:00 +00001597rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001598{
1599 struct rib *head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001600 rib_dest_t *dest;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001601
paul4d38fdb2005-04-28 17:35:14 +00001602 assert (rib && rn);
1603
Paul Jakma6d691122006-07-27 21:49:00 +00001604 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001605 rnode_debug (rn, "rn %p, rib %p", (void *)rn, (void *)rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001606
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001607 dest = rib_dest_from_rnode (rn);
1608 if (!dest)
Paul Jakma6d691122006-07-27 21:49:00 +00001609 {
1610 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001611 rnode_debug (rn, "adding dest to table");
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001612
1613 dest = XCALLOC (MTYPE_RIB_DEST, sizeof (rib_dest_t));
1614 route_lock_node (rn); /* rn route table reference */
1615 rn->info = dest;
1616 dest->rnode = rn;
1617 }
1618
1619 head = dest->routes;
1620 if (head)
1621 {
Paul Jakma6d691122006-07-27 21:49:00 +00001622 head->prev = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001623 }
paul718e3742002-12-13 20:15:29 +00001624 rib->next = head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001625 dest->routes = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001626 rib_queue_add (&zebrad, rn);
1627}
1628
1629static void
1630rib_addnode (struct route_node *rn, struct rib *rib)
1631{
1632 /* RIB node has been un-removed before route-node is processed.
1633 * route_node must hence already be on the queue for processing..
1634 */
1635 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1636 {
1637 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001638 rnode_debug (rn, "rn %p, un-removed rib %p", (void *)rn, (void *)rib);
David Lamparter94813742014-04-24 20:22:53 +02001639
Paul Jakma6d691122006-07-27 21:49:00 +00001640 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1641 return;
1642 }
1643 rib_link (rn, rib);
1644}
1645
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001646/*
1647 * rib_unlink
1648 *
1649 * Detach a rib structure from a route_node.
1650 *
1651 * Note that a call to rib_unlink() should be followed by a call to
1652 * rib_gc_dest() at some point. This allows a rib_dest_t that is no
1653 * longer required to be deleted.
1654 */
Paul Jakma6d691122006-07-27 21:49:00 +00001655static void
1656rib_unlink (struct route_node *rn, struct rib *rib)
1657{
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001658 rib_dest_t *dest;
Paul Jakma6d691122006-07-27 21:49:00 +00001659
1660 assert (rn && rib);
1661
1662 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001663 rnode_debug (rn, "rn %p, rib %p", (void *)rn, (void *)rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001664
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001665 dest = rib_dest_from_rnode (rn);
1666
Paul Jakma6d691122006-07-27 21:49:00 +00001667 if (rib->next)
1668 rib->next->prev = rib->prev;
1669
1670 if (rib->prev)
1671 rib->prev->next = rib->next;
1672 else
1673 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001674 dest->routes = rib->next;
Paul Jakma6d691122006-07-27 21:49:00 +00001675 }
1676
1677 /* free RIB and nexthops */
Christian Frankefa713d92013-07-05 15:35:37 +00001678 nexthops_free(rib->nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00001679 XFREE (MTYPE_RIB, rib);
1680
paul718e3742002-12-13 20:15:29 +00001681}
1682
paula1ac18c2005-06-28 17:17:12 +00001683static void
paul718e3742002-12-13 20:15:29 +00001684rib_delnode (struct route_node *rn, struct rib *rib)
1685{
Paul Jakma6d691122006-07-27 21:49:00 +00001686 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001687 rnode_debug (rn, "rn %p, rib %p, removing", (void *)rn, (void *)rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001688 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1689 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001690}
1691
1692int
1693rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001694 struct in_addr *gate, struct in_addr *src,
Paul Jakma9099f9b2016-01-18 10:12:10 +00001695 ifindex_t ifindex, vrf_id_t vrf_id, int table_id,
Timo Teräsb11f3b52015-11-02 16:50:07 +02001696 u_int32_t metric, u_int32_t mtu, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001697{
1698 struct rib *rib;
1699 struct rib *same = NULL;
1700 struct route_table *table;
1701 struct route_node *rn;
1702 struct nexthop *nexthop;
1703
1704 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02001705 table = zebra_vrf_table (AFI_IP, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00001706 if (! table)
1707 return 0;
1708
1709 /* Make it sure prefixlen is applied to the prefix. */
1710 apply_mask_ipv4 (p);
1711
1712 /* Set default distance by route type. */
1713 if (distance == 0)
1714 {
Balaji.G837d16c2012-09-26 14:09:10 +05301715 if ((unsigned)type >= array_size(route_info))
David Lamparter7052f222009-08-27 00:28:28 +02001716 distance = 150;
1717 else
1718 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00001719
1720 /* iBGP distance is 200. */
1721 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1722 distance = 200;
1723 }
1724
1725 /* Lookup route node.*/
1726 rn = route_node_get (table, (struct prefix *) p);
1727
1728 /* If same type of route are installed, treat it as a implicit
1729 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001730 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00001731 {
Paul Jakma6d691122006-07-27 21:49:00 +00001732 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1733 continue;
1734
hassoebf1ead2005-09-21 14:58:20 +00001735 if (rib->type != type)
1736 continue;
1737 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001738 {
1739 same = rib;
1740 break;
1741 }
hassoebf1ead2005-09-21 14:58:20 +00001742 /* Duplicate connected route comes in. */
1743 else if ((nexthop = rib->nexthop) &&
1744 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001745 nexthop->ifindex == ifindex &&
1746 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001747 {
1748 rib->refcnt++;
1749 return 0 ;
1750 }
paul718e3742002-12-13 20:15:29 +00001751 }
1752
1753 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001754 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001755 rib->type = type;
1756 rib->distance = distance;
1757 rib->flags = flags;
1758 rib->metric = metric;
Timo Teräsb11f3b52015-11-02 16:50:07 +02001759 rib->mtu = mtu;
Feng Lu0d0686f2015-05-22 11:40:02 +02001760 rib->vrf_id = vrf_id;
1761 rib->table = table_id;
paul718e3742002-12-13 20:15:29 +00001762 rib->nexthop_num = 0;
1763 rib->uptime = time (NULL);
1764
1765 /* Nexthop settings. */
1766 if (gate)
1767 {
1768 if (ifindex)
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05001769 rib_nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001770 else
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05001771 rib_nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001772 }
1773 else
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05001774 rib_nexthop_ifindex_add (rib, ifindex);
paul718e3742002-12-13 20:15:29 +00001775
1776 /* If this route is kernel route, set FIB flag to the route. */
1777 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1778 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1779 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1780
1781 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001782 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001783 zlog_debug ("%s: calling rib_addnode (%p, %p)",
1784 __func__, (void *)rn, (void *)rib);
paul718e3742002-12-13 20:15:29 +00001785 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001786
paul718e3742002-12-13 20:15:29 +00001787 /* Free implicit route.*/
1788 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001789 {
1790 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001791 zlog_debug ("%s: calling rib_delnode (%p, %p)",
1792 __func__, (void *)rn, (void *)rib);
paul4d38fdb2005-04-28 17:35:14 +00001793 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001794 }
paul4d38fdb2005-04-28 17:35:14 +00001795
1796 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001797 return 0;
1798}
1799
Denis Ovsienkodc958242007-08-13 16:03:06 +00001800/* This function dumps the contents of a given RIB entry into
1801 * standard debug log. Calling function name and IP prefix in
1802 * question are passed as 1st and 2nd arguments.
1803 */
1804
David Lamparterf7bf4152013-10-22 17:10:21 +00001805void _rib_dump (const char * func,
1806 union prefix46constptr pp, const struct rib * rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001807{
David Lamparterf7bf4152013-10-22 17:10:21 +00001808 const struct prefix *p = pp.p;
Timo Teräsbe6335d2015-05-23 11:08:41 +03001809 char straddr[PREFIX_STRLEN];
Christian Frankefa713d92013-07-05 15:35:37 +00001810 struct nexthop *nexthop, *tnexthop;
1811 int recursing;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001812
Feng Lu0d0686f2015-05-22 11:40:02 +02001813 zlog_debug ("%s: dumping RIB entry %p for %s vrf %u", func, (void *)rib,
1814 prefix2str(p, straddr, sizeof(straddr)), rib->vrf_id);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001815 zlog_debug
1816 (
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001817 "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
Denis Ovsienkodc958242007-08-13 16:03:06 +00001818 func,
1819 rib->refcnt,
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001820 (unsigned long) rib->uptime,
Denis Ovsienkodc958242007-08-13 16:03:06 +00001821 rib->type,
1822 rib->table
1823 );
1824 zlog_debug
1825 (
1826 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1827 func,
1828 rib->metric,
1829 rib->distance,
1830 rib->flags,
1831 rib->status
1832 );
1833 zlog_debug
1834 (
1835 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1836 func,
1837 rib->nexthop_num,
1838 rib->nexthop_active_num,
1839 rib->nexthop_fib_num
1840 );
Vincent Bernatfed643f2012-10-23 16:00:42 +00001841
Christian Frankefa713d92013-07-05 15:35:37 +00001842 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1843 {
Vincent Bernatfed643f2012-10-23 16:00:42 +00001844 inet_ntop (p->family, &nexthop->gate, straddr, INET6_ADDRSTRLEN);
Christian Frankefa713d92013-07-05 15:35:37 +00001845 zlog_debug
1846 (
1847 "%s: %s %s with flags %s%s%s",
1848 func,
1849 (recursing ? " NH" : "NH"),
1850 straddr,
1851 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1852 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1853 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1854 );
1855 }
Denis Ovsienkodc958242007-08-13 16:03:06 +00001856 zlog_debug ("%s: dump complete", func);
1857}
1858
1859/* This is an exported helper to rtm_read() to dump the strange
1860 * RIB entry found by rib_lookup_ipv4_route()
1861 */
1862
1863void rib_lookup_and_dump (struct prefix_ipv4 * p)
1864{
1865 struct route_table *table;
1866 struct route_node *rn;
1867 struct rib *rib;
1868 char prefix_buf[INET_ADDRSTRLEN];
1869
1870 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02001871 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001872 if (! table)
1873 {
Feng Lu41f44a22015-05-22 11:39:56 +02001874 zlog_err ("%s: zebra_vrf_table() returned NULL", __func__);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001875 return;
1876 }
1877
Denis Ovsienkodc958242007-08-13 16:03:06 +00001878 /* Scan the RIB table for exactly matching RIB entry. */
1879 rn = route_node_lookup (table, (struct prefix *) p);
1880
1881 /* No route for this prefix. */
1882 if (! rn)
1883 {
Timo Teräsbe6335d2015-05-23 11:08:41 +03001884 zlog_debug ("%s: lookup failed for %s", __func__,
1885 prefix2str((struct prefix*) p, prefix_buf, sizeof(prefix_buf)));
Denis Ovsienkodc958242007-08-13 16:03:06 +00001886 return;
1887 }
1888
1889 /* Unlock node. */
1890 route_unlock_node (rn);
1891
1892 /* let's go */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001893 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001894 {
1895 zlog_debug
1896 (
1897 "%s: rn %p, rib %p: %s, %s",
1898 __func__,
David Lampartereed3c482015-03-03 08:51:53 +01001899 (void *)rn,
1900 (void *)rib,
Denis Ovsienkodc958242007-08-13 16:03:06 +00001901 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
1902 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
1903 );
David Lamparterf7bf4152013-10-22 17:10:21 +00001904 rib_dump (p, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001905 }
1906}
1907
paul718e3742002-12-13 20:15:29 +00001908int
G.Balajicddf3912011-11-26 21:59:32 +04001909rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001910{
1911 struct route_table *table;
1912 struct route_node *rn;
1913 struct rib *same;
1914 struct nexthop *nexthop;
Dinesh Dutt9ae85522015-05-19 17:47:22 -07001915 int ret = 0;
paul4d38fdb2005-04-28 17:35:14 +00001916
paul718e3742002-12-13 20:15:29 +00001917 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02001918 table = zebra_vrf_table (AFI_IP, safi, rib->vrf_id);
paul718e3742002-12-13 20:15:29 +00001919 if (! table)
1920 return 0;
G.Balajicddf3912011-11-26 21:59:32 +04001921
paul718e3742002-12-13 20:15:29 +00001922 /* Make it sure prefixlen is applied to the prefix. */
1923 apply_mask_ipv4 (p);
1924
1925 /* Set default distance by route type. */
1926 if (rib->distance == 0)
1927 {
1928 rib->distance = route_info[rib->type].distance;
1929
1930 /* iBGP distance is 200. */
1931 if (rib->type == ZEBRA_ROUTE_BGP
1932 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1933 rib->distance = 200;
1934 }
1935
1936 /* Lookup route node.*/
1937 rn = route_node_get (table, (struct prefix *) p);
1938
1939 /* If same type of route are installed, treat it as a implicit
1940 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001941 RNODE_FOREACH_RIB (rn, same)
paul718e3742002-12-13 20:15:29 +00001942 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00001943 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00001944 continue;
1945
paul718e3742002-12-13 20:15:29 +00001946 if (same->type == rib->type && same->table == rib->table
1947 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001948 break;
paul718e3742002-12-13 20:15:29 +00001949 }
paul4d38fdb2005-04-28 17:35:14 +00001950
paul718e3742002-12-13 20:15:29 +00001951 /* If this route is kernel route, set FIB flag to the route. */
1952 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
1953 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1954 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1955
1956 /* Link new rib to node.*/
1957 rib_addnode (rn, rib);
Dinesh Dutt9ae85522015-05-19 17:47:22 -07001958 ret = 1;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001959 if (IS_ZEBRA_DEBUG_RIB)
1960 {
1961 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01001962 __func__, (void *)rn, (void *)rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00001963 rib_dump (p, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001964 }
paul718e3742002-12-13 20:15:29 +00001965
paul718e3742002-12-13 20:15:29 +00001966 /* Free implicit route.*/
1967 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001968 {
1969 if (IS_ZEBRA_DEBUG_RIB)
1970 {
1971 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01001972 __func__, (void *)rn, (void *)same);
David Lamparterf7bf4152013-10-22 17:10:21 +00001973 rib_dump (p, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001974 }
paul4d38fdb2005-04-28 17:35:14 +00001975 rib_delnode (rn, same);
Dinesh Dutt9ae85522015-05-19 17:47:22 -07001976 ret = -1;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001977 }
paul4d38fdb2005-04-28 17:35:14 +00001978
1979 route_unlock_node (rn);
Dinesh Dutt9ae85522015-05-19 17:47:22 -07001980 return ret;
paul718e3742002-12-13 20:15:29 +00001981}
1982
hassoebf1ead2005-09-21 14:58:20 +00001983/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00001984int
1985rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma9099f9b2016-01-18 10:12:10 +00001986 struct in_addr *gate, ifindex_t ifindex,
1987 vrf_id_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001988{
1989 struct route_table *table;
1990 struct route_node *rn;
1991 struct rib *rib;
1992 struct rib *fib = NULL;
1993 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00001994 struct nexthop *nexthop, *tnexthop;
1995 int recursing;
Timo Teräsbe6335d2015-05-23 11:08:41 +03001996 char buf1[PREFIX_STRLEN];
Stephen Hemminger81cce012009-04-28 14:28:00 -07001997 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00001998
1999 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02002000 table = zebra_vrf_table (AFI_IP, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002001 if (! table)
2002 return 0;
2003
2004 /* Apply mask. */
2005 apply_mask_ipv4 (p);
2006
Christian Frankeb52aef12013-11-27 17:06:15 +00002007 if (IS_ZEBRA_DEBUG_KERNEL)
2008 {
2009 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002010 zlog_debug ("rib_delete_ipv4(): route delete %s vrf %u via %s ifindex %d",
2011 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Christian Frankeb52aef12013-11-27 17:06:15 +00002012 inet_ntoa (*gate),
2013 ifindex);
2014 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002015 zlog_debug ("rib_delete_ipv4(): route delete %s vrf %u ifindex %d",
2016 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Christian Frankeb52aef12013-11-27 17:06:15 +00002017 ifindex);
2018 }
paul5ec90d22003-06-19 01:41:37 +00002019
paul718e3742002-12-13 20:15:29 +00002020 /* Lookup route node. */
2021 rn = route_node_lookup (table, (struct prefix *) p);
2022 if (! rn)
2023 {
2024 if (IS_ZEBRA_DEBUG_KERNEL)
2025 {
2026 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002027 zlog_debug ("route %s vrf %u via %s ifindex %d doesn't exist in rib",
2028 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002029 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002030 ifindex);
2031 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002032 zlog_debug ("route %s vrf %u ifindex %d doesn't exist in rib",
2033 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002034 ifindex);
2035 }
2036 return ZEBRA_ERR_RTNOEXIST;
2037 }
2038
2039 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002040 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002041 {
Paul Jakma6d691122006-07-27 21:49:00 +00002042 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2043 continue;
2044
Timo Teräs325823a2016-01-15 17:36:31 +02002045 if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB))
paul718e3742002-12-13 20:15:29 +00002046 fib = rib;
2047
hassoebf1ead2005-09-21 14:58:20 +00002048 if (rib->type != type)
2049 continue;
2050 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002051 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002052 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002053 if (nexthop->ifindex != ifindex)
2054 continue;
hassoebf1ead2005-09-21 14:58:20 +00002055 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002056 {
hassoebf1ead2005-09-21 14:58:20 +00002057 rib->refcnt--;
2058 route_unlock_node (rn);
2059 route_unlock_node (rn);
2060 return 0;
paul718e3742002-12-13 20:15:29 +00002061 }
hassoebf1ead2005-09-21 14:58:20 +00002062 same = rib;
2063 break;
paul718e3742002-12-13 20:15:29 +00002064 }
hassoebf1ead2005-09-21 14:58:20 +00002065 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002066 else
paul5ec90d22003-06-19 01:41:37 +00002067 {
Christian Frankefa713d92013-07-05 15:35:37 +00002068 if (gate == NULL)
2069 {
2070 same = rib;
2071 break;
2072 }
2073 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2074 if (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate))
2075 {
2076 same = rib;
2077 break;
2078 }
2079 if (same)
2080 break;
2081 }
paul718e3742002-12-13 20:15:29 +00002082 }
paul718e3742002-12-13 20:15:29 +00002083 /* If same type of route can't be found and this message is from
2084 kernel. */
2085 if (! same)
2086 {
James Li92992c62015-11-09 20:21:57 -05002087 if (fib && type == ZEBRA_ROUTE_KERNEL &&
2088 CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE))
2089 {
2090 if (IS_ZEBRA_DEBUG_KERNEL)
2091 {
2092 zlog_debug ("Zebra route %s/%d was deleted by others from kernel",
2093 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
2094 p->prefixlen);
2095 }
2096 /* This means someone else, other than Zebra, has deleted
2097 * a Zebra router from the kernel. We will add it back */
2098 rib_update_kernel(rn, NULL, fib);
2099 }
paul718e3742002-12-13 20:15:29 +00002100 else
2101 {
2102 if (IS_ZEBRA_DEBUG_KERNEL)
2103 {
2104 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002105 zlog_debug ("route %s vrf %u via %s ifindex %d type %d "
2106 "doesn't exist in rib",
2107 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002108 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002109 ifindex,
2110 type);
2111 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002112 zlog_debug ("route %s vrf %u ifindex %d type %d doesn't exist in rib",
2113 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002114 ifindex,
2115 type);
2116 }
2117 route_unlock_node (rn);
2118 return ZEBRA_ERR_RTNOEXIST;
2119 }
2120 }
paul4d38fdb2005-04-28 17:35:14 +00002121
paul718e3742002-12-13 20:15:29 +00002122 if (same)
2123 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002124
paul718e3742002-12-13 20:15:29 +00002125 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002126 return 0;
2127}
David Lamparter6b0655a2014-06-04 06:53:35 +02002128
paul718e3742002-12-13 20:15:29 +00002129/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002130static void
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002131static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si)
paul718e3742002-12-13 20:15:29 +00002132{
2133 struct rib *rib;
2134 struct route_node *rn;
2135 struct route_table *table;
2136
2137 /* Lookup table. */
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002138 table = zebra_vrf_table (afi, safi, si->vrf_id);
paul718e3742002-12-13 20:15:29 +00002139 if (! table)
2140 return;
2141
2142 /* Lookup existing route */
2143 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002144 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002145 {
2146 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2147 continue;
2148
2149 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2150 break;
2151 }
paul718e3742002-12-13 20:15:29 +00002152
2153 if (rib)
2154 {
Piotr Chytłade24f822007-06-28 00:09:28 +02002155 /* if tag value changed , update old value in RIB */
2156 if (rib->tag != si->tag)
2157 rib->tag = si->tag;
2158
paul718e3742002-12-13 20:15:29 +00002159 /* Same distance static route is there. Update it with new
2160 nexthop. */
paul718e3742002-12-13 20:15:29 +00002161 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002162 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002163 {
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002164 case STATIC_IPV4_GATEWAY:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002165 rib_nexthop_ipv4_add (rib, &si->addr.ipv4, NULL);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002166 break;
2167 case STATIC_IPV4_IFNAME:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002168 rib_nexthop_ifname_add (rib, si->ifname);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002169 break;
2170 case STATIC_IPV4_BLACKHOLE:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002171 rib_nexthop_blackhole_add (rib);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002172 break;
2173 case STATIC_IPV6_GATEWAY:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002174 rib_nexthop_ipv6_add (rib, &si->addr.ipv6);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002175 break;
2176 case STATIC_IPV6_IFNAME:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002177 rib_nexthop_ifname_add (rib, si->ifname);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002178 break;
2179 case STATIC_IPV6_GATEWAY_IFNAME:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002180 rib_nexthop_ipv6_ifname_add (rib, &si->addr.ipv6, si->ifname);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002181 break;
paul4d38fdb2005-04-28 17:35:14 +00002182 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002183 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002184 }
2185 else
2186 {
2187 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002188 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2189
paul718e3742002-12-13 20:15:29 +00002190 rib->type = ZEBRA_ROUTE_STATIC;
2191 rib->distance = si->distance;
2192 rib->metric = 0;
Feng Lu7aaf4ea2015-05-22 11:40:06 +02002193 rib->vrf_id = si->vrf_id;
Nolan Leakeb0145dd2012-09-13 17:17:31 +00002194 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002195 rib->nexthop_num = 0;
Piotr Chytłade24f822007-06-28 00:09:28 +02002196 rib->tag = si->tag;
paul718e3742002-12-13 20:15:29 +00002197
2198 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002199 {
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002200 case STATIC_IPV4_GATEWAY:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002201 rib_nexthop_ipv4_add (rib, &si->addr.ipv4, NULL);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002202 break;
2203 case STATIC_IPV4_IFNAME:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002204 rib_nexthop_ifname_add (rib, si->ifname);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002205 break;
2206 case STATIC_IPV4_BLACKHOLE:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002207 rib_nexthop_blackhole_add (rib);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002208 break;
2209 case STATIC_IPV6_GATEWAY:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002210 rib_nexthop_ipv6_add (rib, &si->addr.ipv6);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002211 break;
2212 case STATIC_IPV6_IFNAME:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002213 rib_nexthop_ifname_add (rib, si->ifname);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002214 break;
2215 case STATIC_IPV6_GATEWAY_IFNAME:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002216 rib_nexthop_ipv6_ifname_add (rib, &si->addr.ipv6, si->ifname);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002217 break;
paul7021c422003-07-15 12:52:22 +00002218 }
paul718e3742002-12-13 20:15:29 +00002219
hasso81dfcaa2003-05-25 19:21:25 +00002220 /* Save the flags of this static routes (reject, blackhole) */
2221 rib->flags = si->flags;
2222
paul718e3742002-12-13 20:15:29 +00002223 /* Link this rib to the tree. */
2224 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002225 }
2226}
2227
paula1ac18c2005-06-28 17:17:12 +00002228static int
Donald Sharpa979ab72015-11-04 13:26:38 -05002229static_nexthop_same (struct nexthop *nexthop, struct static_route *si)
paul718e3742002-12-13 20:15:29 +00002230{
2231 if (nexthop->type == NEXTHOP_TYPE_IPV4
2232 && si->type == STATIC_IPV4_GATEWAY
Donald Sharpd4c27d62015-11-04 13:26:35 -05002233 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->addr.ipv4))
paul718e3742002-12-13 20:15:29 +00002234 return 1;
2235 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2236 && si->type == STATIC_IPV4_IFNAME
Donald Sharpd4c27d62015-11-04 13:26:35 -05002237 && strcmp (nexthop->ifname, si->ifname) == 0)
paul718e3742002-12-13 20:15:29 +00002238 return 1;
paul595db7f2003-05-25 21:35:06 +00002239 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2240 && si->type == STATIC_IPV4_BLACKHOLE)
2241 return 1;
Donald Sharpa979ab72015-11-04 13:26:38 -05002242 if (nexthop->type == NEXTHOP_TYPE_IPV6
2243 && si->type == STATIC_IPV6_GATEWAY
2244 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6))
2245 return 1;
2246 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2247 && si->type == STATIC_IPV6_IFNAME
2248 && strcmp (nexthop->ifname, si->ifname) == 0)
2249 return 1;
2250 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2251 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2252 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6)
2253 && strcmp (nexthop->ifname, si->ifname) == 0)
2254 return 1;
paule8e19462006-01-19 20:16:55 +00002255 return 0;
paul718e3742002-12-13 20:15:29 +00002256}
2257
2258/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002259static void
Donald Sharp949b7192015-11-04 13:26:39 -05002260static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si)
paul718e3742002-12-13 20:15:29 +00002261{
2262 struct route_node *rn;
2263 struct rib *rib;
2264 struct nexthop *nexthop;
2265 struct route_table *table;
2266
2267 /* Lookup table. */
Donald Sharp949b7192015-11-04 13:26:39 -05002268 table = zebra_vrf_table (afi, safi, si->vrf_id);
paul718e3742002-12-13 20:15:29 +00002269 if (! table)
2270 return;
paul4d38fdb2005-04-28 17:35:14 +00002271
paul718e3742002-12-13 20:15:29 +00002272 /* Lookup existing route with type and distance. */
2273 rn = route_node_lookup (table, p);
2274 if (! rn)
2275 return;
2276
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002277 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002278 {
2279 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2280 continue;
2281
Piotr Chytłade24f822007-06-28 00:09:28 +02002282 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance &&
2283 rib->tag == si->tag)
Paul Jakma6d691122006-07-27 21:49:00 +00002284 break;
2285 }
paul718e3742002-12-13 20:15:29 +00002286
2287 if (! rib)
2288 {
2289 route_unlock_node (rn);
2290 return;
2291 }
2292
2293 /* Lookup nexthop. */
2294 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Donald Sharpa979ab72015-11-04 13:26:38 -05002295 if (static_nexthop_same (nexthop, si))
paul718e3742002-12-13 20:15:29 +00002296 break;
2297
2298 /* Can't find nexthop. */
2299 if (! nexthop)
2300 {
2301 route_unlock_node (rn);
2302 return;
2303 }
2304
2305 /* Check nexthop. */
2306 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002307 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002308 else
2309 {
paul6baeb982003-10-28 03:47:15 +00002310 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2311 rib_uninstall (rn, rib);
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002312 rib_nexthop_delete (rib, nexthop);
paul319572c2005-09-21 12:30:08 +00002313 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002314 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002315 }
paul718e3742002-12-13 20:15:29 +00002316 /* Unlock node. */
2317 route_unlock_node (rn);
2318}
2319
paul718e3742002-12-13 20:15:29 +00002320int
Everton Marques33d86db2014-07-14 11:19:00 -03002321static_add_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate,
Paul Jakma96d10602016-07-01 14:23:45 +01002322 const char *ifname, u_char flags, route_tag_t tag,
2323 u_char distance, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002324{
2325 u_char type = 0;
2326 struct route_node *rn;
Donald Sharpd4c27d62015-11-04 13:26:35 -05002327 struct static_route *si;
2328 struct static_route *pp;
2329 struct static_route *cp;
2330 struct static_route *update = NULL;
Feng Lu0d0686f2015-05-22 11:40:02 +02002331 struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
2332 struct route_table *stable = zvrf->stable[AFI_IP][safi];
paul718e3742002-12-13 20:15:29 +00002333
paul718e3742002-12-13 20:15:29 +00002334 if (! stable)
2335 return -1;
2336
2337 /* Lookup static route prefix. */
2338 rn = route_node_get (stable, p);
2339
2340 /* Make flags. */
2341 if (gate)
2342 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002343 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002344 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002345 else
2346 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002347
2348 /* Do nothing if there is a same static route. */
2349 for (si = rn->info; si; si = si->next)
2350 {
2351 if (type == si->type
Donald Sharpd4c27d62015-11-04 13:26:35 -05002352 && (! gate || IPV4_ADDR_SAME (gate, &si->addr.ipv4))
2353 && (! ifname || strcmp (ifname, si->ifname) == 0))
paul718e3742002-12-13 20:15:29 +00002354 {
Piotr Chytłade24f822007-06-28 00:09:28 +02002355 if (distance == si->distance &&
2356 tag == si->tag)
paul718e3742002-12-13 20:15:29 +00002357 {
2358 route_unlock_node (rn);
2359 return 0;
2360 }
2361 else
2362 update = si;
2363 }
2364 }
2365
Piotr Chytłade24f822007-06-28 00:09:28 +02002366 /* Distance or tag changed. */
paul718e3742002-12-13 20:15:29 +00002367 if (update)
Piotr Chytłade24f822007-06-28 00:09:28 +02002368 static_delete_ipv4_safi (safi, p, gate, ifname, update->tag, update->distance, vrf_id);
paul718e3742002-12-13 20:15:29 +00002369
2370 /* Make new static route structure. */
Donald Sharpd4c27d62015-11-04 13:26:35 -05002371 si = XCALLOC (MTYPE_STATIC_ROUTE, sizeof (struct static_route));
paul718e3742002-12-13 20:15:29 +00002372
2373 si->type = type;
2374 si->distance = distance;
Piotr Chytłade24f822007-06-28 00:09:28 +02002375 si->tag = tag;
hasso81dfcaa2003-05-25 19:21:25 +00002376 si->flags = flags;
Feng Lu7aaf4ea2015-05-22 11:40:06 +02002377 si->vrf_id = vrf_id;
paul718e3742002-12-13 20:15:29 +00002378
2379 if (gate)
Donald Sharpd4c27d62015-11-04 13:26:35 -05002380 si->addr.ipv4 = *gate;
paul718e3742002-12-13 20:15:29 +00002381 if (ifname)
David Lamparter23757db2016-02-24 06:26:02 +01002382 si->ifname = XSTRDUP (MTYPE_TMP, ifname);
paul718e3742002-12-13 20:15:29 +00002383
2384 /* Add new static route information to the tree with sort by
2385 distance value and gateway address. */
2386 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2387 {
2388 if (si->distance < cp->distance)
2389 break;
2390 if (si->distance > cp->distance)
2391 continue;
2392 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2393 {
Donald Sharpd4c27d62015-11-04 13:26:35 -05002394 if (ntohl (si->addr.ipv4.s_addr) < ntohl (cp->addr.ipv4.s_addr))
paul718e3742002-12-13 20:15:29 +00002395 break;
Donald Sharpd4c27d62015-11-04 13:26:35 -05002396 if (ntohl (si->addr.ipv4.s_addr) > ntohl (cp->addr.ipv4.s_addr))
paul718e3742002-12-13 20:15:29 +00002397 continue;
2398 }
2399 }
2400
2401 /* Make linked list. */
2402 if (pp)
2403 pp->next = si;
2404 else
2405 rn->info = si;
2406 if (cp)
2407 cp->prev = si;
2408 si->prev = pp;
2409 si->next = cp;
2410
2411 /* Install into rib. */
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002412 static_install_route (AFI_IP, safi, p, si);
paul718e3742002-12-13 20:15:29 +00002413
2414 return 1;
2415}
2416
paul718e3742002-12-13 20:15:29 +00002417int
Everton Marques33d86db2014-07-14 11:19:00 -03002418static_delete_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate,
Paul Jakma96d10602016-07-01 14:23:45 +01002419 const char *ifname, route_tag_t tag, u_char distance,
2420 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002421{
2422 u_char type = 0;
2423 struct route_node *rn;
Donald Sharpd4c27d62015-11-04 13:26:35 -05002424 struct static_route *si;
paul718e3742002-12-13 20:15:29 +00002425 struct route_table *stable;
2426
2427 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02002428 stable = zebra_vrf_static_table (AFI_IP, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002429 if (! stable)
2430 return -1;
2431
2432 /* Lookup static route prefix. */
2433 rn = route_node_lookup (stable, p);
2434 if (! rn)
2435 return 0;
2436
2437 /* Make flags. */
2438 if (gate)
2439 type = STATIC_IPV4_GATEWAY;
2440 else if (ifname)
2441 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002442 else
2443 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002444
2445 /* Find same static route is the tree */
2446 for (si = rn->info; si; si = si->next)
2447 if (type == si->type
Donald Sharpd4c27d62015-11-04 13:26:35 -05002448 && (! gate || IPV4_ADDR_SAME (gate, &si->addr.ipv4))
Piotr Chytłade24f822007-06-28 00:09:28 +02002449 && (! ifname || strcmp (ifname, si->ifname) == 0)
2450 && (! tag || (tag == si->tag)))
paul718e3742002-12-13 20:15:29 +00002451 break;
2452
2453 /* Can't find static route. */
2454 if (! si)
2455 {
2456 route_unlock_node (rn);
2457 return 0;
2458 }
2459
2460 /* Install into rib. */
Donald Sharp949b7192015-11-04 13:26:39 -05002461 static_uninstall_route (AFI_IP, safi, p, si);
paul718e3742002-12-13 20:15:29 +00002462
2463 /* Unlink static route from linked list. */
2464 if (si->prev)
2465 si->prev->next = si->next;
2466 else
2467 rn->info = si->next;
2468 if (si->next)
2469 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002470 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002471
2472 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002473 if (ifname)
Donald Sharpd4c27d62015-11-04 13:26:35 -05002474 XFREE (0, si->ifname);
2475 XFREE (MTYPE_STATIC_ROUTE, si);
paul718e3742002-12-13 20:15:29 +00002476
paul143a3852003-09-29 20:06:13 +00002477 route_unlock_node (rn);
2478
paul718e3742002-12-13 20:15:29 +00002479 return 1;
2480}
2481
paul718e3742002-12-13 20:15:29 +00002482int
2483rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
Paul Jakma9099f9b2016-01-18 10:12:10 +00002484 struct in6_addr *gate, ifindex_t ifindex,
Feng Lu0d0686f2015-05-22 11:40:02 +02002485 vrf_id_t vrf_id, int table_id,
Timo Teräsb11f3b52015-11-02 16:50:07 +02002486 u_int32_t metric, u_int32_t mtu, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002487{
2488 struct rib *rib;
2489 struct rib *same = NULL;
2490 struct route_table *table;
2491 struct route_node *rn;
2492 struct nexthop *nexthop;
2493
paul718e3742002-12-13 20:15:29 +00002494 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02002495 table = zebra_vrf_table (AFI_IP6, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002496 if (! table)
2497 return 0;
2498
2499 /* Make sure mask is applied. */
2500 apply_mask_ipv6 (p);
2501
2502 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002503 if (!distance)
2504 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002505
2506 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2507 distance = 200;
2508
paul718e3742002-12-13 20:15:29 +00002509 /* Lookup route node.*/
2510 rn = route_node_get (table, (struct prefix *) p);
2511
2512 /* If same type of route are installed, treat it as a implicit
2513 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002514 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002515 {
Paul Jakma6d691122006-07-27 21:49:00 +00002516 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2517 continue;
2518
hassoebf1ead2005-09-21 14:58:20 +00002519 if (rib->type != type)
2520 continue;
2521 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002522 {
2523 same = rib;
paul718e3742002-12-13 20:15:29 +00002524 break;
2525 }
hassoebf1ead2005-09-21 14:58:20 +00002526 else if ((nexthop = rib->nexthop) &&
2527 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2528 nexthop->ifindex == ifindex)
2529 {
2530 rib->refcnt++;
2531 return 0;
2532 }
paul718e3742002-12-13 20:15:29 +00002533 }
2534
2535 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002536 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2537
paul718e3742002-12-13 20:15:29 +00002538 rib->type = type;
2539 rib->distance = distance;
2540 rib->flags = flags;
2541 rib->metric = metric;
Timo Teräsb11f3b52015-11-02 16:50:07 +02002542 rib->mtu = mtu;
Feng Lu0d0686f2015-05-22 11:40:02 +02002543 rib->vrf_id = vrf_id;
2544 rib->table = table_id;
paul718e3742002-12-13 20:15:29 +00002545 rib->nexthop_num = 0;
2546 rib->uptime = time (NULL);
2547
2548 /* Nexthop settings. */
2549 if (gate)
2550 {
2551 if (ifindex)
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002552 rib_nexthop_ipv6_ifindex_add (rib, gate, ifindex);
paul718e3742002-12-13 20:15:29 +00002553 else
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002554 rib_nexthop_ipv6_add (rib, gate);
paul718e3742002-12-13 20:15:29 +00002555 }
2556 else
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002557 rib_nexthop_ifindex_add (rib, ifindex);
paul718e3742002-12-13 20:15:29 +00002558
2559 /* If this route is kernel route, set FIB flag to the route. */
2560 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2561 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2562 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2563
2564 /* Link new rib to node.*/
2565 rib_addnode (rn, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002566 if (IS_ZEBRA_DEBUG_RIB)
2567 {
2568 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01002569 __func__, (void *)rn, (void *)rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00002570 rib_dump (p, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002571 }
paul718e3742002-12-13 20:15:29 +00002572
paul718e3742002-12-13 20:15:29 +00002573 /* Free implicit route.*/
2574 if (same)
Vincent Bernatfed643f2012-10-23 16:00:42 +00002575 {
2576 if (IS_ZEBRA_DEBUG_RIB)
2577 {
2578 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01002579 __func__, (void *)rn, (void *)same);
David Lamparterf7bf4152013-10-22 17:10:21 +00002580 rib_dump (p, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002581 }
paul4d38fdb2005-04-28 17:35:14 +00002582 rib_delnode (rn, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002583 }
paul4d38fdb2005-04-28 17:35:14 +00002584
2585 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002586 return 0;
2587}
2588
Ayan Banerjee34c5d892015-11-09 20:14:53 -05002589int
2590rib_add_ipv6_multipath (struct prefix_ipv6 *p, struct rib *rib, safi_t safi)
2591{
2592 struct route_table *table;
2593 struct route_node *rn;
2594 struct rib *same = NULL;
2595 struct nexthop *nexthop;
2596 int ret = 0;
2597
2598 if (!rib)
2599 return 0; /* why are we getting called with NULL rib */
2600
2601 /* Lookup table. */
2602 table = zebra_vrf_table (AFI_IP6, safi, rib->vrf_id);
2603
2604 if (! table)
2605 return 0;
2606
2607 /* Make sure mask is applied. */
2608 apply_mask_ipv6 (p);
2609
2610 /* Set default distance by route type. */
2611 if (rib->distance == 0)
2612 {
2613 rib->distance = route_info[rib->type].distance;
2614
2615 /* iBGP distance is 200. */
2616 if (rib->type == ZEBRA_ROUTE_BGP
2617 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
2618 rib->distance = 200;
2619 }
2620
2621 /* Lookup route node.*/
2622 rn = route_node_get (table, (struct prefix *) p);
2623
2624 /* If same type of route are installed, treat it as a implicit
2625 withdraw. */
2626 RNODE_FOREACH_RIB (rn, same) {
2627 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED)) {
2628 continue;
2629 }
2630 if (same->type != rib->type) {
2631 continue;
2632 }
2633
2634 if (same->table != rib->table) {
2635 continue;
2636 }
2637 if (same->type != ZEBRA_ROUTE_CONNECT) {
2638 break;
2639 }
2640 }
2641
2642 /* If this route is kernel route, set FIB flag to the route. */
2643 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT) {
2644 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) {
2645 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2646 }
2647 }
2648
2649 /* Link new rib to node.*/
2650 rib_addnode (rn, rib);
2651 ret = 1;
2652 /* Free implicit route.*/
2653 if (same)
2654 {
2655 if (IS_ZEBRA_DEBUG_RIB)
2656 {
2657 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
2658 __func__, rn, same);
2659 rib_dump ((struct prefix *)p, same);
2660 }
2661 rib_delnode (rn, same);
2662 ret = -1;
2663 }
2664
2665 route_unlock_node (rn);
2666 return ret;
2667}
2668
hassoebf1ead2005-09-21 14:58:20 +00002669/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002670int
2671rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
Paul Jakma9099f9b2016-01-18 10:12:10 +00002672 struct in6_addr *gate, ifindex_t ifindex,
2673 vrf_id_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002674{
2675 struct route_table *table;
2676 struct route_node *rn;
2677 struct rib *rib;
2678 struct rib *fib = NULL;
2679 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002680 struct nexthop *nexthop, *tnexthop;
2681 int recursing;
Timo Teräsbe6335d2015-05-23 11:08:41 +03002682 char buf1[PREFIX_STRLEN];
Stephen Hemminger81cce012009-04-28 14:28:00 -07002683 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002684
2685 /* Apply mask. */
2686 apply_mask_ipv6 (p);
2687
2688 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02002689 table = zebra_vrf_table (AFI_IP6, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002690 if (! table)
2691 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002692
paul718e3742002-12-13 20:15:29 +00002693 /* Lookup route node. */
2694 rn = route_node_lookup (table, (struct prefix *) p);
2695 if (! rn)
2696 {
2697 if (IS_ZEBRA_DEBUG_KERNEL)
2698 {
2699 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002700 zlog_debug ("route %s vrf %u via %s ifindex %d doesn't exist in rib",
2701 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002702 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002703 ifindex);
2704 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002705 zlog_debug ("route %s vrf %u ifindex %d doesn't exist in rib",
2706 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002707 ifindex);
2708 }
2709 return ZEBRA_ERR_RTNOEXIST;
2710 }
2711
2712 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002713 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002714 {
Paul Jakma6d691122006-07-27 21:49:00 +00002715 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2716 continue;
2717
Timo Teräs325823a2016-01-15 17:36:31 +02002718 if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB))
paul718e3742002-12-13 20:15:29 +00002719 fib = rib;
2720
hassoebf1ead2005-09-21 14:58:20 +00002721 if (rib->type != type)
2722 continue;
2723 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002724 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002725 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002726 if (nexthop->ifindex != ifindex)
2727 continue;
hassoebf1ead2005-09-21 14:58:20 +00002728 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002729 {
hassoebf1ead2005-09-21 14:58:20 +00002730 rib->refcnt--;
2731 route_unlock_node (rn);
2732 route_unlock_node (rn);
2733 return 0;
paul718e3742002-12-13 20:15:29 +00002734 }
hassoebf1ead2005-09-21 14:58:20 +00002735 same = rib;
2736 break;
paul718e3742002-12-13 20:15:29 +00002737 }
hassoebf1ead2005-09-21 14:58:20 +00002738 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002739 else
2740 {
2741 if (gate == NULL)
2742 {
2743 same = rib;
2744 break;
2745 }
2746 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2747 if (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate))
2748 {
2749 same = rib;
2750 break;
2751 }
2752 if (same)
2753 break;
2754 }
paul718e3742002-12-13 20:15:29 +00002755 }
2756
2757 /* If same type of route can't be found and this message is from
2758 kernel. */
2759 if (! same)
2760 {
James Li92992c62015-11-09 20:21:57 -05002761 if (fib && type == ZEBRA_ROUTE_KERNEL &&
2762 CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE))
2763 {
2764 if (IS_ZEBRA_DEBUG_KERNEL)
2765 {
2766 zlog_debug ("Zebra route %s/%d was deleted by others from kernel",
2767 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
2768 p->prefixlen);
2769 }
2770 /* This means someone else, other than Zebra, has deleted a Zebra
2771 * route from the kernel. We will add it back */
2772 rib_update_kernel(rn, NULL, fib);
2773 }
paul718e3742002-12-13 20:15:29 +00002774 else
2775 {
2776 if (IS_ZEBRA_DEBUG_KERNEL)
2777 {
2778 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002779 zlog_debug ("route %s vrf %u via %s ifindex %d type %d "
2780 "doesn't exist in rib",
2781 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002782 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002783 ifindex,
2784 type);
2785 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002786 zlog_debug ("route %s vrf %u ifindex %d type %d doesn't exist in rib",
2787 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002788 ifindex,
2789 type);
2790 }
2791 route_unlock_node (rn);
2792 return ZEBRA_ERR_RTNOEXIST;
2793 }
2794 }
2795
2796 if (same)
2797 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002798
paul718e3742002-12-13 20:15:29 +00002799 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002800 return 0;
2801}
David Lamparter6b0655a2014-06-04 06:53:35 +02002802
paul718e3742002-12-13 20:15:29 +00002803/* Add static route into static route configuration. */
2804int
2805static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
Paul Jakma96d10602016-07-01 14:23:45 +01002806 const char *ifname, u_char flags, route_tag_t tag,
Piotr Chytłade24f822007-06-28 00:09:28 +02002807 u_char distance, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002808{
2809 struct route_node *rn;
Donald Sharpd4c27d62015-11-04 13:26:35 -05002810 struct static_route *si;
2811 struct static_route *pp;
2812 struct static_route *cp;
Donald Sharpc1900e02015-11-04 13:26:40 -05002813 struct static_route *update = NULL;
Feng Lu0d0686f2015-05-22 11:40:02 +02002814 struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
2815 struct route_table *stable = zvrf->stable[AFI_IP6][SAFI_UNICAST];
paul718e3742002-12-13 20:15:29 +00002816
paul718e3742002-12-13 20:15:29 +00002817 if (! stable)
2818 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00002819
2820 if (!gate &&
2821 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
2822 return -1;
2823
2824 if (!ifname &&
2825 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
2826 return -1;
paul718e3742002-12-13 20:15:29 +00002827
2828 /* Lookup static route prefix. */
2829 rn = route_node_get (stable, p);
2830
2831 /* Do nothing if there is a same static route. */
2832 for (si = rn->info; si; si = si->next)
2833 {
Donald Sharpc1900e02015-11-04 13:26:40 -05002834 if (type == si->type
Piotr Chytłade24f822007-06-28 00:09:28 +02002835 && tag == si->tag
Donald Sharpd4c27d62015-11-04 13:26:35 -05002836 && (! gate || IPV6_ADDR_SAME (gate, &si->addr.ipv6))
paul718e3742002-12-13 20:15:29 +00002837 && (! ifname || strcmp (ifname, si->ifname) == 0))
2838 {
Donald Sharpc1900e02015-11-04 13:26:40 -05002839 if (distance == si->distance)
2840 {
2841 route_unlock_node (rn);
2842 return 0;
2843 }
2844 else
2845 update = si;
paul718e3742002-12-13 20:15:29 +00002846 }
2847 }
2848
Donald Sharpc1900e02015-11-04 13:26:40 -05002849 if (update)
Christian Franke68cfaab2016-06-06 21:10:24 +02002850 static_delete_ipv6(p, type, gate, ifname, tag, update->distance, vrf_id);
Donald Sharpc1900e02015-11-04 13:26:40 -05002851
paul718e3742002-12-13 20:15:29 +00002852 /* Make new static route structure. */
Donald Sharpd4c27d62015-11-04 13:26:35 -05002853 si = XCALLOC (MTYPE_STATIC_ROUTE, sizeof (struct static_route));
paul718e3742002-12-13 20:15:29 +00002854
2855 si->type = type;
2856 si->distance = distance;
Piotr Chytłade24f822007-06-28 00:09:28 +02002857 si->tag = tag;
hasso81dfcaa2003-05-25 19:21:25 +00002858 si->flags = flags;
Feng Lu7aaf4ea2015-05-22 11:40:06 +02002859 si->vrf_id = vrf_id;
paul718e3742002-12-13 20:15:29 +00002860
2861 switch (type)
2862 {
2863 case STATIC_IPV6_GATEWAY:
Donald Sharpd4c27d62015-11-04 13:26:35 -05002864 si->addr.ipv6 = *gate;
paul718e3742002-12-13 20:15:29 +00002865 break;
2866 case STATIC_IPV6_IFNAME:
David Lamparter23757db2016-02-24 06:26:02 +01002867 si->ifname = XSTRDUP (MTYPE_TMP, ifname);
paul718e3742002-12-13 20:15:29 +00002868 break;
2869 case STATIC_IPV6_GATEWAY_IFNAME:
Donald Sharpd4c27d62015-11-04 13:26:35 -05002870 si->addr.ipv6 = *gate;
David Lamparter23757db2016-02-24 06:26:02 +01002871 si->ifname = XSTRDUP (MTYPE_TMP, ifname);
paul718e3742002-12-13 20:15:29 +00002872 break;
2873 }
2874
2875 /* Add new static route information to the tree with sort by
2876 distance value and gateway address. */
2877 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2878 {
2879 if (si->distance < cp->distance)
2880 break;
2881 if (si->distance > cp->distance)
2882 continue;
2883 }
2884
2885 /* Make linked list. */
2886 if (pp)
2887 pp->next = si;
2888 else
2889 rn->info = si;
2890 if (cp)
2891 cp->prev = si;
2892 si->prev = pp;
2893 si->next = cp;
2894
2895 /* Install into rib. */
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002896 static_install_route (AFI_IP6, SAFI_UNICAST, p, si);
paul718e3742002-12-13 20:15:29 +00002897
2898 return 1;
2899}
2900
2901/* Delete static route from static route configuration. */
2902int
2903static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
Paul Jakma96d10602016-07-01 14:23:45 +01002904 const char *ifname, route_tag_t tag, u_char distance,
2905 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002906{
2907 struct route_node *rn;
Donald Sharpd4c27d62015-11-04 13:26:35 -05002908 struct static_route *si;
paul718e3742002-12-13 20:15:29 +00002909 struct route_table *stable;
2910
2911 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02002912 stable = zebra_vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +00002913 if (! stable)
2914 return -1;
2915
2916 /* Lookup static route prefix. */
2917 rn = route_node_lookup (stable, p);
2918 if (! rn)
2919 return 0;
2920
2921 /* Find same static route is the tree */
2922 for (si = rn->info; si; si = si->next)
2923 if (distance == si->distance
2924 && type == si->type
Donald Sharpd4c27d62015-11-04 13:26:35 -05002925 && (! gate || IPV6_ADDR_SAME (gate, &si->addr.ipv6))
Piotr Chytłade24f822007-06-28 00:09:28 +02002926 && (! ifname || strcmp (ifname, si->ifname) == 0)
2927 && (! tag || (tag == si->tag)))
paul718e3742002-12-13 20:15:29 +00002928 break;
2929
2930 /* Can't find static route. */
2931 if (! si)
2932 {
2933 route_unlock_node (rn);
2934 return 0;
2935 }
2936
2937 /* Install into rib. */
Donald Sharp949b7192015-11-04 13:26:39 -05002938 static_uninstall_route (AFI_IP6, SAFI_UNICAST, p, si);
paul718e3742002-12-13 20:15:29 +00002939
2940 /* Unlink static route from linked list. */
2941 if (si->prev)
2942 si->prev->next = si->next;
2943 else
2944 rn->info = si->next;
2945 if (si->next)
2946 si->next->prev = si->prev;
2947
2948 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002949 if (ifname)
2950 XFREE (0, si->ifname);
Donald Sharpd4c27d62015-11-04 13:26:35 -05002951 XFREE (MTYPE_STATIC_ROUTE, si);
paul718e3742002-12-13 20:15:29 +00002952
2953 return 1;
2954}
David Lamparter6b0655a2014-06-04 06:53:35 +02002955
paul718e3742002-12-13 20:15:29 +00002956/* RIB update function. */
2957void
Feng Lu0d0686f2015-05-22 11:40:02 +02002958rib_update (vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002959{
2960 struct route_node *rn;
2961 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00002962
Feng Lu0d0686f2015-05-22 11:40:02 +02002963 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +00002964 if (table)
2965 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002966 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00002967 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002968
Feng Lu0d0686f2015-05-22 11:40:02 +02002969 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +00002970 if (table)
2971 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002972 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00002973 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002974}
2975
David Lamparter6b0655a2014-06-04 06:53:35 +02002976
paul718e3742002-12-13 20:15:29 +00002977/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00002978static void
paul718e3742002-12-13 20:15:29 +00002979rib_weed_table (struct route_table *table)
2980{
2981 struct route_node *rn;
2982 struct rib *rib;
2983 struct rib *next;
2984
2985 if (table)
2986 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002987 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00002988 {
Paul Jakma6d691122006-07-27 21:49:00 +00002989 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2990 continue;
2991
paulb21b19c2003-06-15 01:28:29 +00002992 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00002993 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00002994 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002995 }
2996}
2997
2998/* Delete all routes from non main table. */
2999void
paula1ac18c2005-06-28 17:17:12 +00003000rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00003001{
Feng Lu0d0686f2015-05-22 11:40:02 +02003002 vrf_iter_t iter;
3003 struct zebra_vrf *zvrf;
3004
3005 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3006 if ((zvrf = vrf_iter2info (iter)) != NULL)
3007 {
3008 rib_weed_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
3009 rib_weed_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
3010 }
paul718e3742002-12-13 20:15:29 +00003011}
David Lamparter6b0655a2014-06-04 06:53:35 +02003012
Feng Lu0d0686f2015-05-22 11:40:02 +02003013#if 0
paul718e3742002-12-13 20:15:29 +00003014/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00003015static void
paul718e3742002-12-13 20:15:29 +00003016rib_sweep_table (struct route_table *table)
3017{
3018 struct route_node *rn;
3019 struct rib *rib;
3020 struct rib *next;
3021 int ret = 0;
3022
3023 if (table)
3024 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003025 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003026 {
Paul Jakma6d691122006-07-27 21:49:00 +00003027 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3028 continue;
3029
paul718e3742002-12-13 20:15:29 +00003030 if (rib->type == ZEBRA_ROUTE_KERNEL &&
3031 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
3032 {
Timo Teräs0abf6792016-01-15 17:36:29 +02003033 ret = rib_update_kernel (rn, rib, NULL);
paul718e3742002-12-13 20:15:29 +00003034 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00003035 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003036 }
3037 }
3038}
Feng Lu0d0686f2015-05-22 11:40:02 +02003039#endif
paul718e3742002-12-13 20:15:29 +00003040
3041/* Sweep all RIB tables. */
3042void
paula1ac18c2005-06-28 17:17:12 +00003043rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00003044{
Feng Lu0d0686f2015-05-22 11:40:02 +02003045 vrf_iter_t iter;
3046 struct zebra_vrf *zvrf;
3047
3048 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3049 if ((zvrf = vrf_iter2info (iter)) != NULL)
3050 {
3051 rib_weed_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
3052 rib_weed_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
3053 }
paul718e3742002-12-13 20:15:29 +00003054}
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003055
3056/* Remove specific by protocol routes from 'table'. */
3057static unsigned long
3058rib_score_proto_table (u_char proto, struct route_table *table)
3059{
3060 struct route_node *rn;
3061 struct rib *rib;
3062 struct rib *next;
3063 unsigned long n = 0;
3064
3065 if (table)
3066 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003067 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003068 {
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003069 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3070 continue;
3071 if (rib->type == proto)
3072 {
3073 rib_delnode (rn, rib);
3074 n++;
3075 }
3076 }
3077
3078 return n;
3079}
3080
3081/* Remove specific by protocol routes. */
3082unsigned long
3083rib_score_proto (u_char proto)
3084{
Feng Lu0d0686f2015-05-22 11:40:02 +02003085 vrf_iter_t iter;
3086 struct zebra_vrf *zvrf;
3087 unsigned long cnt = 0;
3088
3089 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3090 if ((zvrf = vrf_iter2info (iter)) != NULL)
3091 cnt += rib_score_proto_table (proto, zvrf->table[AFI_IP][SAFI_UNICAST])
3092 +rib_score_proto_table (proto, zvrf->table[AFI_IP6][SAFI_UNICAST]);
3093
3094 return cnt;
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003095}
3096
paul718e3742002-12-13 20:15:29 +00003097/* Close RIB and clean up kernel routes. */
Feng Lu267ceb22015-05-22 11:40:09 +02003098void
paul718e3742002-12-13 20:15:29 +00003099rib_close_table (struct route_table *table)
3100{
3101 struct route_node *rn;
David Lamparter7ce9e6a2015-01-12 07:05:06 +01003102 rib_table_info_t *info = table->info;
paul718e3742002-12-13 20:15:29 +00003103 struct rib *rib;
3104
3105 if (table)
3106 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003107 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00003108 {
Timo Teräs325823a2016-01-15 17:36:31 +02003109 if (!CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003110 continue;
3111
David Lamparter7ce9e6a2015-01-12 07:05:06 +01003112 if (info->safi == SAFI_UNICAST)
3113 zfpm_trigger_update (rn, NULL);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00003114
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003115 if (! RIB_SYSTEM_ROUTE (rib))
Timo Teräs0abf6792016-01-15 17:36:29 +02003116 rib_update_kernel (rn, rib, NULL);
Paul Jakma6d691122006-07-27 21:49:00 +00003117 }
paul718e3742002-12-13 20:15:29 +00003118}
3119
3120/* Close all RIB tables. */
3121void
paula1ac18c2005-06-28 17:17:12 +00003122rib_close (void)
paul718e3742002-12-13 20:15:29 +00003123{
Feng Lu0d0686f2015-05-22 11:40:02 +02003124 vrf_iter_t iter;
3125 struct zebra_vrf *zvrf;
3126
3127 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3128 if ((zvrf = vrf_iter2info (iter)) != NULL)
3129 {
3130 rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
3131 rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
3132 }
paul718e3742002-12-13 20:15:29 +00003133}
David Lamparter6b0655a2014-06-04 06:53:35 +02003134
paul718e3742002-12-13 20:15:29 +00003135/* Routing information base initialize. */
3136void
paula1ac18c2005-06-28 17:17:12 +00003137rib_init (void)
paul718e3742002-12-13 20:15:29 +00003138{
paul4d38fdb2005-04-28 17:35:14 +00003139 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00003140}
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003141
3142/*
3143 * vrf_id_get_next
3144 *
3145 * Get the first vrf id that is greater than the given vrf id if any.
3146 *
3147 * Returns TRUE if a vrf id was found, FALSE otherwise.
3148 */
3149static inline int
Feng Lu41f44a22015-05-22 11:39:56 +02003150vrf_id_get_next (vrf_id_t vrf_id, vrf_id_t *next_id_p)
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003151{
Feng Lu41f44a22015-05-22 11:39:56 +02003152 vrf_iter_t iter = vrf_iterator (vrf_id);
3153 struct zebra_vrf *zvrf = vrf_iter2info (iter);
3154
3155 /* The same one ? Then find out the next. */
3156 if (zvrf && (zvrf->vrf_id == vrf_id))
3157 zvrf = vrf_iter2info (vrf_next (iter));
3158
3159 if (zvrf)
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003160 {
Feng Lu41f44a22015-05-22 11:39:56 +02003161 *next_id_p = zvrf->vrf_id;
3162 return 1;
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003163 }
3164
3165 return 0;
3166}
3167
3168/*
3169 * rib_tables_iter_next
3170 *
3171 * Returns the next table in the iteration.
3172 */
3173struct route_table *
3174rib_tables_iter_next (rib_tables_iter_t *iter)
3175{
3176 struct route_table *table;
3177
3178 /*
3179 * Array that helps us go over all AFI/SAFI combinations via one
3180 * index.
3181 */
3182 static struct {
3183 afi_t afi;
3184 safi_t safi;
3185 } afi_safis[] = {
3186 { AFI_IP, SAFI_UNICAST },
3187 { AFI_IP, SAFI_MULTICAST },
3188 { AFI_IP6, SAFI_UNICAST },
3189 { AFI_IP6, SAFI_MULTICAST },
3190 };
3191
3192 table = NULL;
3193
3194 switch (iter->state)
3195 {
3196
3197 case RIB_TABLES_ITER_S_INIT:
Donald Sharp0d271292015-11-19 07:21:30 -05003198 iter->vrf_id = VRF_DEFAULT;
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003199 iter->afi_safi_ix = -1;
3200
3201 /* Fall through */
3202
3203 case RIB_TABLES_ITER_S_ITERATING:
3204 iter->afi_safi_ix++;
3205 while (1)
3206 {
3207
3208 while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
3209 {
Feng Lu41f44a22015-05-22 11:39:56 +02003210 table = zebra_vrf_table (afi_safis[iter->afi_safi_ix].afi,
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003211 afi_safis[iter->afi_safi_ix].safi,
3212 iter->vrf_id);
3213 if (table)
3214 break;
3215
3216 iter->afi_safi_ix++;
3217 }
3218
3219 /*
3220 * Found another table in this vrf.
3221 */
3222 if (table)
3223 break;
3224
3225 /*
3226 * Done with all tables in the current vrf, go to the next
3227 * one.
3228 */
3229 if (!vrf_id_get_next (iter->vrf_id, &iter->vrf_id))
3230 break;
3231
3232 iter->afi_safi_ix = 0;
3233 }
3234
3235 break;
3236
3237 case RIB_TABLES_ITER_S_DONE:
3238 return NULL;
3239 }
3240
3241 if (table)
3242 iter->state = RIB_TABLES_ITER_S_ITERATING;
3243 else
3244 iter->state = RIB_TABLES_ITER_S_DONE;
3245
3246 return table;
3247}
Feng Lu41f44a22015-05-22 11:39:56 +02003248
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05003249/* Lookup VRF by identifier. */
3250struct zebra_vrf *
3251zebra_vrf_lookup (vrf_id_t vrf_id)
3252{
3253 return vrf_info_lookup (vrf_id);
3254}
3255
Feng Lu41f44a22015-05-22 11:39:56 +02003256/*
3257 * Create a routing table for the specific AFI/SAFI in the given VRF.
3258 */
3259static void
3260zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi)
3261{
3262 rib_table_info_t *info;
3263 struct route_table *table;
3264
3265 assert (!zvrf->table[afi][safi]);
3266
3267 table = route_table_init ();
3268 zvrf->table[afi][safi] = table;
3269
3270 info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
3271 info->zvrf = zvrf;
3272 info->afi = afi;
3273 info->safi = safi;
3274 table->info = info;
3275}
3276
3277/* Allocate new zebra VRF. */
3278struct zebra_vrf *
3279zebra_vrf_alloc (vrf_id_t vrf_id)
3280{
3281 struct zebra_vrf *zvrf;
Feng Lu758fb8f2014-07-03 18:23:09 +08003282#ifdef HAVE_NETLINK
3283 char nl_name[64];
3284#endif
Feng Lu41f44a22015-05-22 11:39:56 +02003285
3286 zvrf = XCALLOC (MTYPE_ZEBRA_VRF, sizeof (struct zebra_vrf));
3287
3288 /* Allocate routing table and static table. */
3289 zebra_vrf_table_create (zvrf, AFI_IP, SAFI_UNICAST);
3290 zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_UNICAST);
3291 zvrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
3292 zvrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
3293 zebra_vrf_table_create (zvrf, AFI_IP, SAFI_MULTICAST);
3294 zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_MULTICAST);
3295 zvrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
3296 zvrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
3297
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05003298 zvrf->rnh_table[AFI_IP] = route_table_init();
3299 zvrf->rnh_table[AFI_IP6] = route_table_init();
3300
Feng Lu41f44a22015-05-22 11:39:56 +02003301 /* Set VRF ID */
3302 zvrf->vrf_id = vrf_id;
3303
Feng Lu758fb8f2014-07-03 18:23:09 +08003304#ifdef HAVE_NETLINK
3305 /* Initialize netlink sockets */
3306 snprintf (nl_name, 64, "netlink-listen (vrf %u)", vrf_id);
3307 zvrf->netlink.sock = -1;
3308 zvrf->netlink.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name);
3309
3310 snprintf (nl_name, 64, "netlink-cmd (vrf %u)", vrf_id);
3311 zvrf->netlink_cmd.sock = -1;
3312 zvrf->netlink_cmd.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name);
3313#endif
3314
Feng Lu41f44a22015-05-22 11:39:56 +02003315 return zvrf;
3316}
3317
3318/* Lookup the routing table in an enabled VRF. */
3319struct route_table *
3320zebra_vrf_table (afi_t afi, safi_t safi, vrf_id_t vrf_id)
3321{
3322 struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);
3323
3324 if (!zvrf)
3325 return NULL;
3326
3327 if (afi >= AFI_MAX || safi >= SAFI_MAX)
3328 return NULL;
3329
3330 return zvrf->table[afi][safi];
3331}
3332
3333/* Lookup the static routing table in a VRF. */
3334struct route_table *
3335zebra_vrf_static_table (afi_t afi, safi_t safi, vrf_id_t vrf_id)
3336{
3337 struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);
3338
3339 if (!zvrf)
3340 return NULL;
3341
3342 if (afi >= AFI_MAX || safi >= SAFI_MAX)
3343 return NULL;
3344
3345 return zvrf->stable[afi][safi];
3346}
3347