blob: abb9560ab7c240bd479aeff4e731aa3ee0de0237 [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},
David Lamparter7052f222009-08-27 00:28:28 +020075 /* no entry/default: 150 */
paul718e3742002-12-13 20:15:29 +000076};
David Lamparter6b0655a2014-06-04 06:53:35 +020077
David Lamparterbd078122015-01-06 19:53:24 +010078/* RPF lookup behaviour */
79static enum multicast_mode ipv4_multicast_mode = MCAST_NO_CONFIG;
80
David Lampartereed3c482015-03-03 08:51:53 +010081static void __attribute__((format (printf, 4, 5)))
David Lamparter94813742014-04-24 20:22:53 +020082_rnode_zlog(const char *_func, struct route_node *rn, int priority,
83 const char *msgfmt, ...)
84{
Feng Lu0d0686f2015-05-22 11:40:02 +020085 char prefix[PREFIX_STRLEN], buf[256];
David Lamparter94813742014-04-24 20:22:53 +020086 char msgbuf[512];
87 va_list ap;
88
89 va_start(ap, msgfmt);
90 vsnprintf(msgbuf, sizeof(msgbuf), msgfmt, ap);
91 va_end(ap);
92
93 if (rn)
94 {
David Lamparterab2ba612015-01-22 19:02:13 +010095 rib_table_info_t *info = rn->table->info;
96
Feng Lu0d0686f2015-05-22 11:40:02 +020097 snprintf(buf, sizeof(buf), "%s%s vrf %u",
98 prefix2str(&rn->p, prefix, sizeof(prefix)),
99 info->safi == SAFI_MULTICAST ? " (MRIB)" : "",
100 info->zvrf->vrf_id);
David Lamparter94813742014-04-24 20:22:53 +0200101 }
102 else
103 {
104 snprintf(buf, sizeof(buf), "{(route_node *) NULL}");
105 }
106
107 zlog (NULL, priority, "%s: %s: %s", _func, buf, msgbuf);
108}
109
110#define rnode_debug(node, ...) \
111 _rnode_zlog(__func__, node, LOG_DEBUG, __VA_ARGS__)
112#define rnode_info(node, ...) \
113 _rnode_zlog(__func__, node, LOG_INFO, __VA_ARGS__)
114
Christian Frankefa713d92013-07-05 15:35:37 +0000115/* Add nexthop to the end of a rib node's nexthop list */
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500116void
117rib_nexthop_add (struct rib *rib, struct nexthop *nexthop)
Christian Frankefa713d92013-07-05 15:35:37 +0000118{
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500119 nexthop_add(&rib->nexthop, nexthop);
paul718e3742002-12-13 20:15:29 +0000120 rib->nexthop_num++;
121}
122
123/* Delete specified nexthop from the list. */
paula1ac18c2005-06-28 17:17:12 +0000124static void
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500125rib_nexthop_delete (struct rib *rib, struct nexthop *nexthop)
paul718e3742002-12-13 20:15:29 +0000126{
127 if (nexthop->next)
128 nexthop->next->prev = nexthop->prev;
129 if (nexthop->prev)
130 nexthop->prev->next = nexthop->next;
131 else
132 rib->nexthop = nexthop->next;
133 rib->nexthop_num--;
134}
135
paul718e3742002-12-13 20:15:29 +0000136struct nexthop *
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500137rib_nexthop_ifindex_add (struct rib *rib, ifindex_t ifindex)
paul718e3742002-12-13 20:15:29 +0000138{
139 struct nexthop *nexthop;
140
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500141 nexthop = nexthop_new ();
paul718e3742002-12-13 20:15:29 +0000142 nexthop->type = NEXTHOP_TYPE_IFINDEX;
143 nexthop->ifindex = ifindex;
144
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500145 rib_nexthop_add (rib, nexthop);
paul718e3742002-12-13 20:15:29 +0000146
147 return nexthop;
148}
149
150struct nexthop *
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500151rib_nexthop_ifname_add (struct rib *rib, char *ifname)
paul718e3742002-12-13 20:15:29 +0000152{
153 struct nexthop *nexthop;
154
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500155 nexthop = nexthop_new ();
paul718e3742002-12-13 20:15:29 +0000156 nexthop->type = NEXTHOP_TYPE_IFNAME;
David Lamparter23757db2016-02-24 06:26:02 +0100157 nexthop->ifname = XSTRDUP (MTYPE_TMP, ifname);
paul718e3742002-12-13 20:15:29 +0000158
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500159 rib_nexthop_add (rib, nexthop);
paul718e3742002-12-13 20:15:29 +0000160
161 return nexthop;
162}
163
164struct nexthop *
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500165rib_nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src)
paul718e3742002-12-13 20:15:29 +0000166{
167 struct nexthop *nexthop;
168
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500169 nexthop = nexthop_new ();
paul718e3742002-12-13 20:15:29 +0000170 nexthop->type = NEXTHOP_TYPE_IPV4;
171 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000172 if (src)
173 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000174
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500175 rib_nexthop_add (rib, nexthop);
paul718e3742002-12-13 20:15:29 +0000176
177 return nexthop;
178}
179
Josh Bailey26e2ae32012-03-22 01:09:21 -0700180struct nexthop *
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500181rib_nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
182 struct in_addr *src, ifindex_t ifindex)
paul718e3742002-12-13 20:15:29 +0000183{
184 struct nexthop *nexthop;
185
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500186 nexthop = nexthop_new ();
paul718e3742002-12-13 20:15:29 +0000187 nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
188 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000189 if (src)
190 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000191 nexthop->ifindex = ifindex;
192
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500193 rib_nexthop_add (rib, nexthop);
paul718e3742002-12-13 20:15:29 +0000194
195 return nexthop;
196}
197
paul718e3742002-12-13 20:15:29 +0000198struct nexthop *
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500199rib_nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
paul718e3742002-12-13 20:15:29 +0000200{
201 struct nexthop *nexthop;
202
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500203 nexthop = nexthop_new ();
paul718e3742002-12-13 20:15:29 +0000204 nexthop->type = NEXTHOP_TYPE_IPV6;
205 nexthop->gate.ipv6 = *ipv6;
206
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500207 rib_nexthop_add (rib, nexthop);
paul718e3742002-12-13 20:15:29 +0000208
209 return nexthop;
210}
211
paula1ac18c2005-06-28 17:17:12 +0000212static struct nexthop *
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500213rib_nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
214 char *ifname)
paul718e3742002-12-13 20:15:29 +0000215{
216 struct nexthop *nexthop;
217
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500218 nexthop = nexthop_new ();
paul718e3742002-12-13 20:15:29 +0000219 nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
220 nexthop->gate.ipv6 = *ipv6;
David Lamparter23757db2016-02-24 06:26:02 +0100221 nexthop->ifname = XSTRDUP (MTYPE_TMP, ifname);
paul718e3742002-12-13 20:15:29 +0000222
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500223 rib_nexthop_add (rib, nexthop);
paul718e3742002-12-13 20:15:29 +0000224
225 return nexthop;
226}
227
Ayan Banerjee34c5d892015-11-09 20:14:53 -0500228struct nexthop *
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500229rib_nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
230 ifindex_t ifindex)
paul718e3742002-12-13 20:15:29 +0000231{
232 struct nexthop *nexthop;
233
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500234 nexthop = nexthop_new ();
paul718e3742002-12-13 20:15:29 +0000235 nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
236 nexthop->gate.ipv6 = *ipv6;
237 nexthop->ifindex = ifindex;
238
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500239 rib_nexthop_add (rib, nexthop);
paul718e3742002-12-13 20:15:29 +0000240
241 return nexthop;
242}
paul718e3742002-12-13 20:15:29 +0000243
paul595db7f2003-05-25 21:35:06 +0000244struct nexthop *
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500245rib_nexthop_blackhole_add (struct rib *rib)
paul595db7f2003-05-25 21:35:06 +0000246{
247 struct nexthop *nexthop;
248
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500249 nexthop = nexthop_new ();
paul595db7f2003-05-25 21:35:06 +0000250 nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
251 SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
252
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500253 rib_nexthop_add (rib, nexthop);
paul595db7f2003-05-25 21:35:06 +0000254
255 return nexthop;
256}
257
Christian Frankefa713d92013-07-05 15:35:37 +0000258/* This method checks whether a recursive nexthop has at
259 * least one resolved nexthop in the fib.
260 */
261int
262nexthop_has_fib_child(struct nexthop *nexthop)
263{
264 struct nexthop *nh;
265
266 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
267 return 0;
268
269 for (nh = nexthop->resolved; nh; nh = nh->next)
270 if (CHECK_FLAG (nh->flags, NEXTHOP_FLAG_FIB))
271 return 1;
272
273 return 0;
274}
275
paul718e3742002-12-13 20:15:29 +0000276/* If force flag is not set, do not modify falgs at all for uninstall
277 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000278static int
paul718e3742002-12-13 20:15:29 +0000279nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
280 struct route_node *top)
281{
282 struct prefix_ipv4 p;
283 struct route_table *table;
284 struct route_node *rn;
285 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000286 int resolved;
paul718e3742002-12-13 20:15:29 +0000287 struct nexthop *newhop;
Christian Frankefa713d92013-07-05 15:35:37 +0000288 struct nexthop *resolved_hop;
paul718e3742002-12-13 20:15:29 +0000289
290 if (nexthop->type == NEXTHOP_TYPE_IPV4)
291 nexthop->ifindex = 0;
292
293 if (set)
Christian Frankefa713d92013-07-05 15:35:37 +0000294 {
295 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
296 nexthops_free(nexthop->resolved);
297 nexthop->resolved = NULL;
Timo Teräsb11f3b52015-11-02 16:50:07 +0200298 rib->nexthop_mtu = 0;
Christian Frankefa713d92013-07-05 15:35:37 +0000299 }
paul718e3742002-12-13 20:15:29 +0000300
301 /* Make lookup prefix. */
302 memset (&p, 0, sizeof (struct prefix_ipv4));
303 p.family = AF_INET;
304 p.prefixlen = IPV4_MAX_PREFIXLEN;
305 p.prefix = nexthop->gate.ipv4;
306
307 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200308 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, rib->vrf_id);
paul718e3742002-12-13 20:15:29 +0000309 if (! table)
310 return 0;
311
312 rn = route_node_match (table, (struct prefix *) &p);
313 while (rn)
314 {
315 route_unlock_node (rn);
316
David Warda50c1072009-12-03 15:34:39 +0300317 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000318 if (rn == top)
319 return 0;
320
321 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000322 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100323 {
324 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
325 continue;
Timo Teräs325823a2016-01-15 17:36:31 +0200326 if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB))
Stephen Hemminger16814f92008-08-17 17:39:31 +0100327 break;
328 }
paul718e3742002-12-13 20:15:29 +0000329
330 /* If there is no selected route or matched route is EGP, go up
331 tree. */
332 if (! match
333 || match->type == ZEBRA_ROUTE_BGP)
334 {
335 do {
336 rn = rn->parent;
337 } while (rn && rn->info == NULL);
338 if (rn)
339 route_lock_node (rn);
340 }
341 else
342 {
Christian Franke48a53dc2013-07-05 15:35:38 +0000343 /* If the longest prefix match for the nexthop yields
344 * a blackhole, mark it as inactive. */
345 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE)
346 || CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT))
347 return 0;
348
paul718e3742002-12-13 20:15:29 +0000349 if (match->type == ZEBRA_ROUTE_CONNECT)
350 {
351 /* Directly point connected route. */
352 newhop = match->nexthop;
353 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
354 nexthop->ifindex = newhop->ifindex;
355
356 return 1;
357 }
358 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
359 {
Christian Frankefa713d92013-07-05 15:35:37 +0000360 resolved = 0;
paul718e3742002-12-13 20:15:29 +0000361 for (newhop = match->nexthop; newhop; newhop = newhop->next)
362 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
363 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
364 {
365 if (set)
366 {
367 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
Christian Frankefa713d92013-07-05 15:35:37 +0000368
369 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
370 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
Christian Frankec3e6b592013-07-05 15:35:40 +0000371 /* If the resolving route specifies a gateway, use it */
372 if (newhop->type == NEXTHOP_TYPE_IPV4
373 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX
374 || newhop->type == NEXTHOP_TYPE_IPV4_IFNAME)
375 {
376 resolved_hop->type = newhop->type;
377 resolved_hop->gate.ipv4 = newhop->gate.ipv4;
Timo Teräs82a66352016-01-15 17:36:30 +0200378 resolved_hop->ifindex = newhop->ifindex;
Christian Frankec3e6b592013-07-05 15:35:40 +0000379 }
Christian Frankefa713d92013-07-05 15:35:37 +0000380
Timo Teräs82a66352016-01-15 17:36:30 +0200381 /* If the resolving route is an interface route, it
382 * means the gateway we are looking up is connected
383 * to that interface. Therefore, the resolved route
384 * should have the original gateway as nexthop as it
385 * is directly connected. */
paul718e3742002-12-13 20:15:29 +0000386 if (newhop->type == NEXTHOP_TYPE_IFINDEX
Christian Frankec3e6b592013-07-05 15:35:40 +0000387 || newhop->type == NEXTHOP_TYPE_IFNAME)
388 {
Christian Frankec3e6b592013-07-05 15:35:40 +0000389 resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
390 resolved_hop->gate.ipv4 = nexthop->gate.ipv4;
391 resolved_hop->ifindex = newhop->ifindex;
392 }
Christian Frankefa713d92013-07-05 15:35:37 +0000393
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500394 nexthop_add(&nexthop->resolved, resolved_hop);
paul718e3742002-12-13 20:15:29 +0000395 }
Christian Frankefa713d92013-07-05 15:35:37 +0000396 resolved = 1;
paul718e3742002-12-13 20:15:29 +0000397 }
Timo Teräsb11f3b52015-11-02 16:50:07 +0200398 if (resolved && set)
399 rib->nexthop_mtu = match->mtu;
Christian Frankefa713d92013-07-05 15:35:37 +0000400 return resolved;
paul718e3742002-12-13 20:15:29 +0000401 }
402 else
403 {
404 return 0;
405 }
406 }
407 }
408 return 0;
409}
410
paul718e3742002-12-13 20:15:29 +0000411/* If force flag is not set, do not modify falgs at all for uninstall
412 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000413static int
paul718e3742002-12-13 20:15:29 +0000414nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
415 struct route_node *top)
416{
417 struct prefix_ipv6 p;
418 struct route_table *table;
419 struct route_node *rn;
420 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000421 int resolved;
paul718e3742002-12-13 20:15:29 +0000422 struct nexthop *newhop;
Christian Frankefa713d92013-07-05 15:35:37 +0000423 struct nexthop *resolved_hop;
paul718e3742002-12-13 20:15:29 +0000424
425 if (nexthop->type == NEXTHOP_TYPE_IPV6)
426 nexthop->ifindex = 0;
427
428 if (set)
Christian Frankefa713d92013-07-05 15:35:37 +0000429 {
430 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
431 nexthops_free(nexthop->resolved);
432 nexthop->resolved = NULL;
433 }
paul718e3742002-12-13 20:15:29 +0000434
435 /* Make lookup prefix. */
436 memset (&p, 0, sizeof (struct prefix_ipv6));
437 p.family = AF_INET6;
438 p.prefixlen = IPV6_MAX_PREFIXLEN;
439 p.prefix = nexthop->gate.ipv6;
440
441 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200442 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, rib->vrf_id);
paul718e3742002-12-13 20:15:29 +0000443 if (! table)
444 return 0;
445
446 rn = route_node_match (table, (struct prefix *) &p);
447 while (rn)
448 {
449 route_unlock_node (rn);
450
David Warda50c1072009-12-03 15:34:39 +0300451 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000452 if (rn == top)
453 return 0;
454
455 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000456 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100457 {
458 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
459 continue;
Timo Teräs325823a2016-01-15 17:36:31 +0200460 if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB))
Stephen Hemminger16814f92008-08-17 17:39:31 +0100461 break;
462 }
paul718e3742002-12-13 20:15:29 +0000463
464 /* If there is no selected route or matched route is EGP, go up
465 tree. */
466 if (! match
467 || match->type == ZEBRA_ROUTE_BGP)
468 {
469 do {
470 rn = rn->parent;
471 } while (rn && rn->info == NULL);
472 if (rn)
473 route_lock_node (rn);
474 }
475 else
476 {
Christian Franke48a53dc2013-07-05 15:35:38 +0000477 /* If the longest prefix match for the nexthop yields
478 * a blackhole, mark it as inactive. */
479 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE)
480 || CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT))
481 return 0;
482
paul718e3742002-12-13 20:15:29 +0000483 if (match->type == ZEBRA_ROUTE_CONNECT)
484 {
485 /* Directly point connected route. */
486 newhop = match->nexthop;
487
488 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
489 nexthop->ifindex = newhop->ifindex;
490
491 return 1;
492 }
493 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
494 {
Christian Frankefa713d92013-07-05 15:35:37 +0000495 resolved = 0;
paul718e3742002-12-13 20:15:29 +0000496 for (newhop = match->nexthop; newhop; newhop = newhop->next)
497 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
498 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
499 {
500 if (set)
501 {
502 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
Christian Frankefa713d92013-07-05 15:35:37 +0000503
504 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
505 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
Christian Frankec3e6b592013-07-05 15:35:40 +0000506 /* See nexthop_active_ipv4 for a description how the
507 * resolved nexthop is constructed. */
paul718e3742002-12-13 20:15:29 +0000508 if (newhop->type == NEXTHOP_TYPE_IPV6
509 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
510 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
Christian Frankec3e6b592013-07-05 15:35:40 +0000511 {
512 resolved_hop->type = newhop->type;
513 resolved_hop->gate.ipv6 = newhop->gate.ipv6;
514
515 if (newhop->ifindex)
516 {
517 resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
518 resolved_hop->ifindex = newhop->ifindex;
519 }
520 }
Christian Frankefa713d92013-07-05 15:35:37 +0000521
paul718e3742002-12-13 20:15:29 +0000522 if (newhop->type == NEXTHOP_TYPE_IFINDEX
Christian Frankec3e6b592013-07-05 15:35:40 +0000523 || newhop->type == NEXTHOP_TYPE_IFNAME)
524 {
525 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
526 resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
527 resolved_hop->gate.ipv6 = nexthop->gate.ipv6;
528 resolved_hop->ifindex = newhop->ifindex;
529 }
Christian Frankefa713d92013-07-05 15:35:37 +0000530
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500531 nexthop_add(&nexthop->resolved, resolved_hop);
paul718e3742002-12-13 20:15:29 +0000532 }
Christian Frankefa713d92013-07-05 15:35:37 +0000533 resolved = 1;
paul718e3742002-12-13 20:15:29 +0000534 }
Christian Frankefa713d92013-07-05 15:35:37 +0000535 return resolved;
paul718e3742002-12-13 20:15:29 +0000536 }
537 else
538 {
539 return 0;
540 }
541 }
542 }
543 return 0;
544}
paul718e3742002-12-13 20:15:29 +0000545
546struct rib *
David Lamparter24480d42015-01-22 19:09:36 +0100547rib_match_ipv4_safi (struct in_addr addr, safi_t safi, int skip_bgp,
Feng Lu0d0686f2015-05-22 11:40:02 +0200548 struct route_node **rn_out, vrf_id_t vrf_id)
Everton Marques3dea1782014-09-22 19:35:51 -0300549{
550 struct route_table *table;
551 struct route_node *rn;
552 struct rib *match;
553 struct nexthop *newhop, *tnewhop;
554 int recursing;
555
556 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200557 table = zebra_vrf_table (AFI_IP, safi, vrf_id);
Everton Marques3dea1782014-09-22 19:35:51 -0300558 if (! table)
559 return 0;
560
561 rn = route_node_match_ipv4 (table, &addr);
562
563 while (rn)
564 {
565 route_unlock_node (rn);
566
567 /* Pick up selected route. */
568 RNODE_FOREACH_RIB (rn, match)
569 {
570 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
571 continue;
Timo Teräs325823a2016-01-15 17:36:31 +0200572 if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB))
Everton Marques3dea1782014-09-22 19:35:51 -0300573 break;
574 }
575
576 /* If there is no selected route or matched route is EGP, go up
577 tree. */
Everton Marques83d71122014-09-19 16:39:34 -0300578 if (!match || (skip_bgp && (match->type == ZEBRA_ROUTE_BGP)))
Everton Marques3dea1782014-09-22 19:35:51 -0300579 {
580 do {
581 rn = rn->parent;
582 } while (rn && rn->info == NULL);
583 if (rn)
584 route_lock_node (rn);
585 }
586 else
587 {
David Lamparter24480d42015-01-22 19:09:36 +0100588 if (match->type != ZEBRA_ROUTE_CONNECT)
Everton Marques3dea1782014-09-22 19:35:51 -0300589 {
David Lamparter24480d42015-01-22 19:09:36 +0100590 int found = 0;
Everton Marques3dea1782014-09-22 19:35:51 -0300591 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
592 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
David Lamparter24480d42015-01-22 19:09:36 +0100593 {
594 found = 1;
595 break;
596 }
597 if (!found)
598 return NULL;
Everton Marques3dea1782014-09-22 19:35:51 -0300599 }
David Lamparter24480d42015-01-22 19:09:36 +0100600
601 if (rn_out)
602 *rn_out = rn;
603 return match;
Everton Marques3dea1782014-09-22 19:35:51 -0300604 }
605 }
606 return NULL;
607}
608
609struct rib *
Feng Lu0d0686f2015-05-22 11:40:02 +0200610rib_match_ipv4_multicast (struct in_addr addr, struct route_node **rn_out,
611 vrf_id_t vrf_id)
David Lamparterbd078122015-01-06 19:53:24 +0100612{
613 struct rib *rib = NULL, *mrib = NULL, *urib = NULL;
614 struct route_node *m_rn = NULL, *u_rn = NULL;
615 int skip_bgp = 0; /* bool */
616
617 switch (ipv4_multicast_mode)
618 {
619 case MCAST_MRIB_ONLY:
Feng Lu0d0686f2015-05-22 11:40:02 +0200620 return rib_match_ipv4_safi (addr, SAFI_MULTICAST, skip_bgp, rn_out,
621 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100622 case MCAST_URIB_ONLY:
Feng Lu0d0686f2015-05-22 11:40:02 +0200623 return rib_match_ipv4_safi (addr, SAFI_UNICAST, skip_bgp, rn_out,
624 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100625 case MCAST_NO_CONFIG:
626 case MCAST_MIX_MRIB_FIRST:
Feng Lu0d0686f2015-05-22 11:40:02 +0200627 rib = mrib = rib_match_ipv4_safi (addr, SAFI_MULTICAST, skip_bgp, &m_rn,
628 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100629 if (!mrib)
Feng Lu0d0686f2015-05-22 11:40:02 +0200630 rib = urib = rib_match_ipv4_safi (addr, SAFI_UNICAST, skip_bgp, &u_rn,
631 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100632 break;
633 case MCAST_MIX_DISTANCE:
Feng Lu0d0686f2015-05-22 11:40:02 +0200634 mrib = rib_match_ipv4_safi (addr, SAFI_MULTICAST, skip_bgp, &m_rn,
635 vrf_id);
636 urib = rib_match_ipv4_safi (addr, SAFI_UNICAST, skip_bgp, &u_rn,
637 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100638 if (mrib && urib)
639 rib = urib->distance < mrib->distance ? urib : mrib;
640 else if (mrib)
641 rib = mrib;
642 else if (urib)
643 rib = urib;
644 break;
645 case MCAST_MIX_PFXLEN:
Feng Lu0d0686f2015-05-22 11:40:02 +0200646 mrib = rib_match_ipv4_safi (addr, SAFI_MULTICAST, skip_bgp, &m_rn,
647 vrf_id);
648 urib = rib_match_ipv4_safi (addr, SAFI_UNICAST, skip_bgp, &u_rn,
649 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100650 if (mrib && urib)
651 rib = u_rn->p.prefixlen > m_rn->p.prefixlen ? urib : mrib;
652 else if (mrib)
653 rib = mrib;
654 else if (urib)
655 rib = urib;
656 break;
657 }
658
659 if (rn_out)
660 *rn_out = (rib == mrib) ? m_rn : u_rn;
661
662 if (IS_ZEBRA_DEBUG_RIB)
663 {
664 char buf[BUFSIZ];
665 inet_ntop (AF_INET, &addr, buf, BUFSIZ);
666
Feng Lu0d0686f2015-05-22 11:40:02 +0200667 zlog_debug("%s: %s vrf %u: found %s, using %s",
668 __func__, buf, vrf_id,
David Lamparterbd078122015-01-06 19:53:24 +0100669 mrib ? (urib ? "MRIB+URIB" : "MRIB") :
670 urib ? "URIB" : "nothing",
671 rib == urib ? "URIB" : rib == mrib ? "MRIB" : "none");
672 }
673 return rib;
674}
675
676void
677multicast_mode_ipv4_set (enum multicast_mode mode)
678{
679 if (IS_ZEBRA_DEBUG_RIB)
680 zlog_debug("%s: multicast lookup mode set (%d)", __func__, mode);
681 ipv4_multicast_mode = mode;
682}
683
684enum multicast_mode
685multicast_mode_ipv4_get (void)
686{
687 return ipv4_multicast_mode;
688}
689
690struct rib *
Feng Lu0d0686f2015-05-22 11:40:02 +0200691rib_lookup_ipv4 (struct prefix_ipv4 *p, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000692{
693 struct route_table *table;
694 struct route_node *rn;
695 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000696 struct nexthop *nexthop, *tnexthop;
697 int recursing;
paul718e3742002-12-13 20:15:29 +0000698
699 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200700 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +0000701 if (! table)
702 return 0;
703
704 rn = route_node_lookup (table, (struct prefix *) p);
705
706 /* No route for this prefix. */
707 if (! rn)
708 return NULL;
709
710 /* Unlock node. */
711 route_unlock_node (rn);
712
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000713 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100714 {
715 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
716 continue;
Timo Teräs325823a2016-01-15 17:36:31 +0200717 if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB))
Stephen Hemminger16814f92008-08-17 17:39:31 +0100718 break;
719 }
paul718e3742002-12-13 20:15:29 +0000720
721 if (! match || match->type == ZEBRA_ROUTE_BGP)
722 return NULL;
723
724 if (match->type == ZEBRA_ROUTE_CONNECT)
725 return match;
726
Christian Frankefa713d92013-07-05 15:35:37 +0000727 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +0000728 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
729 return match;
730
731 return NULL;
732}
733
Denis Ovsienkodc958242007-08-13 16:03:06 +0000734/*
735 * This clone function, unlike its original rib_lookup_ipv4(), checks
736 * if specified IPv4 route record (prefix/mask -> gate) exists in
737 * the whole RIB and has ZEBRA_FLAG_SELECTED set.
738 *
739 * Return values:
740 * -1: error
741 * 0: exact match found
742 * 1: a match was found with a different gate
743 * 2: connected route found
744 * 3: no matches found
745 */
746int
Feng Lu0d0686f2015-05-22 11:40:02 +0200747rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate,
748 vrf_id_t vrf_id)
Denis Ovsienkodc958242007-08-13 16:03:06 +0000749{
750 struct route_table *table;
751 struct route_node *rn;
752 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000753 struct nexthop *nexthop, *tnexthop;
754 int recursing;
755 int nexthops_active;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000756
757 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200758 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
Denis Ovsienkodc958242007-08-13 16:03:06 +0000759 if (! table)
760 return ZEBRA_RIB_LOOKUP_ERROR;
761
762 /* Scan the RIB table for exactly matching RIB entry. */
763 rn = route_node_lookup (table, (struct prefix *) p);
764
765 /* No route for this prefix. */
766 if (! rn)
767 return ZEBRA_RIB_NOTFOUND;
768
769 /* Unlock node. */
770 route_unlock_node (rn);
771
772 /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000773 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100774 {
775 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
776 continue;
Timo Teräs325823a2016-01-15 17:36:31 +0200777 if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB))
Stephen Hemminger16814f92008-08-17 17:39:31 +0100778 break;
779 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000780
781 /* None such found :( */
782 if (!match)
783 return ZEBRA_RIB_NOTFOUND;
784
785 if (match->type == ZEBRA_ROUTE_CONNECT)
786 return ZEBRA_RIB_FOUND_CONNECTED;
787
788 /* Ok, we have a cood candidate, let's check it's nexthop list... */
Christian Frankefa713d92013-07-05 15:35:37 +0000789 nexthops_active = 0;
790 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000791 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000792 {
Christian Frankefa713d92013-07-05 15:35:37 +0000793 nexthops_active = 1;
794 if (nexthop->gate.ipv4.s_addr == sockunion2ip (qgate))
795 return ZEBRA_RIB_FOUND_EXACT;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000796 if (IS_ZEBRA_DEBUG_RIB)
Christian Frankefa713d92013-07-05 15:35:37 +0000797 {
798 char gate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
799 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
800 inet_ntop (AF_INET, &sockunion2ip(qgate), qgate_buf, INET_ADDRSTRLEN);
801 zlog_debug ("%s: qgate == %s, %s == %s", __func__,
802 qgate_buf, recursing ? "rgate" : "gate", gate_buf);
803 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000804 }
Christian Frankefa713d92013-07-05 15:35:37 +0000805
806 if (nexthops_active)
807 return ZEBRA_RIB_FOUND_NOGATE;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000808
809 return ZEBRA_RIB_NOTFOUND;
810}
811
paul718e3742002-12-13 20:15:29 +0000812struct rib *
Feng Lu0d0686f2015-05-22 11:40:02 +0200813rib_match_ipv6 (struct in6_addr *addr, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000814{
815 struct prefix_ipv6 p;
816 struct route_table *table;
817 struct route_node *rn;
818 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000819 struct nexthop *newhop, *tnewhop;
820 int recursing;
paul718e3742002-12-13 20:15:29 +0000821
822 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200823 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +0000824 if (! table)
825 return 0;
826
827 memset (&p, 0, sizeof (struct prefix_ipv6));
828 p.family = AF_INET6;
829 p.prefixlen = IPV6_MAX_PREFIXLEN;
830 IPV6_ADDR_COPY (&p.prefix, addr);
831
832 rn = route_node_match (table, (struct prefix *) &p);
833
834 while (rn)
835 {
836 route_unlock_node (rn);
837
838 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000839 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100840 {
841 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
842 continue;
Timo Teräs325823a2016-01-15 17:36:31 +0200843 if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB))
Stephen Hemminger16814f92008-08-17 17:39:31 +0100844 break;
845 }
paul718e3742002-12-13 20:15:29 +0000846
847 /* If there is no selected route or matched route is EGP, go up
848 tree. */
849 if (! match
850 || match->type == ZEBRA_ROUTE_BGP)
851 {
852 do {
853 rn = rn->parent;
854 } while (rn && rn->info == NULL);
855 if (rn)
856 route_lock_node (rn);
857 }
858 else
859 {
860 if (match->type == ZEBRA_ROUTE_CONNECT)
861 /* Directly point connected route. */
862 return match;
863 else
864 {
Christian Frankefa713d92013-07-05 15:35:37 +0000865 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
paul718e3742002-12-13 20:15:29 +0000866 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
867 return match;
868 return NULL;
869 }
870 }
871 }
872 return NULL;
873}
paul718e3742002-12-13 20:15:29 +0000874
Paul Jakma7514fb72007-05-02 16:05:35 +0000875#define RIB_SYSTEM_ROUTE(R) \
876 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
877
Denis Ovsienkodc958242007-08-13 16:03:06 +0000878/* This function verifies reachability of one given nexthop, which can be
879 * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
880 * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
881 * nexthop->ifindex will be updated appropriately as well.
882 * An existing route map can turn (otherwise active) nexthop into inactive, but
883 * not vice versa.
884 *
885 * The return value is the final value of 'ACTIVE' flag.
886 */
887
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300888static unsigned
paul718e3742002-12-13 20:15:29 +0000889nexthop_active_check (struct route_node *rn, struct rib *rib,
890 struct nexthop *nexthop, int set)
891{
Christian Frankef3a17322013-07-05 15:35:41 +0000892 rib_table_info_t *info = rn->table->info;
paul718e3742002-12-13 20:15:29 +0000893 struct interface *ifp;
Paul Jakma7514fb72007-05-02 16:05:35 +0000894 route_map_result_t ret = RMAP_MATCH;
895 extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
896 struct route_map *rmap;
897 int family;
paul718e3742002-12-13 20:15:29 +0000898
Paul Jakma7514fb72007-05-02 16:05:35 +0000899 family = 0;
paul718e3742002-12-13 20:15:29 +0000900 switch (nexthop->type)
901 {
902 case NEXTHOP_TYPE_IFINDEX:
Feng Lu0d0686f2015-05-22 11:40:02 +0200903 ifp = if_lookup_by_index_vrf (nexthop->ifindex, rib->vrf_id);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000904 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000905 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
906 else
907 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
908 break;
paul718e3742002-12-13 20:15:29 +0000909 case NEXTHOP_TYPE_IPV6_IFNAME:
Paul Jakma7514fb72007-05-02 16:05:35 +0000910 family = AFI_IP6;
911 case NEXTHOP_TYPE_IFNAME:
Feng Lu0d0686f2015-05-22 11:40:02 +0200912 ifp = if_lookup_by_name_vrf (nexthop->ifname, rib->vrf_id);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000913 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000914 {
915 if (set)
916 nexthop->ifindex = ifp->ifindex;
917 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
918 }
919 else
920 {
921 if (set)
922 nexthop->ifindex = 0;
923 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
924 }
925 break;
926 case NEXTHOP_TYPE_IPV4:
927 case NEXTHOP_TYPE_IPV4_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000928 family = AFI_IP;
paul718e3742002-12-13 20:15:29 +0000929 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
930 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
931 else
932 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
933 break;
paul718e3742002-12-13 20:15:29 +0000934 case NEXTHOP_TYPE_IPV6:
Paul Jakma7514fb72007-05-02 16:05:35 +0000935 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000936 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
937 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
938 else
939 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
940 break;
941 case NEXTHOP_TYPE_IPV6_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000942 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000943 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
944 {
Feng Lu0d0686f2015-05-22 11:40:02 +0200945 ifp = if_lookup_by_index_vrf (nexthop->ifindex, rib->vrf_id);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000946 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000947 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
948 else
949 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
950 }
951 else
952 {
953 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
954 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
955 else
956 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
957 }
958 break;
paul595db7f2003-05-25 21:35:06 +0000959 case NEXTHOP_TYPE_BLACKHOLE:
960 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
961 break;
paul718e3742002-12-13 20:15:29 +0000962 default:
963 break;
964 }
Paul Jakma7514fb72007-05-02 16:05:35 +0000965 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
966 return 0;
967
Christian Frankef3a17322013-07-05 15:35:41 +0000968 /* XXX: What exactly do those checks do? Do we support
969 * e.g. IPv4 routes with IPv6 nexthops or vice versa? */
Paul Jakma7514fb72007-05-02 16:05:35 +0000970 if (RIB_SYSTEM_ROUTE(rib) ||
971 (family == AFI_IP && rn->p.family != AF_INET) ||
972 (family == AFI_IP6 && rn->p.family != AF_INET6))
973 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
974
Christian Frankef3a17322013-07-05 15:35:41 +0000975 /* The original code didn't determine the family correctly
976 * e.g. for NEXTHOP_TYPE_IFINDEX. Retrieve the correct afi
977 * from the rib_table_info in those cases.
978 * Possibly it may be better to use only the rib_table_info
979 * in every case.
980 */
981 if (!family)
982 family = info->afi;
983
Paul Jakma7514fb72007-05-02 16:05:35 +0000984 rmap = 0;
985 if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
986 proto_rm[family][rib->type])
987 rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
988 if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
989 rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
990 if (rmap) {
Feng Lu1885d0a2015-05-22 11:40:04 +0200991 struct nexthop_vrfid nh_vrf = {nexthop, rib->vrf_id};
992 ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, &nh_vrf);
Paul Jakma7514fb72007-05-02 16:05:35 +0000993 }
994
995 if (ret == RMAP_DENYMATCH)
996 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
paul718e3742002-12-13 20:15:29 +0000997 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
998}
999
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001000/* Iterate over all nexthops of the given RIB entry and refresh their
1001 * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
1002 * nexthop is found to toggle the ACTIVE flag, the whole rib structure
Timo Teräs7eb61362015-11-02 16:50:05 +02001003 * is flagged with RIB_ENTRY_CHANGED. The 4th 'set' argument is
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001004 * transparently passed to nexthop_active_check().
1005 *
1006 * Return value is the new number of active nexthops.
1007 */
1008
paula1ac18c2005-06-28 17:17:12 +00001009static int
paul718e3742002-12-13 20:15:29 +00001010nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
1011{
1012 struct nexthop *nexthop;
Paul Jakma9099f9b2016-01-18 10:12:10 +00001013 unsigned int prev_active, new_active;
1014 ifindex_t prev_index;
1015
paul718e3742002-12-13 20:15:29 +00001016 rib->nexthop_active_num = 0;
paul718e3742002-12-13 20:15:29 +00001017
1018 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001019 {
1020 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001021 prev_index = nexthop->ifindex;
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001022 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
1023 rib->nexthop_active_num++;
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001024 if (prev_active != new_active ||
1025 prev_index != nexthop->ifindex)
Timo Teräs7eb61362015-11-02 16:50:05 +02001026 SET_FLAG (rib->status, RIB_ENTRY_CHANGED);
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001027 }
paul718e3742002-12-13 20:15:29 +00001028 return rib->nexthop_active_num;
1029}
paul6baeb982003-10-28 03:47:15 +00001030
David Lamparter6b0655a2014-06-04 06:53:35 +02001031
paul718e3742002-12-13 20:15:29 +00001032
Timo Teräs0abf6792016-01-15 17:36:29 +02001033static int
1034rib_update_kernel (struct route_node *rn, struct rib *old, struct rib *new)
paul718e3742002-12-13 20:15:29 +00001035{
1036 int ret = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001037 struct nexthop *nexthop, *tnexthop;
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001038 rib_table_info_t *info = rn->table->info;
Christian Frankefa713d92013-07-05 15:35:37 +00001039 int recursing;
paul718e3742002-12-13 20:15:29 +00001040
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001041 if (info->safi != SAFI_UNICAST)
1042 {
Timo Teräs0abf6792016-01-15 17:36:29 +02001043 if (new)
1044 for (ALL_NEXTHOPS_RO(new->nexthop, nexthop, tnexthop, recursing))
1045 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1046 if (old)
1047 for (ALL_NEXTHOPS_RO(old->nexthop, nexthop, tnexthop, recursing))
1048 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1049 return 0;
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001050 }
1051
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001052 /*
1053 * Make sure we update the FPM any time we send new information to
1054 * the kernel.
1055 */
Timo Teräs0abf6792016-01-15 17:36:29 +02001056 zfpm_trigger_update (rn, "updating in kernel");
1057
1058 ret = kernel_route_rib (&rn->p, old, new);
paul718e3742002-12-13 20:15:29 +00001059
Denis Ovsienkodc958242007-08-13 16:03:06 +00001060 /* This condition is never met, if we are using rt_socket.c */
Timo Teräs0abf6792016-01-15 17:36:29 +02001061 if (ret < 0 && new)
Timo Teräs7e73eb72016-04-09 17:22:32 +03001062 {
Timo Teräs0abf6792016-01-15 17:36:29 +02001063 for (ALL_NEXTHOPS_RO(new->nexthop, nexthop, tnexthop, recursing))
1064 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
Timo Teräs7e73eb72016-04-09 17:22:32 +03001065 }
1066 else if (old && old != new)
1067 {
1068 for (ALL_NEXTHOPS_RO(old->nexthop, nexthop, tnexthop, recursing))
1069 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1070 }
paul718e3742002-12-13 20:15:29 +00001071
1072 return ret;
1073}
1074
1075/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001076static void
paul718e3742002-12-13 20:15:29 +00001077rib_uninstall (struct route_node *rn, struct rib *rib)
1078{
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001079 rib_table_info_t *info = rn->table->info;
1080
Timo Teräs325823a2016-01-15 17:36:31 +02001081 if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB))
paul718e3742002-12-13 20:15:29 +00001082 {
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001083 if (info->safi == SAFI_UNICAST)
1084 zfpm_trigger_update (rn, "rib_uninstall");
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001085
paul718e3742002-12-13 20:15:29 +00001086 redistribute_delete (&rn->p, rib);
1087 if (! RIB_SYSTEM_ROUTE (rib))
Timo Teräs0abf6792016-01-15 17:36:29 +02001088 rib_update_kernel (rn, rib, NULL);
paul718e3742002-12-13 20:15:29 +00001089 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
1090 }
1091}
1092
Paul Jakma6d691122006-07-27 21:49:00 +00001093static void rib_unlink (struct route_node *, struct rib *);
1094
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001095/*
1096 * rib_can_delete_dest
1097 *
1098 * Returns TRUE if the given dest can be deleted from the table.
1099 */
1100static int
1101rib_can_delete_dest (rib_dest_t *dest)
1102{
1103 if (dest->routes)
1104 {
1105 return 0;
1106 }
1107
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001108 /*
1109 * Don't delete the dest if we have to update the FPM about this
1110 * prefix.
1111 */
1112 if (CHECK_FLAG (dest->flags, RIB_DEST_UPDATE_FPM) ||
1113 CHECK_FLAG (dest->flags, RIB_DEST_SENT_TO_FPM))
1114 return 0;
1115
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001116 return 1;
1117}
1118
1119/*
1120 * rib_gc_dest
1121 *
1122 * Garbage collect the rib dest corresponding to the given route node
1123 * if appropriate.
1124 *
1125 * Returns TRUE if the dest was deleted, FALSE otherwise.
1126 */
1127int
1128rib_gc_dest (struct route_node *rn)
1129{
1130 rib_dest_t *dest;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001131
1132 dest = rib_dest_from_rnode (rn);
1133 if (!dest)
1134 return 0;
1135
1136 if (!rib_can_delete_dest (dest))
1137 return 0;
1138
1139 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001140 rnode_debug (rn, "removing dest from table");
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001141
1142 dest->rnode = NULL;
1143 XFREE (MTYPE_RIB_DEST, dest);
1144 rn->info = NULL;
1145
1146 /*
1147 * Release the one reference that we keep on the route node.
1148 */
1149 route_unlock_node (rn);
1150 return 1;
1151}
1152
Timo Teräs0abf6792016-01-15 17:36:29 +02001153/* Check if 'alternate' RIB entry is better than 'current'. */
1154static struct rib *
1155rib_choose_best (struct rib *current, struct rib *alternate)
1156{
1157 if (current == NULL)
1158 return alternate;
1159
1160 /* filter route selection in following order:
1161 * - connected beats other types
1162 * - lower distance beats higher
1163 * - lower metric beats higher for equal distance
1164 * - last, hence oldest, route wins tie break.
1165 */
1166
1167 /* Connected routes. Pick the last connected
1168 * route of the set of lowest metric connected routes.
1169 */
1170 if (alternate->type == ZEBRA_ROUTE_CONNECT)
1171 {
1172 if (current->type != ZEBRA_ROUTE_CONNECT
1173 || alternate->metric <= current->metric)
1174 return alternate;
1175
1176 return current;
1177 }
1178
1179 if (current->type == ZEBRA_ROUTE_CONNECT)
1180 return current;
1181
1182 /* higher distance loses */
1183 if (alternate->distance < current->distance)
1184 return alternate;
1185 if (current->distance < alternate->distance)
1186 return current;
1187
1188 /* metric tie-breaks equal distance */
1189 if (alternate->metric <= current->metric)
1190 return alternate;
1191
1192 return current;
1193}
1194
paul718e3742002-12-13 20:15:29 +00001195/* Core function for processing routing information base. */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001196static void
1197rib_process (struct route_node *rn)
paul718e3742002-12-13 20:15:29 +00001198{
1199 struct rib *rib;
1200 struct rib *next;
Timo Teräs325823a2016-01-15 17:36:31 +02001201 struct rib *old_selected = NULL;
1202 struct rib *new_selected = NULL;
Timo Teräs0abf6792016-01-15 17:36:29 +02001203 struct rib *old_fib = NULL;
1204 struct rib *new_fib = NULL;
pauld753e9e2003-01-22 19:45:50 +00001205 int installed = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001206 struct nexthop *nexthop = NULL, *tnexthop;
1207 int recursing;
Balaji95116332014-10-23 15:25:25 +00001208 rib_table_info_t *info;
1209
paul4d38fdb2005-04-28 17:35:14 +00001210 assert (rn);
Balaji95116332014-10-23 15:25:25 +00001211
1212 info = rn->table->info;
1213
Timo Teräs0abf6792016-01-15 17:36:29 +02001214 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00001215 {
Timo Teräs7e73eb72016-04-09 17:22:32 +03001216 UNSET_FLAG (rib->status, RIB_ENTRY_CHANGED);
1217
paul718e3742002-12-13 20:15:29 +00001218 /* Currently installed rib. */
1219 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Paul Jakma6d691122006-07-27 21:49:00 +00001220 {
Timo Teräs325823a2016-01-15 17:36:31 +02001221 assert (old_selected == NULL);
1222 old_selected = rib;
1223 }
1224 if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB))
1225 {
Timo Teräs0abf6792016-01-15 17:36:29 +02001226 assert (old_fib == NULL);
1227 old_fib = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001228 }
Timo Teräs0abf6792016-01-15 17:36:29 +02001229
1230 /* Skip deleted entries from selection */
Paul Jakma6d691122006-07-27 21:49:00 +00001231 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
Timo Teräs0abf6792016-01-15 17:36:29 +02001232 continue;
paul4d38fdb2005-04-28 17:35:14 +00001233
paul718e3742002-12-13 20:15:29 +00001234 /* Skip unreachable nexthop. */
1235 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +00001236 continue;
paul718e3742002-12-13 20:15:29 +00001237
1238 /* Infinit distance. */
1239 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +00001240 continue;
paul718e3742002-12-13 20:15:29 +00001241
Timo Teräs325823a2016-01-15 17:36:31 +02001242 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_FIB_OVERRIDE))
1243 new_fib = rib_choose_best(new_fib, rib);
1244 else
1245 new_selected = rib_choose_best(new_selected, rib);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001246 } /* RNODE_FOREACH_RIB_SAFE */
Denis Ovsienkodc958242007-08-13 16:03:06 +00001247
Timo Teräs325823a2016-01-15 17:36:31 +02001248 /* If no FIB override route, use the selected route also for FIB */
1249 if (new_fib == NULL)
1250 new_fib = new_selected;
1251
Denis Ovsienkodc958242007-08-13 16:03:06 +00001252 /* After the cycle is finished, the following pointers will be set:
Timo Teräs325823a2016-01-15 17:36:31 +02001253 * old_selected --- RIB entry currently having SELECTED
1254 * new_selected --- RIB entry that is newly SELECTED
1255 * old_fib --- RIB entry currently in kernel FIB
1256 * new_fib --- RIB entry that is newly to be in kernel FIB
1257 *
1258 * new_selected will get SELECTED flag, and is going to be redistributed
1259 * the zclients. new_fib (which can be new_selected) will be installed in kernel.
Denis Ovsienkodc958242007-08-13 16:03:06 +00001260 */
1261
Timo Teräs0abf6792016-01-15 17:36:29 +02001262 /* Set real nexthops. */
1263 if (new_fib)
1264 nexthop_active_update (rn, new_fib, 1);
Timo Teräs325823a2016-01-15 17:36:31 +02001265 if (new_selected && new_selected != new_fib)
Timo Teräs7e73eb72016-04-09 17:22:32 +03001266 nexthop_active_update (rn, new_selected, 1);
Timo Teräs0abf6792016-01-15 17:36:29 +02001267
1268 /* Update kernel if FIB entry has changed */
1269 if (old_fib != new_fib
1270 || (new_fib && CHECK_FLAG (new_fib->status, RIB_ENTRY_CHANGED)))
paul718e3742002-12-13 20:15:29 +00001271 {
Timo Teräs0abf6792016-01-15 17:36:29 +02001272 if (old_fib && old_fib != new_fib)
1273 {
Timo Teräs0abf6792016-01-15 17:36:29 +02001274 if (! RIB_SYSTEM_ROUTE (old_fib) && (! new_fib || RIB_SYSTEM_ROUTE (new_fib)))
1275 rib_update_kernel (rn, old_fib, NULL);
Timo Teräs325823a2016-01-15 17:36:31 +02001276 UNSET_FLAG (old_fib->status, RIB_ENTRY_SELECTED_FIB);
Timo Teräs0abf6792016-01-15 17:36:29 +02001277 }
1278
1279 if (new_fib)
1280 {
1281 /* Install new or replace existing FIB entry */
Timo Teräs325823a2016-01-15 17:36:31 +02001282 SET_FLAG (new_fib->status, RIB_ENTRY_SELECTED_FIB);
Timo Teräs0abf6792016-01-15 17:36:29 +02001283 if (! RIB_SYSTEM_ROUTE (new_fib))
1284 rib_update_kernel (rn, old_fib, new_fib);
1285 }
1286
1287 if (info->safi == SAFI_UNICAST)
1288 zfpm_trigger_update (rn, "updating existing route");
1289 }
1290 else if (old_fib == new_fib && new_fib && ! RIB_SYSTEM_ROUTE (new_fib))
1291 {
1292 /* Housekeeping code to deal with race conditions in kernel with
1293 * linux netlink reporting interface up before IPv4 or IPv6 protocol
1294 * is ready to add routes. This makes sure routes are IN the kernel.
1295 */
1296 for (ALL_NEXTHOPS_RO(new_fib->nexthop, nexthop, tnexthop, recursing))
1297 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1298 {
1299 installed = 1;
1300 break;
1301 }
1302 if (! installed)
1303 rib_update_kernel (rn, NULL, new_fib);
1304 }
1305
Timo Teräs325823a2016-01-15 17:36:31 +02001306 /* Redistribute SELECTED entry */
1307 if (old_selected != new_selected
1308 || (new_selected && CHECK_FLAG (new_selected->status, RIB_ENTRY_CHANGED)))
1309 {
1310 if (old_selected)
1311 {
1312 if (! new_selected)
1313 redistribute_delete (&rn->p, old_selected);
1314 if (old_selected != new_selected)
1315 UNSET_FLAG (old_selected->flags, ZEBRA_FLAG_SELECTED);
1316 }
1317
1318 if (new_selected)
1319 {
1320 /* Install new or replace existing redistributed entry */
1321 SET_FLAG (new_selected->flags, ZEBRA_FLAG_SELECTED);
1322 redistribute_add (&rn->p, new_selected);
1323 }
1324 }
1325
Timo Teräs0abf6792016-01-15 17:36:29 +02001326 /* Remove all RIB entries queued for removal */
1327 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
1328 {
1329 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
paul4d38fdb2005-04-28 17:35:14 +00001330 {
Timo Teräs0abf6792016-01-15 17:36:29 +02001331 if (IS_ZEBRA_DEBUG_RIB)
1332 rnode_debug (rn, "rn %p, removing rib %p",
1333 (void *)rn, (void *)rib);
1334 rib_unlink (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001335 }
paul718e3742002-12-13 20:15:29 +00001336 }
1337
Paul Jakma6d691122006-07-27 21:49:00 +00001338 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lampartereed3c482015-03-03 08:51:53 +01001339 rnode_debug (rn, "rn %p dequeued", (void *)rn);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001340
1341 /*
1342 * Check if the dest can be deleted now.
1343 */
1344 rib_gc_dest (rn);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001345}
1346
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001347/* Take a list of route_node structs and return 1, if there was a record
1348 * picked from it and processed by rib_process(). Don't process more,
1349 * than one RN record; operate only in the specified sub-queue.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001350 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001351static unsigned int
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001352process_subq (struct list * subq, u_char qindex)
1353{
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001354 struct listnode *lnode = listhead (subq);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001355 struct route_node *rnode;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001356
1357 if (!lnode)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001358 return 0;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001359
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001360 rnode = listgetdata (lnode);
1361 rib_process (rnode);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001362
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001363 if (rnode->info)
1364 UNSET_FLAG (rib_dest_from_rnode (rnode)->flags, RIB_ROUTE_QUEUED (qindex));
1365
Chris Caputo67b94672009-07-18 04:02:26 +00001366#if 0
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001367 else
1368 {
1369 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1370 __func__, rnode, rnode->lock);
1371 zlog_backtrace(LOG_DEBUG);
1372 }
Chris Caputo67b94672009-07-18 04:02:26 +00001373#endif
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001374 route_unlock_node (rnode);
1375 list_delete_node (subq, lnode);
1376 return 1;
1377}
1378
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05001379/*
1380 * All meta queues have been processed. Trigger next-hop evaluation.
1381 */
1382static void
1383meta_queue_process_complete (struct work_queue *dummy)
1384{
1385 zebra_evaluate_rnh_table(0, AF_INET);
1386#ifdef HAVE_IPV6
1387 zebra_evaluate_rnh_table(0, AF_INET6);
1388#endif /* HAVE_IPV6 */
1389}
1390
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001391/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1392 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1393 * is pointed to the meta queue structure.
1394 */
1395static wq_item_status
1396meta_queue_process (struct work_queue *dummy, void *data)
1397{
1398 struct meta_queue * mq = data;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001399 unsigned i;
1400
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001401 for (i = 0; i < MQ_SIZE; i++)
1402 if (process_subq (mq->subq[i], i))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001403 {
1404 mq->size--;
1405 break;
1406 }
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001407 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1408}
1409
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001410/*
1411 * Map from rib types to queue type (priority) in meta queue
1412 */
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001413static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
1414 [ZEBRA_ROUTE_SYSTEM] = 4,
1415 [ZEBRA_ROUTE_KERNEL] = 0,
1416 [ZEBRA_ROUTE_CONNECT] = 0,
1417 [ZEBRA_ROUTE_STATIC] = 1,
1418 [ZEBRA_ROUTE_RIP] = 2,
1419 [ZEBRA_ROUTE_RIPNG] = 2,
1420 [ZEBRA_ROUTE_OSPF] = 2,
1421 [ZEBRA_ROUTE_OSPF6] = 2,
1422 [ZEBRA_ROUTE_ISIS] = 2,
1423 [ZEBRA_ROUTE_BGP] = 3,
1424 [ZEBRA_ROUTE_HSLS] = 4,
Paul Jakma57345092011-12-25 17:52:09 +01001425 [ZEBRA_ROUTE_BABEL] = 2,
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001426};
1427
1428/* Look into the RN and queue it into one or more priority queues,
1429 * increasing the size for each data push done.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001430 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001431static void
1432rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001433{
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001434 struct rib *rib;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001435
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001436 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001437 {
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001438 u_char qindex = meta_queue_map[rib->type];
1439
1440 /* Invariant: at this point we always have rn->info set. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001441 if (CHECK_FLAG (rib_dest_from_rnode (rn)->flags,
1442 RIB_ROUTE_QUEUED (qindex)))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001443 {
1444 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lamparter94813742014-04-24 20:22:53 +02001445 rnode_debug (rn, "rn %p is already queued in sub-queue %u",
David Lampartereed3c482015-03-03 08:51:53 +01001446 (void *)rn, qindex);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001447 continue;
1448 }
1449
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001450 SET_FLAG (rib_dest_from_rnode (rn)->flags, RIB_ROUTE_QUEUED (qindex));
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001451 listnode_add (mq->subq[qindex], rn);
1452 route_lock_node (rn);
1453 mq->size++;
1454
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001455 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lamparter94813742014-04-24 20:22:53 +02001456 rnode_debug (rn, "queued rn %p into sub-queue %u",
David Lampartereed3c482015-03-03 08:51:53 +01001457 (void *)rn, qindex);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001458 }
paul4d38fdb2005-04-28 17:35:14 +00001459}
1460
Paul Jakma6d691122006-07-27 21:49:00 +00001461/* Add route_node to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001462static void
Paul Jakma6d691122006-07-27 21:49:00 +00001463rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
paul4d38fdb2005-04-28 17:35:14 +00001464{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001465 assert (zebra && rn);
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001466
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001467 /* Pointless to queue a route_node with no RIB entries to add or remove */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001468 if (!rnode_to_ribs (rn))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001469 {
1470 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
David Lampartereed3c482015-03-03 08:51:53 +01001471 __func__, (void *)rn, rn->lock);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001472 zlog_backtrace(LOG_DEBUG);
1473 return;
1474 }
1475
1476 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lamparter94813742014-04-24 20:22:53 +02001477 rnode_info (rn, "work queue added");
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001478
1479 assert (zebra);
1480
1481 if (zebra->ribq == NULL)
1482 {
1483 zlog_err ("%s: work_queue does not exist!", __func__);
1484 return;
Paul Jakma6d691122006-07-27 21:49:00 +00001485 }
paul4d38fdb2005-04-28 17:35:14 +00001486
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001487 /*
1488 * The RIB queue should normally be either empty or holding the only
1489 * work_queue_item element. In the latter case this element would
1490 * hold a pointer to the meta queue structure, which must be used to
1491 * actually queue the route nodes to process. So create the MQ
1492 * holder, if necessary, then push the work into it in any case.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001493 * This semantics was introduced after 0.99.9 release.
1494 */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001495 if (!zebra->ribq->items->count)
1496 work_queue_add (zebra->ribq, zebra->mq);
1497
1498 rib_meta_queue_add (zebra->mq, rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001499
1500 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lampartereed3c482015-03-03 08:51:53 +01001501 rnode_debug (rn, "rn %p queued", (void *)rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001502
1503 return;
paul4d38fdb2005-04-28 17:35:14 +00001504}
1505
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001506/* Create new meta queue.
1507 A destructor function doesn't seem to be necessary here.
1508 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001509static struct meta_queue *
1510meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001511{
1512 struct meta_queue *new;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001513 unsigned i;
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001514
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001515 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1516 assert(new);
1517
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001518 for (i = 0; i < MQ_SIZE; i++)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001519 {
1520 new->subq[i] = list_new ();
1521 assert(new->subq[i]);
1522 }
1523
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001524 return new;
1525}
1526
paul4d38fdb2005-04-28 17:35:14 +00001527/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001528static void
paul4d38fdb2005-04-28 17:35:14 +00001529rib_queue_init (struct zebra_t *zebra)
1530{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001531 assert (zebra);
1532
paul4d38fdb2005-04-28 17:35:14 +00001533 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001534 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001535 {
Paul Jakma6d691122006-07-27 21:49:00 +00001536 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001537 return;
1538 }
1539
1540 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001541 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001542 zebra->ribq->spec.errorfunc = NULL;
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05001543 zebra->ribq->spec.completion_func = &meta_queue_process_complete;
paul4d38fdb2005-04-28 17:35:14 +00001544 /* XXX: TODO: These should be runtime configurable via vty */
1545 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001546 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001547
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001548 if (!(zebra->mq = meta_queue_new ()))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001549 {
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001550 zlog_err ("%s: could not initialise meta queue!", __func__);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001551 return;
1552 }
1553 return;
paul718e3742002-12-13 20:15:29 +00001554}
1555
Paul Jakma6d691122006-07-27 21:49:00 +00001556/* RIB updates are processed via a queue of pointers to route_nodes.
1557 *
1558 * The queue length is bounded by the maximal size of the routing table,
1559 * as a route_node will not be requeued, if already queued.
1560 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001561 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05001562 * state, or static_install_route (when an existing RIB is updated)
Paul Jakma3c0755d2006-12-08 00:53:14 +00001563 * and then submit route_node to queue for best-path selection later.
1564 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001565 *
1566 * Deleted RIBs are reaped during best-path selection.
1567 *
1568 * rib_addnode
1569 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001570 * |-------->| | best RIB, if required
1571 * | |
1572 * static_install->|->rib_addqueue...... -> rib_process
1573 * | |
1574 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001575 * |-> set RIB_ENTRY_REMOVE |
1576 * rib_delnode (RIB freed)
1577 *
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001578 * The 'info' pointer of a route_node points to a rib_dest_t
1579 * ('dest'). Queueing state for a route_node is kept on the dest. The
1580 * dest is created on-demand by rib_link() and is kept around at least
1581 * as long as there are ribs hanging off it (@see rib_gc_dest()).
Paul Jakma6d691122006-07-27 21:49:00 +00001582 *
1583 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1584 *
1585 * - route_nodes: refcounted by:
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001586 * - dest attached to route_node:
1587 * - managed by: rib_link/rib_gc_dest
Paul Jakma6d691122006-07-27 21:49:00 +00001588 * - route_node processing queue
1589 * - managed by: rib_addqueue, rib_process.
1590 *
1591 */
1592
paul718e3742002-12-13 20:15:29 +00001593/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001594static void
Paul Jakma6d691122006-07-27 21:49:00 +00001595rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001596{
1597 struct rib *head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001598 rib_dest_t *dest;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001599
paul4d38fdb2005-04-28 17:35:14 +00001600 assert (rib && rn);
1601
Paul Jakma6d691122006-07-27 21:49:00 +00001602 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001603 rnode_debug (rn, "rn %p, rib %p", (void *)rn, (void *)rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001604
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001605 dest = rib_dest_from_rnode (rn);
1606 if (!dest)
Paul Jakma6d691122006-07-27 21:49:00 +00001607 {
1608 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001609 rnode_debug (rn, "adding dest to table");
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001610
1611 dest = XCALLOC (MTYPE_RIB_DEST, sizeof (rib_dest_t));
1612 route_lock_node (rn); /* rn route table reference */
1613 rn->info = dest;
1614 dest->rnode = rn;
1615 }
1616
1617 head = dest->routes;
1618 if (head)
1619 {
Paul Jakma6d691122006-07-27 21:49:00 +00001620 head->prev = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001621 }
paul718e3742002-12-13 20:15:29 +00001622 rib->next = head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001623 dest->routes = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001624 rib_queue_add (&zebrad, rn);
1625}
1626
1627static void
1628rib_addnode (struct route_node *rn, struct rib *rib)
1629{
1630 /* RIB node has been un-removed before route-node is processed.
1631 * route_node must hence already be on the queue for processing..
1632 */
1633 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1634 {
1635 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001636 rnode_debug (rn, "rn %p, un-removed rib %p", (void *)rn, (void *)rib);
David Lamparter94813742014-04-24 20:22:53 +02001637
Paul Jakma6d691122006-07-27 21:49:00 +00001638 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1639 return;
1640 }
1641 rib_link (rn, rib);
1642}
1643
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001644/*
1645 * rib_unlink
1646 *
1647 * Detach a rib structure from a route_node.
1648 *
1649 * Note that a call to rib_unlink() should be followed by a call to
1650 * rib_gc_dest() at some point. This allows a rib_dest_t that is no
1651 * longer required to be deleted.
1652 */
Paul Jakma6d691122006-07-27 21:49:00 +00001653static void
1654rib_unlink (struct route_node *rn, struct rib *rib)
1655{
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001656 rib_dest_t *dest;
Paul Jakma6d691122006-07-27 21:49:00 +00001657
1658 assert (rn && rib);
1659
1660 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001661 rnode_debug (rn, "rn %p, rib %p", (void *)rn, (void *)rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001662
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001663 dest = rib_dest_from_rnode (rn);
1664
Paul Jakma6d691122006-07-27 21:49:00 +00001665 if (rib->next)
1666 rib->next->prev = rib->prev;
1667
1668 if (rib->prev)
1669 rib->prev->next = rib->next;
1670 else
1671 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001672 dest->routes = rib->next;
Paul Jakma6d691122006-07-27 21:49:00 +00001673 }
1674
1675 /* free RIB and nexthops */
Christian Frankefa713d92013-07-05 15:35:37 +00001676 nexthops_free(rib->nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00001677 XFREE (MTYPE_RIB, rib);
1678
paul718e3742002-12-13 20:15:29 +00001679}
1680
paula1ac18c2005-06-28 17:17:12 +00001681static void
paul718e3742002-12-13 20:15:29 +00001682rib_delnode (struct route_node *rn, struct rib *rib)
1683{
Paul Jakma6d691122006-07-27 21:49:00 +00001684 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001685 rnode_debug (rn, "rn %p, rib %p, removing", (void *)rn, (void *)rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001686 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1687 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001688}
1689
1690int
1691rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001692 struct in_addr *gate, struct in_addr *src,
Paul Jakma9099f9b2016-01-18 10:12:10 +00001693 ifindex_t ifindex, vrf_id_t vrf_id, int table_id,
Timo Teräsb11f3b52015-11-02 16:50:07 +02001694 u_int32_t metric, u_int32_t mtu, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001695{
1696 struct rib *rib;
1697 struct rib *same = NULL;
1698 struct route_table *table;
1699 struct route_node *rn;
1700 struct nexthop *nexthop;
1701
1702 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02001703 table = zebra_vrf_table (AFI_IP, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00001704 if (! table)
1705 return 0;
1706
1707 /* Make it sure prefixlen is applied to the prefix. */
1708 apply_mask_ipv4 (p);
1709
1710 /* Set default distance by route type. */
1711 if (distance == 0)
1712 {
Balaji.G837d16c2012-09-26 14:09:10 +05301713 if ((unsigned)type >= array_size(route_info))
David Lamparter7052f222009-08-27 00:28:28 +02001714 distance = 150;
1715 else
1716 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00001717
1718 /* iBGP distance is 200. */
1719 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1720 distance = 200;
1721 }
1722
1723 /* Lookup route node.*/
1724 rn = route_node_get (table, (struct prefix *) p);
1725
1726 /* If same type of route are installed, treat it as a implicit
1727 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001728 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00001729 {
Paul Jakma6d691122006-07-27 21:49:00 +00001730 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1731 continue;
1732
hassoebf1ead2005-09-21 14:58:20 +00001733 if (rib->type != type)
1734 continue;
1735 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001736 {
1737 same = rib;
1738 break;
1739 }
hassoebf1ead2005-09-21 14:58:20 +00001740 /* Duplicate connected route comes in. */
1741 else if ((nexthop = rib->nexthop) &&
1742 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001743 nexthop->ifindex == ifindex &&
1744 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001745 {
1746 rib->refcnt++;
1747 return 0 ;
1748 }
paul718e3742002-12-13 20:15:29 +00001749 }
1750
1751 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001752 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001753 rib->type = type;
1754 rib->distance = distance;
1755 rib->flags = flags;
1756 rib->metric = metric;
Timo Teräsb11f3b52015-11-02 16:50:07 +02001757 rib->mtu = mtu;
Feng Lu0d0686f2015-05-22 11:40:02 +02001758 rib->vrf_id = vrf_id;
1759 rib->table = table_id;
paul718e3742002-12-13 20:15:29 +00001760 rib->nexthop_num = 0;
1761 rib->uptime = time (NULL);
1762
1763 /* Nexthop settings. */
1764 if (gate)
1765 {
1766 if (ifindex)
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05001767 rib_nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001768 else
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05001769 rib_nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001770 }
1771 else
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05001772 rib_nexthop_ifindex_add (rib, ifindex);
paul718e3742002-12-13 20:15:29 +00001773
1774 /* If this route is kernel route, set FIB flag to the route. */
1775 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1776 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1777 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1778
1779 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001780 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001781 zlog_debug ("%s: calling rib_addnode (%p, %p)",
1782 __func__, (void *)rn, (void *)rib);
paul718e3742002-12-13 20:15:29 +00001783 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001784
paul718e3742002-12-13 20:15:29 +00001785 /* Free implicit route.*/
1786 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001787 {
1788 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001789 zlog_debug ("%s: calling rib_delnode (%p, %p)",
1790 __func__, (void *)rn, (void *)rib);
paul4d38fdb2005-04-28 17:35:14 +00001791 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001792 }
paul4d38fdb2005-04-28 17:35:14 +00001793
1794 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001795 return 0;
1796}
1797
Denis Ovsienkodc958242007-08-13 16:03:06 +00001798/* This function dumps the contents of a given RIB entry into
1799 * standard debug log. Calling function name and IP prefix in
1800 * question are passed as 1st and 2nd arguments.
1801 */
1802
David Lamparterf7bf4152013-10-22 17:10:21 +00001803void _rib_dump (const char * func,
1804 union prefix46constptr pp, const struct rib * rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001805{
David Lamparterf7bf4152013-10-22 17:10:21 +00001806 const struct prefix *p = pp.p;
Timo Teräsbe6335d2015-05-23 11:08:41 +03001807 char straddr[PREFIX_STRLEN];
Christian Frankefa713d92013-07-05 15:35:37 +00001808 struct nexthop *nexthop, *tnexthop;
1809 int recursing;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001810
Feng Lu0d0686f2015-05-22 11:40:02 +02001811 zlog_debug ("%s: dumping RIB entry %p for %s vrf %u", func, (void *)rib,
1812 prefix2str(p, straddr, sizeof(straddr)), rib->vrf_id);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001813 zlog_debug
1814 (
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001815 "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
Denis Ovsienkodc958242007-08-13 16:03:06 +00001816 func,
1817 rib->refcnt,
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001818 (unsigned long) rib->uptime,
Denis Ovsienkodc958242007-08-13 16:03:06 +00001819 rib->type,
1820 rib->table
1821 );
1822 zlog_debug
1823 (
1824 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1825 func,
1826 rib->metric,
1827 rib->distance,
1828 rib->flags,
1829 rib->status
1830 );
1831 zlog_debug
1832 (
1833 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1834 func,
1835 rib->nexthop_num,
1836 rib->nexthop_active_num,
1837 rib->nexthop_fib_num
1838 );
Vincent Bernatfed643f2012-10-23 16:00:42 +00001839
Christian Frankefa713d92013-07-05 15:35:37 +00001840 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1841 {
Vincent Bernatfed643f2012-10-23 16:00:42 +00001842 inet_ntop (p->family, &nexthop->gate, straddr, INET6_ADDRSTRLEN);
Christian Frankefa713d92013-07-05 15:35:37 +00001843 zlog_debug
1844 (
1845 "%s: %s %s with flags %s%s%s",
1846 func,
1847 (recursing ? " NH" : "NH"),
1848 straddr,
1849 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1850 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1851 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1852 );
1853 }
Denis Ovsienkodc958242007-08-13 16:03:06 +00001854 zlog_debug ("%s: dump complete", func);
1855}
1856
1857/* This is an exported helper to rtm_read() to dump the strange
1858 * RIB entry found by rib_lookup_ipv4_route()
1859 */
1860
1861void rib_lookup_and_dump (struct prefix_ipv4 * p)
1862{
1863 struct route_table *table;
1864 struct route_node *rn;
1865 struct rib *rib;
1866 char prefix_buf[INET_ADDRSTRLEN];
1867
1868 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02001869 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001870 if (! table)
1871 {
Feng Lu41f44a22015-05-22 11:39:56 +02001872 zlog_err ("%s: zebra_vrf_table() returned NULL", __func__);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001873 return;
1874 }
1875
Denis Ovsienkodc958242007-08-13 16:03:06 +00001876 /* Scan the RIB table for exactly matching RIB entry. */
1877 rn = route_node_lookup (table, (struct prefix *) p);
1878
1879 /* No route for this prefix. */
1880 if (! rn)
1881 {
Timo Teräsbe6335d2015-05-23 11:08:41 +03001882 zlog_debug ("%s: lookup failed for %s", __func__,
1883 prefix2str((struct prefix*) p, prefix_buf, sizeof(prefix_buf)));
Denis Ovsienkodc958242007-08-13 16:03:06 +00001884 return;
1885 }
1886
1887 /* Unlock node. */
1888 route_unlock_node (rn);
1889
1890 /* let's go */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001891 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001892 {
1893 zlog_debug
1894 (
1895 "%s: rn %p, rib %p: %s, %s",
1896 __func__,
David Lampartereed3c482015-03-03 08:51:53 +01001897 (void *)rn,
1898 (void *)rib,
Denis Ovsienkodc958242007-08-13 16:03:06 +00001899 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
1900 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
1901 );
David Lamparterf7bf4152013-10-22 17:10:21 +00001902 rib_dump (p, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001903 }
1904}
1905
paul718e3742002-12-13 20:15:29 +00001906int
G.Balajicddf3912011-11-26 21:59:32 +04001907rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001908{
1909 struct route_table *table;
1910 struct route_node *rn;
1911 struct rib *same;
1912 struct nexthop *nexthop;
Dinesh Dutt9ae85522015-05-19 17:47:22 -07001913 int ret = 0;
paul4d38fdb2005-04-28 17:35:14 +00001914
paul718e3742002-12-13 20:15:29 +00001915 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02001916 table = zebra_vrf_table (AFI_IP, safi, rib->vrf_id);
paul718e3742002-12-13 20:15:29 +00001917 if (! table)
1918 return 0;
G.Balajicddf3912011-11-26 21:59:32 +04001919
paul718e3742002-12-13 20:15:29 +00001920 /* Make it sure prefixlen is applied to the prefix. */
1921 apply_mask_ipv4 (p);
1922
1923 /* Set default distance by route type. */
1924 if (rib->distance == 0)
1925 {
1926 rib->distance = route_info[rib->type].distance;
1927
1928 /* iBGP distance is 200. */
1929 if (rib->type == ZEBRA_ROUTE_BGP
1930 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1931 rib->distance = 200;
1932 }
1933
1934 /* Lookup route node.*/
1935 rn = route_node_get (table, (struct prefix *) p);
1936
1937 /* If same type of route are installed, treat it as a implicit
1938 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001939 RNODE_FOREACH_RIB (rn, same)
paul718e3742002-12-13 20:15:29 +00001940 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00001941 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00001942 continue;
1943
paul718e3742002-12-13 20:15:29 +00001944 if (same->type == rib->type && same->table == rib->table
1945 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001946 break;
paul718e3742002-12-13 20:15:29 +00001947 }
paul4d38fdb2005-04-28 17:35:14 +00001948
paul718e3742002-12-13 20:15:29 +00001949 /* If this route is kernel route, set FIB flag to the route. */
1950 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
1951 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1952 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1953
1954 /* Link new rib to node.*/
1955 rib_addnode (rn, rib);
Dinesh Dutt9ae85522015-05-19 17:47:22 -07001956 ret = 1;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001957 if (IS_ZEBRA_DEBUG_RIB)
1958 {
1959 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01001960 __func__, (void *)rn, (void *)rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00001961 rib_dump (p, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001962 }
paul718e3742002-12-13 20:15:29 +00001963
paul718e3742002-12-13 20:15:29 +00001964 /* Free implicit route.*/
1965 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001966 {
1967 if (IS_ZEBRA_DEBUG_RIB)
1968 {
1969 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01001970 __func__, (void *)rn, (void *)same);
David Lamparterf7bf4152013-10-22 17:10:21 +00001971 rib_dump (p, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001972 }
paul4d38fdb2005-04-28 17:35:14 +00001973 rib_delnode (rn, same);
Dinesh Dutt9ae85522015-05-19 17:47:22 -07001974 ret = -1;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001975 }
paul4d38fdb2005-04-28 17:35:14 +00001976
1977 route_unlock_node (rn);
Dinesh Dutt9ae85522015-05-19 17:47:22 -07001978 return ret;
paul718e3742002-12-13 20:15:29 +00001979}
1980
hassoebf1ead2005-09-21 14:58:20 +00001981/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00001982int
1983rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma9099f9b2016-01-18 10:12:10 +00001984 struct in_addr *gate, ifindex_t ifindex,
1985 vrf_id_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001986{
1987 struct route_table *table;
1988 struct route_node *rn;
1989 struct rib *rib;
1990 struct rib *fib = NULL;
1991 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00001992 struct nexthop *nexthop, *tnexthop;
1993 int recursing;
Timo Teräsbe6335d2015-05-23 11:08:41 +03001994 char buf1[PREFIX_STRLEN];
Stephen Hemminger81cce012009-04-28 14:28:00 -07001995 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00001996
1997 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02001998 table = zebra_vrf_table (AFI_IP, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00001999 if (! table)
2000 return 0;
2001
2002 /* Apply mask. */
2003 apply_mask_ipv4 (p);
2004
Christian Frankeb52aef12013-11-27 17:06:15 +00002005 if (IS_ZEBRA_DEBUG_KERNEL)
2006 {
2007 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002008 zlog_debug ("rib_delete_ipv4(): route delete %s vrf %u via %s ifindex %d",
2009 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Christian Frankeb52aef12013-11-27 17:06:15 +00002010 inet_ntoa (*gate),
2011 ifindex);
2012 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002013 zlog_debug ("rib_delete_ipv4(): route delete %s vrf %u ifindex %d",
2014 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Christian Frankeb52aef12013-11-27 17:06:15 +00002015 ifindex);
2016 }
paul5ec90d22003-06-19 01:41:37 +00002017
paul718e3742002-12-13 20:15:29 +00002018 /* Lookup route node. */
2019 rn = route_node_lookup (table, (struct prefix *) p);
2020 if (! rn)
2021 {
2022 if (IS_ZEBRA_DEBUG_KERNEL)
2023 {
2024 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002025 zlog_debug ("route %s vrf %u via %s ifindex %d doesn't exist in rib",
2026 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002027 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002028 ifindex);
2029 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002030 zlog_debug ("route %s vrf %u ifindex %d doesn't exist in rib",
2031 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002032 ifindex);
2033 }
2034 return ZEBRA_ERR_RTNOEXIST;
2035 }
2036
2037 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002038 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002039 {
Paul Jakma6d691122006-07-27 21:49:00 +00002040 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2041 continue;
2042
Timo Teräs325823a2016-01-15 17:36:31 +02002043 if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB))
paul718e3742002-12-13 20:15:29 +00002044 fib = rib;
2045
hassoebf1ead2005-09-21 14:58:20 +00002046 if (rib->type != type)
2047 continue;
2048 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002049 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002050 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002051 if (nexthop->ifindex != ifindex)
2052 continue;
hassoebf1ead2005-09-21 14:58:20 +00002053 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002054 {
hassoebf1ead2005-09-21 14:58:20 +00002055 rib->refcnt--;
2056 route_unlock_node (rn);
2057 route_unlock_node (rn);
2058 return 0;
paul718e3742002-12-13 20:15:29 +00002059 }
hassoebf1ead2005-09-21 14:58:20 +00002060 same = rib;
2061 break;
paul718e3742002-12-13 20:15:29 +00002062 }
hassoebf1ead2005-09-21 14:58:20 +00002063 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002064 else
paul5ec90d22003-06-19 01:41:37 +00002065 {
Christian Frankefa713d92013-07-05 15:35:37 +00002066 if (gate == NULL)
2067 {
2068 same = rib;
2069 break;
2070 }
2071 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2072 if (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate))
2073 {
2074 same = rib;
2075 break;
2076 }
2077 if (same)
2078 break;
2079 }
paul718e3742002-12-13 20:15:29 +00002080 }
paul718e3742002-12-13 20:15:29 +00002081 /* If same type of route can't be found and this message is from
2082 kernel. */
2083 if (! same)
2084 {
James Li92992c62015-11-09 20:21:57 -05002085 if (fib && type == ZEBRA_ROUTE_KERNEL &&
2086 CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE))
2087 {
2088 if (IS_ZEBRA_DEBUG_KERNEL)
2089 {
2090 zlog_debug ("Zebra route %s/%d was deleted by others from kernel",
2091 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
2092 p->prefixlen);
2093 }
2094 /* This means someone else, other than Zebra, has deleted
2095 * a Zebra router from the kernel. We will add it back */
2096 rib_update_kernel(rn, NULL, fib);
2097 }
paul718e3742002-12-13 20:15:29 +00002098 else
2099 {
2100 if (IS_ZEBRA_DEBUG_KERNEL)
2101 {
2102 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002103 zlog_debug ("route %s vrf %u via %s ifindex %d type %d "
2104 "doesn't exist in rib",
2105 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002106 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002107 ifindex,
2108 type);
2109 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002110 zlog_debug ("route %s vrf %u ifindex %d type %d doesn't exist in rib",
2111 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002112 ifindex,
2113 type);
2114 }
2115 route_unlock_node (rn);
2116 return ZEBRA_ERR_RTNOEXIST;
2117 }
2118 }
paul4d38fdb2005-04-28 17:35:14 +00002119
paul718e3742002-12-13 20:15:29 +00002120 if (same)
2121 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002122
paul718e3742002-12-13 20:15:29 +00002123 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002124 return 0;
2125}
David Lamparter6b0655a2014-06-04 06:53:35 +02002126
paul718e3742002-12-13 20:15:29 +00002127/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002128static void
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002129static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si)
paul718e3742002-12-13 20:15:29 +00002130{
2131 struct rib *rib;
2132 struct route_node *rn;
2133 struct route_table *table;
2134
2135 /* Lookup table. */
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002136 table = zebra_vrf_table (afi, safi, si->vrf_id);
paul718e3742002-12-13 20:15:29 +00002137 if (! table)
2138 return;
2139
2140 /* Lookup existing route */
2141 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002142 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002143 {
2144 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2145 continue;
2146
2147 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2148 break;
2149 }
paul718e3742002-12-13 20:15:29 +00002150
2151 if (rib)
2152 {
Piotr Chytłade24f822007-06-28 00:09:28 +02002153 /* if tag value changed , update old value in RIB */
2154 if (rib->tag != si->tag)
2155 rib->tag = si->tag;
2156
paul718e3742002-12-13 20:15:29 +00002157 /* Same distance static route is there. Update it with new
2158 nexthop. */
paul718e3742002-12-13 20:15:29 +00002159 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002160 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002161 {
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002162 case STATIC_IPV4_GATEWAY:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002163 rib_nexthop_ipv4_add (rib, &si->addr.ipv4, NULL);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002164 break;
2165 case STATIC_IPV4_IFNAME:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002166 rib_nexthop_ifname_add (rib, si->ifname);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002167 break;
2168 case STATIC_IPV4_BLACKHOLE:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002169 rib_nexthop_blackhole_add (rib);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002170 break;
2171 case STATIC_IPV6_GATEWAY:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002172 rib_nexthop_ipv6_add (rib, &si->addr.ipv6);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002173 break;
2174 case STATIC_IPV6_IFNAME:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002175 rib_nexthop_ifname_add (rib, si->ifname);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002176 break;
2177 case STATIC_IPV6_GATEWAY_IFNAME:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002178 rib_nexthop_ipv6_ifname_add (rib, &si->addr.ipv6, si->ifname);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002179 break;
paul4d38fdb2005-04-28 17:35:14 +00002180 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002181 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002182 }
2183 else
2184 {
2185 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002186 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2187
paul718e3742002-12-13 20:15:29 +00002188 rib->type = ZEBRA_ROUTE_STATIC;
2189 rib->distance = si->distance;
2190 rib->metric = 0;
Feng Lu7aaf4ea2015-05-22 11:40:06 +02002191 rib->vrf_id = si->vrf_id;
Nolan Leakeb0145dd2012-09-13 17:17:31 +00002192 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002193 rib->nexthop_num = 0;
Piotr Chytłade24f822007-06-28 00:09:28 +02002194 rib->tag = si->tag;
paul718e3742002-12-13 20:15:29 +00002195
2196 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002197 {
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002198 case STATIC_IPV4_GATEWAY:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002199 rib_nexthop_ipv4_add (rib, &si->addr.ipv4, NULL);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002200 break;
2201 case STATIC_IPV4_IFNAME:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002202 rib_nexthop_ifname_add (rib, si->ifname);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002203 break;
2204 case STATIC_IPV4_BLACKHOLE:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002205 rib_nexthop_blackhole_add (rib);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002206 break;
2207 case STATIC_IPV6_GATEWAY:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002208 rib_nexthop_ipv6_add (rib, &si->addr.ipv6);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002209 break;
2210 case STATIC_IPV6_IFNAME:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002211 rib_nexthop_ifname_add (rib, si->ifname);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002212 break;
2213 case STATIC_IPV6_GATEWAY_IFNAME:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002214 rib_nexthop_ipv6_ifname_add (rib, &si->addr.ipv6, si->ifname);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002215 break;
paul7021c422003-07-15 12:52:22 +00002216 }
paul718e3742002-12-13 20:15:29 +00002217
hasso81dfcaa2003-05-25 19:21:25 +00002218 /* Save the flags of this static routes (reject, blackhole) */
2219 rib->flags = si->flags;
2220
paul718e3742002-12-13 20:15:29 +00002221 /* Link this rib to the tree. */
2222 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002223 }
2224}
2225
paula1ac18c2005-06-28 17:17:12 +00002226static int
Donald Sharpa979ab72015-11-04 13:26:38 -05002227static_nexthop_same (struct nexthop *nexthop, struct static_route *si)
paul718e3742002-12-13 20:15:29 +00002228{
2229 if (nexthop->type == NEXTHOP_TYPE_IPV4
2230 && si->type == STATIC_IPV4_GATEWAY
Donald Sharpd4c27d62015-11-04 13:26:35 -05002231 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->addr.ipv4))
paul718e3742002-12-13 20:15:29 +00002232 return 1;
2233 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2234 && si->type == STATIC_IPV4_IFNAME
Donald Sharpd4c27d62015-11-04 13:26:35 -05002235 && strcmp (nexthop->ifname, si->ifname) == 0)
paul718e3742002-12-13 20:15:29 +00002236 return 1;
paul595db7f2003-05-25 21:35:06 +00002237 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2238 && si->type == STATIC_IPV4_BLACKHOLE)
2239 return 1;
Donald Sharpa979ab72015-11-04 13:26:38 -05002240 if (nexthop->type == NEXTHOP_TYPE_IPV6
2241 && si->type == STATIC_IPV6_GATEWAY
2242 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6))
2243 return 1;
2244 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2245 && si->type == STATIC_IPV6_IFNAME
2246 && strcmp (nexthop->ifname, si->ifname) == 0)
2247 return 1;
2248 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2249 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2250 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6)
2251 && strcmp (nexthop->ifname, si->ifname) == 0)
2252 return 1;
paule8e19462006-01-19 20:16:55 +00002253 return 0;
paul718e3742002-12-13 20:15:29 +00002254}
2255
2256/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002257static void
Donald Sharp949b7192015-11-04 13:26:39 -05002258static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si)
paul718e3742002-12-13 20:15:29 +00002259{
2260 struct route_node *rn;
2261 struct rib *rib;
2262 struct nexthop *nexthop;
2263 struct route_table *table;
2264
2265 /* Lookup table. */
Donald Sharp949b7192015-11-04 13:26:39 -05002266 table = zebra_vrf_table (afi, safi, si->vrf_id);
paul718e3742002-12-13 20:15:29 +00002267 if (! table)
2268 return;
paul4d38fdb2005-04-28 17:35:14 +00002269
paul718e3742002-12-13 20:15:29 +00002270 /* Lookup existing route with type and distance. */
2271 rn = route_node_lookup (table, p);
2272 if (! rn)
2273 return;
2274
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002275 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002276 {
2277 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2278 continue;
2279
Piotr Chytłade24f822007-06-28 00:09:28 +02002280 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance &&
2281 rib->tag == si->tag)
Paul Jakma6d691122006-07-27 21:49:00 +00002282 break;
2283 }
paul718e3742002-12-13 20:15:29 +00002284
2285 if (! rib)
2286 {
2287 route_unlock_node (rn);
2288 return;
2289 }
2290
2291 /* Lookup nexthop. */
2292 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Donald Sharpa979ab72015-11-04 13:26:38 -05002293 if (static_nexthop_same (nexthop, si))
paul718e3742002-12-13 20:15:29 +00002294 break;
2295
2296 /* Can't find nexthop. */
2297 if (! nexthop)
2298 {
2299 route_unlock_node (rn);
2300 return;
2301 }
2302
2303 /* Check nexthop. */
2304 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002305 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002306 else
2307 {
paul6baeb982003-10-28 03:47:15 +00002308 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2309 rib_uninstall (rn, rib);
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002310 rib_nexthop_delete (rib, nexthop);
paul319572c2005-09-21 12:30:08 +00002311 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002312 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002313 }
paul718e3742002-12-13 20:15:29 +00002314 /* Unlock node. */
2315 route_unlock_node (rn);
2316}
2317
paul718e3742002-12-13 20:15:29 +00002318int
Everton Marques33d86db2014-07-14 11:19:00 -03002319static_add_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate,
Paul Jakma96d10602016-07-01 14:23:45 +01002320 const char *ifname, u_char flags, route_tag_t tag,
2321 u_char distance, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002322{
2323 u_char type = 0;
2324 struct route_node *rn;
Donald Sharpd4c27d62015-11-04 13:26:35 -05002325 struct static_route *si;
2326 struct static_route *pp;
2327 struct static_route *cp;
2328 struct static_route *update = NULL;
Feng Lu0d0686f2015-05-22 11:40:02 +02002329 struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
2330 struct route_table *stable = zvrf->stable[AFI_IP][safi];
paul718e3742002-12-13 20:15:29 +00002331
paul718e3742002-12-13 20:15:29 +00002332 if (! stable)
2333 return -1;
2334
2335 /* Lookup static route prefix. */
2336 rn = route_node_get (stable, p);
2337
2338 /* Make flags. */
2339 if (gate)
2340 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002341 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002342 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002343 else
2344 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002345
2346 /* Do nothing if there is a same static route. */
2347 for (si = rn->info; si; si = si->next)
2348 {
2349 if (type == si->type
Donald Sharpd4c27d62015-11-04 13:26:35 -05002350 && (! gate || IPV4_ADDR_SAME (gate, &si->addr.ipv4))
2351 && (! ifname || strcmp (ifname, si->ifname) == 0))
paul718e3742002-12-13 20:15:29 +00002352 {
Piotr Chytłade24f822007-06-28 00:09:28 +02002353 if (distance == si->distance &&
2354 tag == si->tag)
paul718e3742002-12-13 20:15:29 +00002355 {
2356 route_unlock_node (rn);
2357 return 0;
2358 }
2359 else
2360 update = si;
2361 }
2362 }
2363
Piotr Chytłade24f822007-06-28 00:09:28 +02002364 /* Distance or tag changed. */
paul718e3742002-12-13 20:15:29 +00002365 if (update)
Piotr Chytłade24f822007-06-28 00:09:28 +02002366 static_delete_ipv4_safi (safi, p, gate, ifname, update->tag, update->distance, vrf_id);
paul718e3742002-12-13 20:15:29 +00002367
2368 /* Make new static route structure. */
Donald Sharpd4c27d62015-11-04 13:26:35 -05002369 si = XCALLOC (MTYPE_STATIC_ROUTE, sizeof (struct static_route));
paul718e3742002-12-13 20:15:29 +00002370
2371 si->type = type;
2372 si->distance = distance;
Piotr Chytłade24f822007-06-28 00:09:28 +02002373 si->tag = tag;
hasso81dfcaa2003-05-25 19:21:25 +00002374 si->flags = flags;
Feng Lu7aaf4ea2015-05-22 11:40:06 +02002375 si->vrf_id = vrf_id;
paul718e3742002-12-13 20:15:29 +00002376
2377 if (gate)
Donald Sharpd4c27d62015-11-04 13:26:35 -05002378 si->addr.ipv4 = *gate;
paul718e3742002-12-13 20:15:29 +00002379 if (ifname)
David Lamparter23757db2016-02-24 06:26:02 +01002380 si->ifname = XSTRDUP (MTYPE_TMP, ifname);
paul718e3742002-12-13 20:15:29 +00002381
2382 /* Add new static route information to the tree with sort by
2383 distance value and gateway address. */
2384 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2385 {
2386 if (si->distance < cp->distance)
2387 break;
2388 if (si->distance > cp->distance)
2389 continue;
2390 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2391 {
Donald Sharpd4c27d62015-11-04 13:26:35 -05002392 if (ntohl (si->addr.ipv4.s_addr) < ntohl (cp->addr.ipv4.s_addr))
paul718e3742002-12-13 20:15:29 +00002393 break;
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 continue;
2396 }
2397 }
2398
2399 /* Make linked list. */
2400 if (pp)
2401 pp->next = si;
2402 else
2403 rn->info = si;
2404 if (cp)
2405 cp->prev = si;
2406 si->prev = pp;
2407 si->next = cp;
2408
2409 /* Install into rib. */
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002410 static_install_route (AFI_IP, safi, p, si);
paul718e3742002-12-13 20:15:29 +00002411
2412 return 1;
2413}
2414
paul718e3742002-12-13 20:15:29 +00002415int
Everton Marques33d86db2014-07-14 11:19:00 -03002416static_delete_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate,
Paul Jakma96d10602016-07-01 14:23:45 +01002417 const char *ifname, route_tag_t tag, u_char distance,
2418 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002419{
2420 u_char type = 0;
2421 struct route_node *rn;
Donald Sharpd4c27d62015-11-04 13:26:35 -05002422 struct static_route *si;
paul718e3742002-12-13 20:15:29 +00002423 struct route_table *stable;
2424
2425 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02002426 stable = zebra_vrf_static_table (AFI_IP, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002427 if (! stable)
2428 return -1;
2429
2430 /* Lookup static route prefix. */
2431 rn = route_node_lookup (stable, p);
2432 if (! rn)
2433 return 0;
2434
2435 /* Make flags. */
2436 if (gate)
2437 type = STATIC_IPV4_GATEWAY;
2438 else if (ifname)
2439 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002440 else
2441 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002442
2443 /* Find same static route is the tree */
2444 for (si = rn->info; si; si = si->next)
2445 if (type == si->type
Donald Sharpd4c27d62015-11-04 13:26:35 -05002446 && (! gate || IPV4_ADDR_SAME (gate, &si->addr.ipv4))
Piotr Chytłade24f822007-06-28 00:09:28 +02002447 && (! ifname || strcmp (ifname, si->ifname) == 0)
2448 && (! tag || (tag == si->tag)))
paul718e3742002-12-13 20:15:29 +00002449 break;
2450
2451 /* Can't find static route. */
2452 if (! si)
2453 {
2454 route_unlock_node (rn);
2455 return 0;
2456 }
2457
2458 /* Install into rib. */
Donald Sharp949b7192015-11-04 13:26:39 -05002459 static_uninstall_route (AFI_IP, safi, p, si);
paul718e3742002-12-13 20:15:29 +00002460
2461 /* Unlink static route from linked list. */
2462 if (si->prev)
2463 si->prev->next = si->next;
2464 else
2465 rn->info = si->next;
2466 if (si->next)
2467 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002468 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002469
2470 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002471 if (ifname)
Donald Sharpd4c27d62015-11-04 13:26:35 -05002472 XFREE (0, si->ifname);
2473 XFREE (MTYPE_STATIC_ROUTE, si);
paul718e3742002-12-13 20:15:29 +00002474
paul143a3852003-09-29 20:06:13 +00002475 route_unlock_node (rn);
2476
paul718e3742002-12-13 20:15:29 +00002477 return 1;
2478}
2479
paul718e3742002-12-13 20:15:29 +00002480int
2481rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
Paul Jakma9099f9b2016-01-18 10:12:10 +00002482 struct in6_addr *gate, ifindex_t ifindex,
Feng Lu0d0686f2015-05-22 11:40:02 +02002483 vrf_id_t vrf_id, int table_id,
Timo Teräsb11f3b52015-11-02 16:50:07 +02002484 u_int32_t metric, u_int32_t mtu, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002485{
2486 struct rib *rib;
2487 struct rib *same = NULL;
2488 struct route_table *table;
2489 struct route_node *rn;
2490 struct nexthop *nexthop;
2491
paul718e3742002-12-13 20:15:29 +00002492 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02002493 table = zebra_vrf_table (AFI_IP6, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002494 if (! table)
2495 return 0;
2496
2497 /* Make sure mask is applied. */
2498 apply_mask_ipv6 (p);
2499
2500 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002501 if (!distance)
2502 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002503
2504 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2505 distance = 200;
2506
paul718e3742002-12-13 20:15:29 +00002507 /* Lookup route node.*/
2508 rn = route_node_get (table, (struct prefix *) p);
2509
2510 /* If same type of route are installed, treat it as a implicit
2511 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002512 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002513 {
Paul Jakma6d691122006-07-27 21:49:00 +00002514 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2515 continue;
2516
hassoebf1ead2005-09-21 14:58:20 +00002517 if (rib->type != type)
2518 continue;
2519 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002520 {
2521 same = rib;
paul718e3742002-12-13 20:15:29 +00002522 break;
2523 }
hassoebf1ead2005-09-21 14:58:20 +00002524 else if ((nexthop = rib->nexthop) &&
2525 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2526 nexthop->ifindex == ifindex)
2527 {
2528 rib->refcnt++;
2529 return 0;
2530 }
paul718e3742002-12-13 20:15:29 +00002531 }
2532
2533 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002534 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2535
paul718e3742002-12-13 20:15:29 +00002536 rib->type = type;
2537 rib->distance = distance;
2538 rib->flags = flags;
2539 rib->metric = metric;
Timo Teräsb11f3b52015-11-02 16:50:07 +02002540 rib->mtu = mtu;
Feng Lu0d0686f2015-05-22 11:40:02 +02002541 rib->vrf_id = vrf_id;
2542 rib->table = table_id;
paul718e3742002-12-13 20:15:29 +00002543 rib->nexthop_num = 0;
2544 rib->uptime = time (NULL);
2545
2546 /* Nexthop settings. */
2547 if (gate)
2548 {
2549 if (ifindex)
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002550 rib_nexthop_ipv6_ifindex_add (rib, gate, ifindex);
paul718e3742002-12-13 20:15:29 +00002551 else
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002552 rib_nexthop_ipv6_add (rib, gate);
paul718e3742002-12-13 20:15:29 +00002553 }
2554 else
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002555 rib_nexthop_ifindex_add (rib, ifindex);
paul718e3742002-12-13 20:15:29 +00002556
2557 /* If this route is kernel route, set FIB flag to the route. */
2558 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2559 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2560 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2561
2562 /* Link new rib to node.*/
2563 rib_addnode (rn, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002564 if (IS_ZEBRA_DEBUG_RIB)
2565 {
2566 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01002567 __func__, (void *)rn, (void *)rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00002568 rib_dump (p, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002569 }
paul718e3742002-12-13 20:15:29 +00002570
paul718e3742002-12-13 20:15:29 +00002571 /* Free implicit route.*/
2572 if (same)
Vincent Bernatfed643f2012-10-23 16:00:42 +00002573 {
2574 if (IS_ZEBRA_DEBUG_RIB)
2575 {
2576 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01002577 __func__, (void *)rn, (void *)same);
David Lamparterf7bf4152013-10-22 17:10:21 +00002578 rib_dump (p, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002579 }
paul4d38fdb2005-04-28 17:35:14 +00002580 rib_delnode (rn, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002581 }
paul4d38fdb2005-04-28 17:35:14 +00002582
2583 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002584 return 0;
2585}
2586
Ayan Banerjee34c5d892015-11-09 20:14:53 -05002587int
2588rib_add_ipv6_multipath (struct prefix_ipv6 *p, struct rib *rib, safi_t safi)
2589{
2590 struct route_table *table;
2591 struct route_node *rn;
2592 struct rib *same = NULL;
2593 struct nexthop *nexthop;
2594 int ret = 0;
2595
2596 if (!rib)
2597 return 0; /* why are we getting called with NULL rib */
2598
2599 /* Lookup table. */
2600 table = zebra_vrf_table (AFI_IP6, safi, rib->vrf_id);
2601
2602 if (! table)
2603 return 0;
2604
2605 /* Make sure mask is applied. */
2606 apply_mask_ipv6 (p);
2607
2608 /* Set default distance by route type. */
2609 if (rib->distance == 0)
2610 {
2611 rib->distance = route_info[rib->type].distance;
2612
2613 /* iBGP distance is 200. */
2614 if (rib->type == ZEBRA_ROUTE_BGP
2615 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
2616 rib->distance = 200;
2617 }
2618
2619 /* Lookup route node.*/
2620 rn = route_node_get (table, (struct prefix *) p);
2621
2622 /* If same type of route are installed, treat it as a implicit
2623 withdraw. */
2624 RNODE_FOREACH_RIB (rn, same) {
2625 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED)) {
2626 continue;
2627 }
2628 if (same->type != rib->type) {
2629 continue;
2630 }
2631
2632 if (same->table != rib->table) {
2633 continue;
2634 }
2635 if (same->type != ZEBRA_ROUTE_CONNECT) {
2636 break;
2637 }
2638 }
2639
2640 /* If this route is kernel route, set FIB flag to the route. */
2641 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT) {
2642 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) {
2643 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2644 }
2645 }
2646
2647 /* Link new rib to node.*/
2648 rib_addnode (rn, rib);
2649 ret = 1;
2650 /* Free implicit route.*/
2651 if (same)
2652 {
2653 if (IS_ZEBRA_DEBUG_RIB)
2654 {
2655 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
2656 __func__, rn, same);
2657 rib_dump ((struct prefix *)p, same);
2658 }
2659 rib_delnode (rn, same);
2660 ret = -1;
2661 }
2662
2663 route_unlock_node (rn);
2664 return ret;
2665}
2666
hassoebf1ead2005-09-21 14:58:20 +00002667/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002668int
2669rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
Paul Jakma9099f9b2016-01-18 10:12:10 +00002670 struct in6_addr *gate, ifindex_t ifindex,
2671 vrf_id_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002672{
2673 struct route_table *table;
2674 struct route_node *rn;
2675 struct rib *rib;
2676 struct rib *fib = NULL;
2677 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002678 struct nexthop *nexthop, *tnexthop;
2679 int recursing;
Timo Teräsbe6335d2015-05-23 11:08:41 +03002680 char buf1[PREFIX_STRLEN];
Stephen Hemminger81cce012009-04-28 14:28:00 -07002681 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002682
2683 /* Apply mask. */
2684 apply_mask_ipv6 (p);
2685
2686 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02002687 table = zebra_vrf_table (AFI_IP6, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002688 if (! table)
2689 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002690
paul718e3742002-12-13 20:15:29 +00002691 /* Lookup route node. */
2692 rn = route_node_lookup (table, (struct prefix *) p);
2693 if (! rn)
2694 {
2695 if (IS_ZEBRA_DEBUG_KERNEL)
2696 {
2697 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002698 zlog_debug ("route %s vrf %u via %s ifindex %d doesn't exist in rib",
2699 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002700 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002701 ifindex);
2702 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002703 zlog_debug ("route %s vrf %u ifindex %d doesn't exist in rib",
2704 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002705 ifindex);
2706 }
2707 return ZEBRA_ERR_RTNOEXIST;
2708 }
2709
2710 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002711 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002712 {
Paul Jakma6d691122006-07-27 21:49:00 +00002713 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2714 continue;
2715
Timo Teräs325823a2016-01-15 17:36:31 +02002716 if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB))
paul718e3742002-12-13 20:15:29 +00002717 fib = rib;
2718
hassoebf1ead2005-09-21 14:58:20 +00002719 if (rib->type != type)
2720 continue;
2721 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002722 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002723 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002724 if (nexthop->ifindex != ifindex)
2725 continue;
hassoebf1ead2005-09-21 14:58:20 +00002726 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002727 {
hassoebf1ead2005-09-21 14:58:20 +00002728 rib->refcnt--;
2729 route_unlock_node (rn);
2730 route_unlock_node (rn);
2731 return 0;
paul718e3742002-12-13 20:15:29 +00002732 }
hassoebf1ead2005-09-21 14:58:20 +00002733 same = rib;
2734 break;
paul718e3742002-12-13 20:15:29 +00002735 }
hassoebf1ead2005-09-21 14:58:20 +00002736 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002737 else
2738 {
2739 if (gate == NULL)
2740 {
2741 same = rib;
2742 break;
2743 }
2744 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2745 if (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate))
2746 {
2747 same = rib;
2748 break;
2749 }
2750 if (same)
2751 break;
2752 }
paul718e3742002-12-13 20:15:29 +00002753 }
2754
2755 /* If same type of route can't be found and this message is from
2756 kernel. */
2757 if (! same)
2758 {
James Li92992c62015-11-09 20:21:57 -05002759 if (fib && type == ZEBRA_ROUTE_KERNEL &&
2760 CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE))
2761 {
2762 if (IS_ZEBRA_DEBUG_KERNEL)
2763 {
2764 zlog_debug ("Zebra route %s/%d was deleted by others from kernel",
2765 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
2766 p->prefixlen);
2767 }
2768 /* This means someone else, other than Zebra, has deleted a Zebra
2769 * route from the kernel. We will add it back */
2770 rib_update_kernel(rn, NULL, fib);
2771 }
paul718e3742002-12-13 20:15:29 +00002772 else
2773 {
2774 if (IS_ZEBRA_DEBUG_KERNEL)
2775 {
2776 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002777 zlog_debug ("route %s vrf %u via %s ifindex %d type %d "
2778 "doesn't exist in rib",
2779 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002780 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002781 ifindex,
2782 type);
2783 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002784 zlog_debug ("route %s vrf %u ifindex %d type %d doesn't exist in rib",
2785 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002786 ifindex,
2787 type);
2788 }
2789 route_unlock_node (rn);
2790 return ZEBRA_ERR_RTNOEXIST;
2791 }
2792 }
2793
2794 if (same)
2795 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002796
paul718e3742002-12-13 20:15:29 +00002797 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002798 return 0;
2799}
David Lamparter6b0655a2014-06-04 06:53:35 +02002800
paul718e3742002-12-13 20:15:29 +00002801/* Add static route into static route configuration. */
2802int
2803static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
Paul Jakma96d10602016-07-01 14:23:45 +01002804 const char *ifname, u_char flags, route_tag_t tag,
Piotr Chytłade24f822007-06-28 00:09:28 +02002805 u_char distance, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002806{
2807 struct route_node *rn;
Donald Sharpd4c27d62015-11-04 13:26:35 -05002808 struct static_route *si;
2809 struct static_route *pp;
2810 struct static_route *cp;
Donald Sharpc1900e02015-11-04 13:26:40 -05002811 struct static_route *update = NULL;
Feng Lu0d0686f2015-05-22 11:40:02 +02002812 struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
2813 struct route_table *stable = zvrf->stable[AFI_IP6][SAFI_UNICAST];
paul718e3742002-12-13 20:15:29 +00002814
paul718e3742002-12-13 20:15:29 +00002815 if (! stable)
2816 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00002817
2818 if (!gate &&
2819 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
2820 return -1;
2821
2822 if (!ifname &&
2823 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
2824 return -1;
paul718e3742002-12-13 20:15:29 +00002825
2826 /* Lookup static route prefix. */
2827 rn = route_node_get (stable, p);
2828
2829 /* Do nothing if there is a same static route. */
2830 for (si = rn->info; si; si = si->next)
2831 {
Donald Sharpc1900e02015-11-04 13:26:40 -05002832 if (type == si->type
Piotr Chytłade24f822007-06-28 00:09:28 +02002833 && tag == si->tag
Donald Sharpd4c27d62015-11-04 13:26:35 -05002834 && (! gate || IPV6_ADDR_SAME (gate, &si->addr.ipv6))
paul718e3742002-12-13 20:15:29 +00002835 && (! ifname || strcmp (ifname, si->ifname) == 0))
2836 {
Donald Sharpc1900e02015-11-04 13:26:40 -05002837 if (distance == si->distance)
2838 {
2839 route_unlock_node (rn);
2840 return 0;
2841 }
2842 else
2843 update = si;
paul718e3742002-12-13 20:15:29 +00002844 }
2845 }
2846
Donald Sharpc1900e02015-11-04 13:26:40 -05002847 if (update)
Piotr Chytłade24f822007-06-28 00:09:28 +02002848 static_delete_ipv6(p, type, gate, ifname, tag, si->distance, vrf_id);
Donald Sharpc1900e02015-11-04 13:26:40 -05002849
paul718e3742002-12-13 20:15:29 +00002850 /* Make new static route structure. */
Donald Sharpd4c27d62015-11-04 13:26:35 -05002851 si = XCALLOC (MTYPE_STATIC_ROUTE, sizeof (struct static_route));
paul718e3742002-12-13 20:15:29 +00002852
2853 si->type = type;
2854 si->distance = distance;
Piotr Chytłade24f822007-06-28 00:09:28 +02002855 si->tag = tag;
hasso81dfcaa2003-05-25 19:21:25 +00002856 si->flags = flags;
Feng Lu7aaf4ea2015-05-22 11:40:06 +02002857 si->vrf_id = vrf_id;
paul718e3742002-12-13 20:15:29 +00002858
2859 switch (type)
2860 {
2861 case STATIC_IPV6_GATEWAY:
Donald Sharpd4c27d62015-11-04 13:26:35 -05002862 si->addr.ipv6 = *gate;
paul718e3742002-12-13 20:15:29 +00002863 break;
2864 case STATIC_IPV6_IFNAME:
David Lamparter23757db2016-02-24 06:26:02 +01002865 si->ifname = XSTRDUP (MTYPE_TMP, ifname);
paul718e3742002-12-13 20:15:29 +00002866 break;
2867 case STATIC_IPV6_GATEWAY_IFNAME:
Donald Sharpd4c27d62015-11-04 13:26:35 -05002868 si->addr.ipv6 = *gate;
David Lamparter23757db2016-02-24 06:26:02 +01002869 si->ifname = XSTRDUP (MTYPE_TMP, ifname);
paul718e3742002-12-13 20:15:29 +00002870 break;
2871 }
2872
2873 /* Add new static route information to the tree with sort by
2874 distance value and gateway address. */
2875 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2876 {
2877 if (si->distance < cp->distance)
2878 break;
2879 if (si->distance > cp->distance)
2880 continue;
2881 }
2882
2883 /* Make linked list. */
2884 if (pp)
2885 pp->next = si;
2886 else
2887 rn->info = si;
2888 if (cp)
2889 cp->prev = si;
2890 si->prev = pp;
2891 si->next = cp;
2892
2893 /* Install into rib. */
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002894 static_install_route (AFI_IP6, SAFI_UNICAST, p, si);
paul718e3742002-12-13 20:15:29 +00002895
2896 return 1;
2897}
2898
2899/* Delete static route from static route configuration. */
2900int
2901static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
Paul Jakma96d10602016-07-01 14:23:45 +01002902 const char *ifname, route_tag_t tag, u_char distance,
2903 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002904{
2905 struct route_node *rn;
Donald Sharpd4c27d62015-11-04 13:26:35 -05002906 struct static_route *si;
paul718e3742002-12-13 20:15:29 +00002907 struct route_table *stable;
2908
2909 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02002910 stable = zebra_vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +00002911 if (! stable)
2912 return -1;
2913
2914 /* Lookup static route prefix. */
2915 rn = route_node_lookup (stable, p);
2916 if (! rn)
2917 return 0;
2918
2919 /* Find same static route is the tree */
2920 for (si = rn->info; si; si = si->next)
2921 if (distance == si->distance
2922 && type == si->type
Donald Sharpd4c27d62015-11-04 13:26:35 -05002923 && (! gate || IPV6_ADDR_SAME (gate, &si->addr.ipv6))
Piotr Chytłade24f822007-06-28 00:09:28 +02002924 && (! ifname || strcmp (ifname, si->ifname) == 0)
2925 && (! tag || (tag == si->tag)))
paul718e3742002-12-13 20:15:29 +00002926 break;
2927
2928 /* Can't find static route. */
2929 if (! si)
2930 {
2931 route_unlock_node (rn);
2932 return 0;
2933 }
2934
2935 /* Install into rib. */
Donald Sharp949b7192015-11-04 13:26:39 -05002936 static_uninstall_route (AFI_IP6, SAFI_UNICAST, p, si);
paul718e3742002-12-13 20:15:29 +00002937
2938 /* Unlink static route from linked list. */
2939 if (si->prev)
2940 si->prev->next = si->next;
2941 else
2942 rn->info = si->next;
2943 if (si->next)
2944 si->next->prev = si->prev;
2945
2946 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002947 if (ifname)
2948 XFREE (0, si->ifname);
Donald Sharpd4c27d62015-11-04 13:26:35 -05002949 XFREE (MTYPE_STATIC_ROUTE, si);
paul718e3742002-12-13 20:15:29 +00002950
2951 return 1;
2952}
David Lamparter6b0655a2014-06-04 06:53:35 +02002953
paul718e3742002-12-13 20:15:29 +00002954/* RIB update function. */
2955void
Feng Lu0d0686f2015-05-22 11:40:02 +02002956rib_update (vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002957{
2958 struct route_node *rn;
2959 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00002960
Feng Lu0d0686f2015-05-22 11:40:02 +02002961 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +00002962 if (table)
2963 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002964 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00002965 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002966
Feng Lu0d0686f2015-05-22 11:40:02 +02002967 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +00002968 if (table)
2969 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002970 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00002971 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002972}
2973
David Lamparter6b0655a2014-06-04 06:53:35 +02002974
paul718e3742002-12-13 20:15:29 +00002975/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00002976static void
paul718e3742002-12-13 20:15:29 +00002977rib_weed_table (struct route_table *table)
2978{
2979 struct route_node *rn;
2980 struct rib *rib;
2981 struct rib *next;
2982
2983 if (table)
2984 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002985 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00002986 {
Paul Jakma6d691122006-07-27 21:49:00 +00002987 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2988 continue;
2989
paulb21b19c2003-06-15 01:28:29 +00002990 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00002991 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00002992 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002993 }
2994}
2995
2996/* Delete all routes from non main table. */
2997void
paula1ac18c2005-06-28 17:17:12 +00002998rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00002999{
Feng Lu0d0686f2015-05-22 11:40:02 +02003000 vrf_iter_t iter;
3001 struct zebra_vrf *zvrf;
3002
3003 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3004 if ((zvrf = vrf_iter2info (iter)) != NULL)
3005 {
3006 rib_weed_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
3007 rib_weed_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
3008 }
paul718e3742002-12-13 20:15:29 +00003009}
David Lamparter6b0655a2014-06-04 06:53:35 +02003010
Feng Lu0d0686f2015-05-22 11:40:02 +02003011#if 0
paul718e3742002-12-13 20:15:29 +00003012/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00003013static void
paul718e3742002-12-13 20:15:29 +00003014rib_sweep_table (struct route_table *table)
3015{
3016 struct route_node *rn;
3017 struct rib *rib;
3018 struct rib *next;
3019 int ret = 0;
3020
3021 if (table)
3022 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003023 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003024 {
Paul Jakma6d691122006-07-27 21:49:00 +00003025 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3026 continue;
3027
paul718e3742002-12-13 20:15:29 +00003028 if (rib->type == ZEBRA_ROUTE_KERNEL &&
3029 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
3030 {
Timo Teräs0abf6792016-01-15 17:36:29 +02003031 ret = rib_update_kernel (rn, rib, NULL);
paul718e3742002-12-13 20:15:29 +00003032 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00003033 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003034 }
3035 }
3036}
Feng Lu0d0686f2015-05-22 11:40:02 +02003037#endif
paul718e3742002-12-13 20:15:29 +00003038
3039/* Sweep all RIB tables. */
3040void
paula1ac18c2005-06-28 17:17:12 +00003041rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00003042{
Feng Lu0d0686f2015-05-22 11:40:02 +02003043 vrf_iter_t iter;
3044 struct zebra_vrf *zvrf;
3045
3046 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3047 if ((zvrf = vrf_iter2info (iter)) != NULL)
3048 {
3049 rib_weed_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
3050 rib_weed_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
3051 }
paul718e3742002-12-13 20:15:29 +00003052}
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003053
3054/* Remove specific by protocol routes from 'table'. */
3055static unsigned long
3056rib_score_proto_table (u_char proto, struct route_table *table)
3057{
3058 struct route_node *rn;
3059 struct rib *rib;
3060 struct rib *next;
3061 unsigned long n = 0;
3062
3063 if (table)
3064 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003065 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003066 {
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003067 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3068 continue;
3069 if (rib->type == proto)
3070 {
3071 rib_delnode (rn, rib);
3072 n++;
3073 }
3074 }
3075
3076 return n;
3077}
3078
3079/* Remove specific by protocol routes. */
3080unsigned long
3081rib_score_proto (u_char proto)
3082{
Feng Lu0d0686f2015-05-22 11:40:02 +02003083 vrf_iter_t iter;
3084 struct zebra_vrf *zvrf;
3085 unsigned long cnt = 0;
3086
3087 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3088 if ((zvrf = vrf_iter2info (iter)) != NULL)
3089 cnt += rib_score_proto_table (proto, zvrf->table[AFI_IP][SAFI_UNICAST])
3090 +rib_score_proto_table (proto, zvrf->table[AFI_IP6][SAFI_UNICAST]);
3091
3092 return cnt;
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003093}
3094
paul718e3742002-12-13 20:15:29 +00003095/* Close RIB and clean up kernel routes. */
Feng Lu267ceb22015-05-22 11:40:09 +02003096void
paul718e3742002-12-13 20:15:29 +00003097rib_close_table (struct route_table *table)
3098{
3099 struct route_node *rn;
David Lamparter7ce9e6a2015-01-12 07:05:06 +01003100 rib_table_info_t *info = table->info;
paul718e3742002-12-13 20:15:29 +00003101 struct rib *rib;
3102
3103 if (table)
3104 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003105 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00003106 {
Timo Teräs325823a2016-01-15 17:36:31 +02003107 if (!CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003108 continue;
3109
David Lamparter7ce9e6a2015-01-12 07:05:06 +01003110 if (info->safi == SAFI_UNICAST)
3111 zfpm_trigger_update (rn, NULL);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00003112
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003113 if (! RIB_SYSTEM_ROUTE (rib))
Timo Teräs0abf6792016-01-15 17:36:29 +02003114 rib_update_kernel (rn, rib, NULL);
Paul Jakma6d691122006-07-27 21:49:00 +00003115 }
paul718e3742002-12-13 20:15:29 +00003116}
3117
3118/* Close all RIB tables. */
3119void
paula1ac18c2005-06-28 17:17:12 +00003120rib_close (void)
paul718e3742002-12-13 20:15:29 +00003121{
Feng Lu0d0686f2015-05-22 11:40:02 +02003122 vrf_iter_t iter;
3123 struct zebra_vrf *zvrf;
3124
3125 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3126 if ((zvrf = vrf_iter2info (iter)) != NULL)
3127 {
3128 rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
3129 rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
3130 }
paul718e3742002-12-13 20:15:29 +00003131}
David Lamparter6b0655a2014-06-04 06:53:35 +02003132
paul718e3742002-12-13 20:15:29 +00003133/* Routing information base initialize. */
3134void
paula1ac18c2005-06-28 17:17:12 +00003135rib_init (void)
paul718e3742002-12-13 20:15:29 +00003136{
paul4d38fdb2005-04-28 17:35:14 +00003137 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00003138}
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003139
3140/*
3141 * vrf_id_get_next
3142 *
3143 * Get the first vrf id that is greater than the given vrf id if any.
3144 *
3145 * Returns TRUE if a vrf id was found, FALSE otherwise.
3146 */
3147static inline int
Feng Lu41f44a22015-05-22 11:39:56 +02003148vrf_id_get_next (vrf_id_t vrf_id, vrf_id_t *next_id_p)
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003149{
Feng Lu41f44a22015-05-22 11:39:56 +02003150 vrf_iter_t iter = vrf_iterator (vrf_id);
3151 struct zebra_vrf *zvrf = vrf_iter2info (iter);
3152
3153 /* The same one ? Then find out the next. */
3154 if (zvrf && (zvrf->vrf_id == vrf_id))
3155 zvrf = vrf_iter2info (vrf_next (iter));
3156
3157 if (zvrf)
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003158 {
Feng Lu41f44a22015-05-22 11:39:56 +02003159 *next_id_p = zvrf->vrf_id;
3160 return 1;
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003161 }
3162
3163 return 0;
3164}
3165
3166/*
3167 * rib_tables_iter_next
3168 *
3169 * Returns the next table in the iteration.
3170 */
3171struct route_table *
3172rib_tables_iter_next (rib_tables_iter_t *iter)
3173{
3174 struct route_table *table;
3175
3176 /*
3177 * Array that helps us go over all AFI/SAFI combinations via one
3178 * index.
3179 */
3180 static struct {
3181 afi_t afi;
3182 safi_t safi;
3183 } afi_safis[] = {
3184 { AFI_IP, SAFI_UNICAST },
3185 { AFI_IP, SAFI_MULTICAST },
3186 { AFI_IP6, SAFI_UNICAST },
3187 { AFI_IP6, SAFI_MULTICAST },
3188 };
3189
3190 table = NULL;
3191
3192 switch (iter->state)
3193 {
3194
3195 case RIB_TABLES_ITER_S_INIT:
Donald Sharp0d271292015-11-19 07:21:30 -05003196 iter->vrf_id = VRF_DEFAULT;
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003197 iter->afi_safi_ix = -1;
3198
3199 /* Fall through */
3200
3201 case RIB_TABLES_ITER_S_ITERATING:
3202 iter->afi_safi_ix++;
3203 while (1)
3204 {
3205
3206 while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
3207 {
Feng Lu41f44a22015-05-22 11:39:56 +02003208 table = zebra_vrf_table (afi_safis[iter->afi_safi_ix].afi,
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003209 afi_safis[iter->afi_safi_ix].safi,
3210 iter->vrf_id);
3211 if (table)
3212 break;
3213
3214 iter->afi_safi_ix++;
3215 }
3216
3217 /*
3218 * Found another table in this vrf.
3219 */
3220 if (table)
3221 break;
3222
3223 /*
3224 * Done with all tables in the current vrf, go to the next
3225 * one.
3226 */
3227 if (!vrf_id_get_next (iter->vrf_id, &iter->vrf_id))
3228 break;
3229
3230 iter->afi_safi_ix = 0;
3231 }
3232
3233 break;
3234
3235 case RIB_TABLES_ITER_S_DONE:
3236 return NULL;
3237 }
3238
3239 if (table)
3240 iter->state = RIB_TABLES_ITER_S_ITERATING;
3241 else
3242 iter->state = RIB_TABLES_ITER_S_DONE;
3243
3244 return table;
3245}
Feng Lu41f44a22015-05-22 11:39:56 +02003246
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05003247/* Lookup VRF by identifier. */
3248struct zebra_vrf *
3249zebra_vrf_lookup (vrf_id_t vrf_id)
3250{
3251 return vrf_info_lookup (vrf_id);
3252}
3253
Feng Lu41f44a22015-05-22 11:39:56 +02003254/*
3255 * Create a routing table for the specific AFI/SAFI in the given VRF.
3256 */
3257static void
3258zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi)
3259{
3260 rib_table_info_t *info;
3261 struct route_table *table;
3262
3263 assert (!zvrf->table[afi][safi]);
3264
3265 table = route_table_init ();
3266 zvrf->table[afi][safi] = table;
3267
3268 info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
3269 info->zvrf = zvrf;
3270 info->afi = afi;
3271 info->safi = safi;
3272 table->info = info;
3273}
3274
3275/* Allocate new zebra VRF. */
3276struct zebra_vrf *
3277zebra_vrf_alloc (vrf_id_t vrf_id)
3278{
3279 struct zebra_vrf *zvrf;
Feng Lu758fb8f2014-07-03 18:23:09 +08003280#ifdef HAVE_NETLINK
3281 char nl_name[64];
3282#endif
Feng Lu41f44a22015-05-22 11:39:56 +02003283
3284 zvrf = XCALLOC (MTYPE_ZEBRA_VRF, sizeof (struct zebra_vrf));
3285
3286 /* Allocate routing table and static table. */
3287 zebra_vrf_table_create (zvrf, AFI_IP, SAFI_UNICAST);
3288 zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_UNICAST);
3289 zvrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
3290 zvrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
3291 zebra_vrf_table_create (zvrf, AFI_IP, SAFI_MULTICAST);
3292 zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_MULTICAST);
3293 zvrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
3294 zvrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
3295
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05003296 zvrf->rnh_table[AFI_IP] = route_table_init();
3297 zvrf->rnh_table[AFI_IP6] = route_table_init();
3298
Feng Lu41f44a22015-05-22 11:39:56 +02003299 /* Set VRF ID */
3300 zvrf->vrf_id = vrf_id;
3301
Feng Lu758fb8f2014-07-03 18:23:09 +08003302#ifdef HAVE_NETLINK
3303 /* Initialize netlink sockets */
3304 snprintf (nl_name, 64, "netlink-listen (vrf %u)", vrf_id);
3305 zvrf->netlink.sock = -1;
3306 zvrf->netlink.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name);
3307
3308 snprintf (nl_name, 64, "netlink-cmd (vrf %u)", vrf_id);
3309 zvrf->netlink_cmd.sock = -1;
3310 zvrf->netlink_cmd.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name);
3311#endif
3312
Feng Lu41f44a22015-05-22 11:39:56 +02003313 return zvrf;
3314}
3315
3316/* Lookup the routing table in an enabled VRF. */
3317struct route_table *
3318zebra_vrf_table (afi_t afi, safi_t safi, vrf_id_t vrf_id)
3319{
3320 struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);
3321
3322 if (!zvrf)
3323 return NULL;
3324
3325 if (afi >= AFI_MAX || safi >= SAFI_MAX)
3326 return NULL;
3327
3328 return zvrf->table[afi][safi];
3329}
3330
3331/* Lookup the static routing table in a VRF. */
3332struct route_table *
3333zebra_vrf_static_table (afi_t afi, safi_t safi, vrf_id_t vrf_id)
3334{
3335 struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);
3336
3337 if (!zvrf)
3338 return NULL;
3339
3340 if (afi >= AFI_MAX || safi >= SAFI_MAX)
3341 return NULL;
3342
3343 return zvrf->stable[afi][safi];
3344}
3345