blob: a55d358d3fec74758c11263f530e03a31db5dcb9 [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;
paul4d38fdb2005-04-28 17:35:14 +00001913
paul718e3742002-12-13 20:15:29 +00001914 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02001915 table = zebra_vrf_table (AFI_IP, safi, rib->vrf_id);
paul718e3742002-12-13 20:15:29 +00001916 if (! table)
1917 return 0;
G.Balajicddf3912011-11-26 21:59:32 +04001918
paul718e3742002-12-13 20:15:29 +00001919 /* Make it sure prefixlen is applied to the prefix. */
1920 apply_mask_ipv4 (p);
1921
1922 /* Set default distance by route type. */
1923 if (rib->distance == 0)
1924 {
1925 rib->distance = route_info[rib->type].distance;
1926
1927 /* iBGP distance is 200. */
1928 if (rib->type == ZEBRA_ROUTE_BGP
1929 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1930 rib->distance = 200;
1931 }
1932
1933 /* Lookup route node.*/
1934 rn = route_node_get (table, (struct prefix *) p);
1935
1936 /* If same type of route are installed, treat it as a implicit
1937 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001938 RNODE_FOREACH_RIB (rn, same)
paul718e3742002-12-13 20:15:29 +00001939 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00001940 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00001941 continue;
1942
paul718e3742002-12-13 20:15:29 +00001943 if (same->type == rib->type && same->table == rib->table
1944 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001945 break;
paul718e3742002-12-13 20:15:29 +00001946 }
paul4d38fdb2005-04-28 17:35:14 +00001947
paul718e3742002-12-13 20:15:29 +00001948 /* If this route is kernel route, set FIB flag to the route. */
1949 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
1950 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1951 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1952
1953 /* Link new rib to node.*/
1954 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001955 if (IS_ZEBRA_DEBUG_RIB)
1956 {
1957 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01001958 __func__, (void *)rn, (void *)rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00001959 rib_dump (p, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001960 }
paul718e3742002-12-13 20:15:29 +00001961
paul718e3742002-12-13 20:15:29 +00001962 /* Free implicit route.*/
1963 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001964 {
1965 if (IS_ZEBRA_DEBUG_RIB)
1966 {
1967 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01001968 __func__, (void *)rn, (void *)same);
David Lamparterf7bf4152013-10-22 17:10:21 +00001969 rib_dump (p, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001970 }
paul4d38fdb2005-04-28 17:35:14 +00001971 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001972 }
paul4d38fdb2005-04-28 17:35:14 +00001973
1974 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001975 return 0;
1976}
1977
hassoebf1ead2005-09-21 14:58:20 +00001978/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00001979int
1980rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma9099f9b2016-01-18 10:12:10 +00001981 struct in_addr *gate, ifindex_t ifindex,
1982 vrf_id_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001983{
1984 struct route_table *table;
1985 struct route_node *rn;
1986 struct rib *rib;
1987 struct rib *fib = NULL;
1988 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00001989 struct nexthop *nexthop, *tnexthop;
1990 int recursing;
Timo Teräsbe6335d2015-05-23 11:08:41 +03001991 char buf1[PREFIX_STRLEN];
Stephen Hemminger81cce012009-04-28 14:28:00 -07001992 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00001993
1994 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02001995 table = zebra_vrf_table (AFI_IP, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00001996 if (! table)
1997 return 0;
1998
1999 /* Apply mask. */
2000 apply_mask_ipv4 (p);
2001
Christian Frankeb52aef12013-11-27 17:06:15 +00002002 if (IS_ZEBRA_DEBUG_KERNEL)
2003 {
2004 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002005 zlog_debug ("rib_delete_ipv4(): route delete %s vrf %u via %s ifindex %d",
2006 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Christian Frankeb52aef12013-11-27 17:06:15 +00002007 inet_ntoa (*gate),
2008 ifindex);
2009 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002010 zlog_debug ("rib_delete_ipv4(): route delete %s vrf %u ifindex %d",
2011 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Christian Frankeb52aef12013-11-27 17:06:15 +00002012 ifindex);
2013 }
paul5ec90d22003-06-19 01:41:37 +00002014
paul718e3742002-12-13 20:15:29 +00002015 /* Lookup route node. */
2016 rn = route_node_lookup (table, (struct prefix *) p);
2017 if (! rn)
2018 {
2019 if (IS_ZEBRA_DEBUG_KERNEL)
2020 {
2021 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002022 zlog_debug ("route %s vrf %u via %s ifindex %d doesn't exist in rib",
2023 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002024 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002025 ifindex);
2026 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002027 zlog_debug ("route %s vrf %u ifindex %d doesn't exist in rib",
2028 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002029 ifindex);
2030 }
2031 return ZEBRA_ERR_RTNOEXIST;
2032 }
2033
2034 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002035 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002036 {
Paul Jakma6d691122006-07-27 21:49:00 +00002037 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2038 continue;
2039
Timo Teräs325823a2016-01-15 17:36:31 +02002040 if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB))
paul718e3742002-12-13 20:15:29 +00002041 fib = rib;
2042
hassoebf1ead2005-09-21 14:58:20 +00002043 if (rib->type != type)
2044 continue;
2045 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002046 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002047 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002048 if (nexthop->ifindex != ifindex)
2049 continue;
hassoebf1ead2005-09-21 14:58:20 +00002050 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002051 {
hassoebf1ead2005-09-21 14:58:20 +00002052 rib->refcnt--;
2053 route_unlock_node (rn);
2054 route_unlock_node (rn);
2055 return 0;
paul718e3742002-12-13 20:15:29 +00002056 }
hassoebf1ead2005-09-21 14:58:20 +00002057 same = rib;
2058 break;
paul718e3742002-12-13 20:15:29 +00002059 }
hassoebf1ead2005-09-21 14:58:20 +00002060 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002061 else
paul5ec90d22003-06-19 01:41:37 +00002062 {
Christian Frankefa713d92013-07-05 15:35:37 +00002063 if (gate == NULL)
2064 {
2065 same = rib;
2066 break;
2067 }
2068 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2069 if (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate))
2070 {
2071 same = rib;
2072 break;
2073 }
2074 if (same)
2075 break;
2076 }
paul718e3742002-12-13 20:15:29 +00002077 }
paul718e3742002-12-13 20:15:29 +00002078 /* If same type of route can't be found and this message is from
2079 kernel. */
2080 if (! same)
2081 {
James Li92992c62015-11-09 20:21:57 -05002082 if (fib && type == ZEBRA_ROUTE_KERNEL &&
2083 CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE))
2084 {
2085 if (IS_ZEBRA_DEBUG_KERNEL)
2086 {
2087 zlog_debug ("Zebra route %s/%d was deleted by others from kernel",
2088 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
2089 p->prefixlen);
2090 }
2091 /* This means someone else, other than Zebra, has deleted
2092 * a Zebra router from the kernel. We will add it back */
2093 rib_update_kernel(rn, NULL, fib);
2094 }
paul718e3742002-12-13 20:15:29 +00002095 else
2096 {
2097 if (IS_ZEBRA_DEBUG_KERNEL)
2098 {
2099 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002100 zlog_debug ("route %s vrf %u via %s ifindex %d type %d "
2101 "doesn't exist in rib",
2102 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002103 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002104 ifindex,
2105 type);
2106 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002107 zlog_debug ("route %s vrf %u ifindex %d type %d doesn't exist in rib",
2108 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002109 ifindex,
2110 type);
2111 }
2112 route_unlock_node (rn);
2113 return ZEBRA_ERR_RTNOEXIST;
2114 }
2115 }
paul4d38fdb2005-04-28 17:35:14 +00002116
paul718e3742002-12-13 20:15:29 +00002117 if (same)
2118 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002119
paul718e3742002-12-13 20:15:29 +00002120 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002121 return 0;
2122}
David Lamparter6b0655a2014-06-04 06:53:35 +02002123
paul718e3742002-12-13 20:15:29 +00002124/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002125static void
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002126static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si)
paul718e3742002-12-13 20:15:29 +00002127{
2128 struct rib *rib;
2129 struct route_node *rn;
2130 struct route_table *table;
2131
2132 /* Lookup table. */
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002133 table = zebra_vrf_table (afi, safi, si->vrf_id);
paul718e3742002-12-13 20:15:29 +00002134 if (! table)
2135 return;
2136
2137 /* Lookup existing route */
2138 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002139 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002140 {
2141 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2142 continue;
2143
2144 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2145 break;
2146 }
paul718e3742002-12-13 20:15:29 +00002147
2148 if (rib)
2149 {
2150 /* Same distance static route is there. Update it with new
2151 nexthop. */
paul718e3742002-12-13 20:15:29 +00002152 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002153 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002154 {
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002155 case STATIC_IPV4_GATEWAY:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002156 rib_nexthop_ipv4_add (rib, &si->addr.ipv4, NULL);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002157 break;
2158 case STATIC_IPV4_IFNAME:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002159 rib_nexthop_ifname_add (rib, si->ifname);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002160 break;
2161 case STATIC_IPV4_BLACKHOLE:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002162 rib_nexthop_blackhole_add (rib);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002163 break;
2164 case STATIC_IPV6_GATEWAY:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002165 rib_nexthop_ipv6_add (rib, &si->addr.ipv6);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002166 break;
2167 case STATIC_IPV6_IFNAME:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002168 rib_nexthop_ifname_add (rib, si->ifname);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002169 break;
2170 case STATIC_IPV6_GATEWAY_IFNAME:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002171 rib_nexthop_ipv6_ifname_add (rib, &si->addr.ipv6, si->ifname);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002172 break;
paul4d38fdb2005-04-28 17:35:14 +00002173 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002174 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002175 }
2176 else
2177 {
2178 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002179 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2180
paul718e3742002-12-13 20:15:29 +00002181 rib->type = ZEBRA_ROUTE_STATIC;
2182 rib->distance = si->distance;
2183 rib->metric = 0;
Feng Lu7aaf4ea2015-05-22 11:40:06 +02002184 rib->vrf_id = si->vrf_id;
Nolan Leakeb0145dd2012-09-13 17:17:31 +00002185 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002186 rib->nexthop_num = 0;
2187
2188 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002189 {
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002190 case STATIC_IPV4_GATEWAY:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002191 rib_nexthop_ipv4_add (rib, &si->addr.ipv4, NULL);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002192 break;
2193 case STATIC_IPV4_IFNAME:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002194 rib_nexthop_ifname_add (rib, si->ifname);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002195 break;
2196 case STATIC_IPV4_BLACKHOLE:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002197 rib_nexthop_blackhole_add (rib);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002198 break;
2199 case STATIC_IPV6_GATEWAY:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002200 rib_nexthop_ipv6_add (rib, &si->addr.ipv6);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002201 break;
2202 case STATIC_IPV6_IFNAME:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002203 rib_nexthop_ifname_add (rib, si->ifname);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002204 break;
2205 case STATIC_IPV6_GATEWAY_IFNAME:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002206 rib_nexthop_ipv6_ifname_add (rib, &si->addr.ipv6, si->ifname);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002207 break;
paul7021c422003-07-15 12:52:22 +00002208 }
paul718e3742002-12-13 20:15:29 +00002209
hasso81dfcaa2003-05-25 19:21:25 +00002210 /* Save the flags of this static routes (reject, blackhole) */
2211 rib->flags = si->flags;
2212
paul718e3742002-12-13 20:15:29 +00002213 /* Link this rib to the tree. */
2214 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002215 }
2216}
2217
paula1ac18c2005-06-28 17:17:12 +00002218static int
Donald Sharpa979ab72015-11-04 13:26:38 -05002219static_nexthop_same (struct nexthop *nexthop, struct static_route *si)
paul718e3742002-12-13 20:15:29 +00002220{
2221 if (nexthop->type == NEXTHOP_TYPE_IPV4
2222 && si->type == STATIC_IPV4_GATEWAY
Donald Sharpd4c27d62015-11-04 13:26:35 -05002223 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->addr.ipv4))
paul718e3742002-12-13 20:15:29 +00002224 return 1;
2225 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2226 && si->type == STATIC_IPV4_IFNAME
Donald Sharpd4c27d62015-11-04 13:26:35 -05002227 && strcmp (nexthop->ifname, si->ifname) == 0)
paul718e3742002-12-13 20:15:29 +00002228 return 1;
paul595db7f2003-05-25 21:35:06 +00002229 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2230 && si->type == STATIC_IPV4_BLACKHOLE)
2231 return 1;
Donald Sharpa979ab72015-11-04 13:26:38 -05002232 if (nexthop->type == NEXTHOP_TYPE_IPV6
2233 && si->type == STATIC_IPV6_GATEWAY
2234 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6))
2235 return 1;
2236 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2237 && si->type == STATIC_IPV6_IFNAME
2238 && strcmp (nexthop->ifname, si->ifname) == 0)
2239 return 1;
2240 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2241 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2242 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6)
2243 && strcmp (nexthop->ifname, si->ifname) == 0)
2244 return 1;
paule8e19462006-01-19 20:16:55 +00002245 return 0;
paul718e3742002-12-13 20:15:29 +00002246}
2247
2248/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002249static void
Donald Sharp949b7192015-11-04 13:26:39 -05002250static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si)
paul718e3742002-12-13 20:15:29 +00002251{
2252 struct route_node *rn;
2253 struct rib *rib;
2254 struct nexthop *nexthop;
2255 struct route_table *table;
2256
2257 /* Lookup table. */
Donald Sharp949b7192015-11-04 13:26:39 -05002258 table = zebra_vrf_table (afi, safi, si->vrf_id);
paul718e3742002-12-13 20:15:29 +00002259 if (! table)
2260 return;
paul4d38fdb2005-04-28 17:35:14 +00002261
paul718e3742002-12-13 20:15:29 +00002262 /* Lookup existing route with type and distance. */
2263 rn = route_node_lookup (table, p);
2264 if (! rn)
2265 return;
2266
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002267 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002268 {
2269 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2270 continue;
2271
2272 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2273 break;
2274 }
paul718e3742002-12-13 20:15:29 +00002275
2276 if (! rib)
2277 {
2278 route_unlock_node (rn);
2279 return;
2280 }
2281
2282 /* Lookup nexthop. */
2283 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Donald Sharpa979ab72015-11-04 13:26:38 -05002284 if (static_nexthop_same (nexthop, si))
paul718e3742002-12-13 20:15:29 +00002285 break;
2286
2287 /* Can't find nexthop. */
2288 if (! nexthop)
2289 {
2290 route_unlock_node (rn);
2291 return;
2292 }
2293
2294 /* Check nexthop. */
2295 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002296 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002297 else
2298 {
paul6baeb982003-10-28 03:47:15 +00002299 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2300 rib_uninstall (rn, rib);
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002301 rib_nexthop_delete (rib, nexthop);
paul319572c2005-09-21 12:30:08 +00002302 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002303 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002304 }
paul718e3742002-12-13 20:15:29 +00002305 /* Unlock node. */
2306 route_unlock_node (rn);
2307}
2308
paul718e3742002-12-13 20:15:29 +00002309int
Everton Marques33d86db2014-07-14 11:19:00 -03002310static_add_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate,
2311 const char *ifname, u_char flags, u_char distance,
Feng Lu0d0686f2015-05-22 11:40:02 +02002312 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002313{
2314 u_char type = 0;
2315 struct route_node *rn;
Donald Sharpd4c27d62015-11-04 13:26:35 -05002316 struct static_route *si;
2317 struct static_route *pp;
2318 struct static_route *cp;
2319 struct static_route *update = NULL;
Feng Lu0d0686f2015-05-22 11:40:02 +02002320 struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
2321 struct route_table *stable = zvrf->stable[AFI_IP][safi];
paul718e3742002-12-13 20:15:29 +00002322
paul718e3742002-12-13 20:15:29 +00002323 if (! stable)
2324 return -1;
2325
2326 /* Lookup static route prefix. */
2327 rn = route_node_get (stable, p);
2328
2329 /* Make flags. */
2330 if (gate)
2331 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002332 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002333 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002334 else
2335 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002336
2337 /* Do nothing if there is a same static route. */
2338 for (si = rn->info; si; si = si->next)
2339 {
2340 if (type == si->type
Donald Sharpd4c27d62015-11-04 13:26:35 -05002341 && (! gate || IPV4_ADDR_SAME (gate, &si->addr.ipv4))
2342 && (! ifname || strcmp (ifname, si->ifname) == 0))
paul718e3742002-12-13 20:15:29 +00002343 {
2344 if (distance == si->distance)
2345 {
2346 route_unlock_node (rn);
2347 return 0;
2348 }
2349 else
2350 update = si;
2351 }
2352 }
2353
Paul Jakma3c0755d2006-12-08 00:53:14 +00002354 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002355 if (update)
Everton Marques33d86db2014-07-14 11:19:00 -03002356 static_delete_ipv4_safi (safi, p, gate, ifname, update->distance, vrf_id);
paul718e3742002-12-13 20:15:29 +00002357
2358 /* Make new static route structure. */
Donald Sharpd4c27d62015-11-04 13:26:35 -05002359 si = XCALLOC (MTYPE_STATIC_ROUTE, sizeof (struct static_route));
paul718e3742002-12-13 20:15:29 +00002360
2361 si->type = type;
2362 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002363 si->flags = flags;
Feng Lu7aaf4ea2015-05-22 11:40:06 +02002364 si->vrf_id = vrf_id;
paul718e3742002-12-13 20:15:29 +00002365
2366 if (gate)
Donald Sharpd4c27d62015-11-04 13:26:35 -05002367 si->addr.ipv4 = *gate;
paul718e3742002-12-13 20:15:29 +00002368 if (ifname)
David Lamparter23757db2016-02-24 06:26:02 +01002369 si->ifname = XSTRDUP (MTYPE_TMP, ifname);
paul718e3742002-12-13 20:15:29 +00002370
2371 /* Add new static route information to the tree with sort by
2372 distance value and gateway address. */
2373 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2374 {
2375 if (si->distance < cp->distance)
2376 break;
2377 if (si->distance > cp->distance)
2378 continue;
2379 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2380 {
Donald Sharpd4c27d62015-11-04 13:26:35 -05002381 if (ntohl (si->addr.ipv4.s_addr) < ntohl (cp->addr.ipv4.s_addr))
paul718e3742002-12-13 20:15:29 +00002382 break;
Donald Sharpd4c27d62015-11-04 13:26:35 -05002383 if (ntohl (si->addr.ipv4.s_addr) > ntohl (cp->addr.ipv4.s_addr))
paul718e3742002-12-13 20:15:29 +00002384 continue;
2385 }
2386 }
2387
2388 /* Make linked list. */
2389 if (pp)
2390 pp->next = si;
2391 else
2392 rn->info = si;
2393 if (cp)
2394 cp->prev = si;
2395 si->prev = pp;
2396 si->next = cp;
2397
2398 /* Install into rib. */
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002399 static_install_route (AFI_IP, safi, p, si);
paul718e3742002-12-13 20:15:29 +00002400
2401 return 1;
2402}
2403
paul718e3742002-12-13 20:15:29 +00002404int
Everton Marques33d86db2014-07-14 11:19:00 -03002405static_delete_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate,
Feng Lu0d0686f2015-05-22 11:40:02 +02002406 const char *ifname, u_char distance, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002407{
2408 u_char type = 0;
2409 struct route_node *rn;
Donald Sharpd4c27d62015-11-04 13:26:35 -05002410 struct static_route *si;
paul718e3742002-12-13 20:15:29 +00002411 struct route_table *stable;
2412
2413 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02002414 stable = zebra_vrf_static_table (AFI_IP, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002415 if (! stable)
2416 return -1;
2417
2418 /* Lookup static route prefix. */
2419 rn = route_node_lookup (stable, p);
2420 if (! rn)
2421 return 0;
2422
2423 /* Make flags. */
2424 if (gate)
2425 type = STATIC_IPV4_GATEWAY;
2426 else if (ifname)
2427 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002428 else
2429 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002430
2431 /* Find same static route is the tree */
2432 for (si = rn->info; si; si = si->next)
2433 if (type == si->type
Donald Sharpd4c27d62015-11-04 13:26:35 -05002434 && (! gate || IPV4_ADDR_SAME (gate, &si->addr.ipv4))
2435 && (! ifname || strcmp (ifname, si->ifname) == 0))
paul718e3742002-12-13 20:15:29 +00002436 break;
2437
2438 /* Can't find static route. */
2439 if (! si)
2440 {
2441 route_unlock_node (rn);
2442 return 0;
2443 }
2444
2445 /* Install into rib. */
Donald Sharp949b7192015-11-04 13:26:39 -05002446 static_uninstall_route (AFI_IP, safi, p, si);
paul718e3742002-12-13 20:15:29 +00002447
2448 /* Unlink static route from linked list. */
2449 if (si->prev)
2450 si->prev->next = si->next;
2451 else
2452 rn->info = si->next;
2453 if (si->next)
2454 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002455 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002456
2457 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002458 if (ifname)
Donald Sharpd4c27d62015-11-04 13:26:35 -05002459 XFREE (0, si->ifname);
2460 XFREE (MTYPE_STATIC_ROUTE, si);
paul718e3742002-12-13 20:15:29 +00002461
paul143a3852003-09-29 20:06:13 +00002462 route_unlock_node (rn);
2463
paul718e3742002-12-13 20:15:29 +00002464 return 1;
2465}
2466
paul718e3742002-12-13 20:15:29 +00002467int
2468rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
Paul Jakma9099f9b2016-01-18 10:12:10 +00002469 struct in6_addr *gate, ifindex_t ifindex,
Feng Lu0d0686f2015-05-22 11:40:02 +02002470 vrf_id_t vrf_id, int table_id,
Timo Teräsb11f3b52015-11-02 16:50:07 +02002471 u_int32_t metric, u_int32_t mtu, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002472{
2473 struct rib *rib;
2474 struct rib *same = NULL;
2475 struct route_table *table;
2476 struct route_node *rn;
2477 struct nexthop *nexthop;
2478
paul718e3742002-12-13 20:15:29 +00002479 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02002480 table = zebra_vrf_table (AFI_IP6, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002481 if (! table)
2482 return 0;
2483
2484 /* Make sure mask is applied. */
2485 apply_mask_ipv6 (p);
2486
2487 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002488 if (!distance)
2489 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002490
2491 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2492 distance = 200;
2493
paul718e3742002-12-13 20:15:29 +00002494 /* Lookup route node.*/
2495 rn = route_node_get (table, (struct prefix *) p);
2496
2497 /* If same type of route are installed, treat it as a implicit
2498 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002499 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002500 {
Paul Jakma6d691122006-07-27 21:49:00 +00002501 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2502 continue;
2503
hassoebf1ead2005-09-21 14:58:20 +00002504 if (rib->type != type)
2505 continue;
2506 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002507 {
2508 same = rib;
paul718e3742002-12-13 20:15:29 +00002509 break;
2510 }
hassoebf1ead2005-09-21 14:58:20 +00002511 else if ((nexthop = rib->nexthop) &&
2512 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2513 nexthop->ifindex == ifindex)
2514 {
2515 rib->refcnt++;
2516 return 0;
2517 }
paul718e3742002-12-13 20:15:29 +00002518 }
2519
2520 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002521 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2522
paul718e3742002-12-13 20:15:29 +00002523 rib->type = type;
2524 rib->distance = distance;
2525 rib->flags = flags;
2526 rib->metric = metric;
Timo Teräsb11f3b52015-11-02 16:50:07 +02002527 rib->mtu = mtu;
Feng Lu0d0686f2015-05-22 11:40:02 +02002528 rib->vrf_id = vrf_id;
2529 rib->table = table_id;
paul718e3742002-12-13 20:15:29 +00002530 rib->nexthop_num = 0;
2531 rib->uptime = time (NULL);
2532
2533 /* Nexthop settings. */
2534 if (gate)
2535 {
2536 if (ifindex)
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002537 rib_nexthop_ipv6_ifindex_add (rib, gate, ifindex);
paul718e3742002-12-13 20:15:29 +00002538 else
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002539 rib_nexthop_ipv6_add (rib, gate);
paul718e3742002-12-13 20:15:29 +00002540 }
2541 else
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002542 rib_nexthop_ifindex_add (rib, ifindex);
paul718e3742002-12-13 20:15:29 +00002543
2544 /* If this route is kernel route, set FIB flag to the route. */
2545 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2546 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2547 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2548
2549 /* Link new rib to node.*/
2550 rib_addnode (rn, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002551 if (IS_ZEBRA_DEBUG_RIB)
2552 {
2553 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01002554 __func__, (void *)rn, (void *)rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00002555 rib_dump (p, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002556 }
paul718e3742002-12-13 20:15:29 +00002557
paul718e3742002-12-13 20:15:29 +00002558 /* Free implicit route.*/
2559 if (same)
Vincent Bernatfed643f2012-10-23 16:00:42 +00002560 {
2561 if (IS_ZEBRA_DEBUG_RIB)
2562 {
2563 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01002564 __func__, (void *)rn, (void *)same);
David Lamparterf7bf4152013-10-22 17:10:21 +00002565 rib_dump (p, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002566 }
paul4d38fdb2005-04-28 17:35:14 +00002567 rib_delnode (rn, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002568 }
paul4d38fdb2005-04-28 17:35:14 +00002569
2570 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002571 return 0;
2572}
2573
Ayan Banerjee34c5d892015-11-09 20:14:53 -05002574int
2575rib_add_ipv6_multipath (struct prefix_ipv6 *p, struct rib *rib, safi_t safi)
2576{
2577 struct route_table *table;
2578 struct route_node *rn;
2579 struct rib *same = NULL;
2580 struct nexthop *nexthop;
2581 int ret = 0;
2582
2583 if (!rib)
2584 return 0; /* why are we getting called with NULL rib */
2585
2586 /* Lookup table. */
2587 table = zebra_vrf_table (AFI_IP6, safi, rib->vrf_id);
2588
2589 if (! table)
2590 return 0;
2591
2592 /* Make sure mask is applied. */
2593 apply_mask_ipv6 (p);
2594
2595 /* Set default distance by route type. */
2596 if (rib->distance == 0)
2597 {
2598 rib->distance = route_info[rib->type].distance;
2599
2600 /* iBGP distance is 200. */
2601 if (rib->type == ZEBRA_ROUTE_BGP
2602 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
2603 rib->distance = 200;
2604 }
2605
2606 /* Lookup route node.*/
2607 rn = route_node_get (table, (struct prefix *) p);
2608
2609 /* If same type of route are installed, treat it as a implicit
2610 withdraw. */
2611 RNODE_FOREACH_RIB (rn, same) {
2612 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED)) {
2613 continue;
2614 }
2615 if (same->type != rib->type) {
2616 continue;
2617 }
2618
2619 if (same->table != rib->table) {
2620 continue;
2621 }
2622 if (same->type != ZEBRA_ROUTE_CONNECT) {
2623 break;
2624 }
2625 }
2626
2627 /* If this route is kernel route, set FIB flag to the route. */
2628 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT) {
2629 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) {
2630 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2631 }
2632 }
2633
2634 /* Link new rib to node.*/
2635 rib_addnode (rn, rib);
2636 ret = 1;
2637 /* Free implicit route.*/
2638 if (same)
2639 {
2640 if (IS_ZEBRA_DEBUG_RIB)
2641 {
2642 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
2643 __func__, rn, same);
2644 rib_dump ((struct prefix *)p, same);
2645 }
2646 rib_delnode (rn, same);
2647 ret = -1;
2648 }
2649
2650 route_unlock_node (rn);
2651 return ret;
2652}
2653
hassoebf1ead2005-09-21 14:58:20 +00002654/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002655int
2656rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
Paul Jakma9099f9b2016-01-18 10:12:10 +00002657 struct in6_addr *gate, ifindex_t ifindex,
2658 vrf_id_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002659{
2660 struct route_table *table;
2661 struct route_node *rn;
2662 struct rib *rib;
2663 struct rib *fib = NULL;
2664 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002665 struct nexthop *nexthop, *tnexthop;
2666 int recursing;
Timo Teräsbe6335d2015-05-23 11:08:41 +03002667 char buf1[PREFIX_STRLEN];
Stephen Hemminger81cce012009-04-28 14:28:00 -07002668 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002669
2670 /* Apply mask. */
2671 apply_mask_ipv6 (p);
2672
2673 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02002674 table = zebra_vrf_table (AFI_IP6, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002675 if (! table)
2676 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002677
paul718e3742002-12-13 20:15:29 +00002678 /* Lookup route node. */
2679 rn = route_node_lookup (table, (struct prefix *) p);
2680 if (! rn)
2681 {
2682 if (IS_ZEBRA_DEBUG_KERNEL)
2683 {
2684 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002685 zlog_debug ("route %s vrf %u via %s ifindex %d doesn't exist in rib",
2686 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002687 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002688 ifindex);
2689 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002690 zlog_debug ("route %s vrf %u ifindex %d doesn't exist in rib",
2691 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002692 ifindex);
2693 }
2694 return ZEBRA_ERR_RTNOEXIST;
2695 }
2696
2697 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002698 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002699 {
Paul Jakma6d691122006-07-27 21:49:00 +00002700 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2701 continue;
2702
Timo Teräs325823a2016-01-15 17:36:31 +02002703 if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB))
paul718e3742002-12-13 20:15:29 +00002704 fib = rib;
2705
hassoebf1ead2005-09-21 14:58:20 +00002706 if (rib->type != type)
2707 continue;
2708 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002709 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002710 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002711 if (nexthop->ifindex != ifindex)
2712 continue;
hassoebf1ead2005-09-21 14:58:20 +00002713 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002714 {
hassoebf1ead2005-09-21 14:58:20 +00002715 rib->refcnt--;
2716 route_unlock_node (rn);
2717 route_unlock_node (rn);
2718 return 0;
paul718e3742002-12-13 20:15:29 +00002719 }
hassoebf1ead2005-09-21 14:58:20 +00002720 same = rib;
2721 break;
paul718e3742002-12-13 20:15:29 +00002722 }
hassoebf1ead2005-09-21 14:58:20 +00002723 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002724 else
2725 {
2726 if (gate == NULL)
2727 {
2728 same = rib;
2729 break;
2730 }
2731 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2732 if (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate))
2733 {
2734 same = rib;
2735 break;
2736 }
2737 if (same)
2738 break;
2739 }
paul718e3742002-12-13 20:15:29 +00002740 }
2741
2742 /* If same type of route can't be found and this message is from
2743 kernel. */
2744 if (! same)
2745 {
James Li92992c62015-11-09 20:21:57 -05002746 if (fib && type == ZEBRA_ROUTE_KERNEL &&
2747 CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE))
2748 {
2749 if (IS_ZEBRA_DEBUG_KERNEL)
2750 {
2751 zlog_debug ("Zebra route %s/%d was deleted by others from kernel",
2752 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
2753 p->prefixlen);
2754 }
2755 /* This means someone else, other than Zebra, has deleted a Zebra
2756 * route from the kernel. We will add it back */
2757 rib_update_kernel(rn, NULL, fib);
2758 }
paul718e3742002-12-13 20:15:29 +00002759 else
2760 {
2761 if (IS_ZEBRA_DEBUG_KERNEL)
2762 {
2763 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002764 zlog_debug ("route %s vrf %u via %s ifindex %d type %d "
2765 "doesn't exist in rib",
2766 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002767 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002768 ifindex,
2769 type);
2770 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002771 zlog_debug ("route %s vrf %u ifindex %d type %d doesn't exist in rib",
2772 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002773 ifindex,
2774 type);
2775 }
2776 route_unlock_node (rn);
2777 return ZEBRA_ERR_RTNOEXIST;
2778 }
2779 }
2780
2781 if (same)
2782 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002783
paul718e3742002-12-13 20:15:29 +00002784 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002785 return 0;
2786}
David Lamparter6b0655a2014-06-04 06:53:35 +02002787
paul718e3742002-12-13 20:15:29 +00002788/* Add static route into static route configuration. */
2789int
2790static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002791 const char *ifname, u_char flags, u_char distance,
Feng Lu0d0686f2015-05-22 11:40:02 +02002792 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002793{
2794 struct route_node *rn;
Donald Sharpd4c27d62015-11-04 13:26:35 -05002795 struct static_route *si;
2796 struct static_route *pp;
2797 struct static_route *cp;
Donald Sharpc1900e02015-11-04 13:26:40 -05002798 struct static_route *update = NULL;
Feng Lu0d0686f2015-05-22 11:40:02 +02002799 struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
2800 struct route_table *stable = zvrf->stable[AFI_IP6][SAFI_UNICAST];
paul718e3742002-12-13 20:15:29 +00002801
paul718e3742002-12-13 20:15:29 +00002802 if (! stable)
2803 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00002804
2805 if (!gate &&
2806 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
2807 return -1;
2808
2809 if (!ifname &&
2810 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
2811 return -1;
paul718e3742002-12-13 20:15:29 +00002812
2813 /* Lookup static route prefix. */
2814 rn = route_node_get (stable, p);
2815
2816 /* Do nothing if there is a same static route. */
2817 for (si = rn->info; si; si = si->next)
2818 {
Donald Sharpc1900e02015-11-04 13:26:40 -05002819 if (type == si->type
Donald Sharpd4c27d62015-11-04 13:26:35 -05002820 && (! gate || IPV6_ADDR_SAME (gate, &si->addr.ipv6))
paul718e3742002-12-13 20:15:29 +00002821 && (! ifname || strcmp (ifname, si->ifname) == 0))
2822 {
Donald Sharpc1900e02015-11-04 13:26:40 -05002823 if (distance == si->distance)
2824 {
2825 route_unlock_node (rn);
2826 return 0;
2827 }
2828 else
2829 update = si;
paul718e3742002-12-13 20:15:29 +00002830 }
2831 }
2832
Donald Sharpc1900e02015-11-04 13:26:40 -05002833 if (update)
2834 static_delete_ipv6(p, type, gate, ifname, si->distance, vrf_id);
2835
paul718e3742002-12-13 20:15:29 +00002836 /* Make new static route structure. */
Donald Sharpd4c27d62015-11-04 13:26:35 -05002837 si = XCALLOC (MTYPE_STATIC_ROUTE, sizeof (struct static_route));
paul718e3742002-12-13 20:15:29 +00002838
2839 si->type = type;
2840 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002841 si->flags = flags;
Feng Lu7aaf4ea2015-05-22 11:40:06 +02002842 si->vrf_id = vrf_id;
paul718e3742002-12-13 20:15:29 +00002843
2844 switch (type)
2845 {
2846 case STATIC_IPV6_GATEWAY:
Donald Sharpd4c27d62015-11-04 13:26:35 -05002847 si->addr.ipv6 = *gate;
paul718e3742002-12-13 20:15:29 +00002848 break;
2849 case STATIC_IPV6_IFNAME:
David Lamparter23757db2016-02-24 06:26:02 +01002850 si->ifname = XSTRDUP (MTYPE_TMP, ifname);
paul718e3742002-12-13 20:15:29 +00002851 break;
2852 case STATIC_IPV6_GATEWAY_IFNAME:
Donald Sharpd4c27d62015-11-04 13:26:35 -05002853 si->addr.ipv6 = *gate;
David Lamparter23757db2016-02-24 06:26:02 +01002854 si->ifname = XSTRDUP (MTYPE_TMP, ifname);
paul718e3742002-12-13 20:15:29 +00002855 break;
2856 }
2857
2858 /* Add new static route information to the tree with sort by
2859 distance value and gateway address. */
2860 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2861 {
2862 if (si->distance < cp->distance)
2863 break;
2864 if (si->distance > cp->distance)
2865 continue;
2866 }
2867
2868 /* Make linked list. */
2869 if (pp)
2870 pp->next = si;
2871 else
2872 rn->info = si;
2873 if (cp)
2874 cp->prev = si;
2875 si->prev = pp;
2876 si->next = cp;
2877
2878 /* Install into rib. */
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002879 static_install_route (AFI_IP6, SAFI_UNICAST, p, si);
paul718e3742002-12-13 20:15:29 +00002880
2881 return 1;
2882}
2883
2884/* Delete static route from static route configuration. */
2885int
2886static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
Feng Lu0d0686f2015-05-22 11:40:02 +02002887 const char *ifname, u_char distance, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002888{
2889 struct route_node *rn;
Donald Sharpd4c27d62015-11-04 13:26:35 -05002890 struct static_route *si;
paul718e3742002-12-13 20:15:29 +00002891 struct route_table *stable;
2892
2893 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02002894 stable = zebra_vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +00002895 if (! stable)
2896 return -1;
2897
2898 /* Lookup static route prefix. */
2899 rn = route_node_lookup (stable, p);
2900 if (! rn)
2901 return 0;
2902
2903 /* Find same static route is the tree */
2904 for (si = rn->info; si; si = si->next)
2905 if (distance == si->distance
2906 && type == si->type
Donald Sharpd4c27d62015-11-04 13:26:35 -05002907 && (! gate || IPV6_ADDR_SAME (gate, &si->addr.ipv6))
paul718e3742002-12-13 20:15:29 +00002908 && (! ifname || strcmp (ifname, si->ifname) == 0))
2909 break;
2910
2911 /* Can't find static route. */
2912 if (! si)
2913 {
2914 route_unlock_node (rn);
2915 return 0;
2916 }
2917
2918 /* Install into rib. */
Donald Sharp949b7192015-11-04 13:26:39 -05002919 static_uninstall_route (AFI_IP6, SAFI_UNICAST, p, si);
paul718e3742002-12-13 20:15:29 +00002920
2921 /* Unlink static route from linked list. */
2922 if (si->prev)
2923 si->prev->next = si->next;
2924 else
2925 rn->info = si->next;
2926 if (si->next)
2927 si->next->prev = si->prev;
2928
2929 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002930 if (ifname)
2931 XFREE (0, si->ifname);
Donald Sharpd4c27d62015-11-04 13:26:35 -05002932 XFREE (MTYPE_STATIC_ROUTE, si);
paul718e3742002-12-13 20:15:29 +00002933
2934 return 1;
2935}
David Lamparter6b0655a2014-06-04 06:53:35 +02002936
paul718e3742002-12-13 20:15:29 +00002937/* RIB update function. */
2938void
Feng Lu0d0686f2015-05-22 11:40:02 +02002939rib_update (vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002940{
2941 struct route_node *rn;
2942 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00002943
Feng Lu0d0686f2015-05-22 11:40:02 +02002944 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +00002945 if (table)
2946 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002947 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00002948 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002949
Feng Lu0d0686f2015-05-22 11:40:02 +02002950 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +00002951 if (table)
2952 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002953 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00002954 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002955}
2956
David Lamparter6b0655a2014-06-04 06:53:35 +02002957
paul718e3742002-12-13 20:15:29 +00002958/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00002959static void
paul718e3742002-12-13 20:15:29 +00002960rib_weed_table (struct route_table *table)
2961{
2962 struct route_node *rn;
2963 struct rib *rib;
2964 struct rib *next;
2965
2966 if (table)
2967 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002968 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00002969 {
Paul Jakma6d691122006-07-27 21:49:00 +00002970 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2971 continue;
2972
paulb21b19c2003-06-15 01:28:29 +00002973 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00002974 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00002975 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002976 }
2977}
2978
2979/* Delete all routes from non main table. */
2980void
paula1ac18c2005-06-28 17:17:12 +00002981rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00002982{
Feng Lu0d0686f2015-05-22 11:40:02 +02002983 vrf_iter_t iter;
2984 struct zebra_vrf *zvrf;
2985
2986 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
2987 if ((zvrf = vrf_iter2info (iter)) != NULL)
2988 {
2989 rib_weed_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
2990 rib_weed_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
2991 }
paul718e3742002-12-13 20:15:29 +00002992}
David Lamparter6b0655a2014-06-04 06:53:35 +02002993
Feng Lu0d0686f2015-05-22 11:40:02 +02002994#if 0
paul718e3742002-12-13 20:15:29 +00002995/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00002996static void
paul718e3742002-12-13 20:15:29 +00002997rib_sweep_table (struct route_table *table)
2998{
2999 struct route_node *rn;
3000 struct rib *rib;
3001 struct rib *next;
3002 int ret = 0;
3003
3004 if (table)
3005 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003006 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003007 {
Paul Jakma6d691122006-07-27 21:49:00 +00003008 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3009 continue;
3010
paul718e3742002-12-13 20:15:29 +00003011 if (rib->type == ZEBRA_ROUTE_KERNEL &&
3012 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
3013 {
Timo Teräs0abf6792016-01-15 17:36:29 +02003014 ret = rib_update_kernel (rn, rib, NULL);
paul718e3742002-12-13 20:15:29 +00003015 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00003016 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003017 }
3018 }
3019}
Feng Lu0d0686f2015-05-22 11:40:02 +02003020#endif
paul718e3742002-12-13 20:15:29 +00003021
3022/* Sweep all RIB tables. */
3023void
paula1ac18c2005-06-28 17:17:12 +00003024rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00003025{
Feng Lu0d0686f2015-05-22 11:40:02 +02003026 vrf_iter_t iter;
3027 struct zebra_vrf *zvrf;
3028
3029 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3030 if ((zvrf = vrf_iter2info (iter)) != NULL)
3031 {
3032 rib_weed_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
3033 rib_weed_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
3034 }
paul718e3742002-12-13 20:15:29 +00003035}
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003036
3037/* Remove specific by protocol routes from 'table'. */
3038static unsigned long
3039rib_score_proto_table (u_char proto, struct route_table *table)
3040{
3041 struct route_node *rn;
3042 struct rib *rib;
3043 struct rib *next;
3044 unsigned long n = 0;
3045
3046 if (table)
3047 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003048 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003049 {
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003050 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3051 continue;
3052 if (rib->type == proto)
3053 {
3054 rib_delnode (rn, rib);
3055 n++;
3056 }
3057 }
3058
3059 return n;
3060}
3061
3062/* Remove specific by protocol routes. */
3063unsigned long
3064rib_score_proto (u_char proto)
3065{
Feng Lu0d0686f2015-05-22 11:40:02 +02003066 vrf_iter_t iter;
3067 struct zebra_vrf *zvrf;
3068 unsigned long cnt = 0;
3069
3070 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3071 if ((zvrf = vrf_iter2info (iter)) != NULL)
3072 cnt += rib_score_proto_table (proto, zvrf->table[AFI_IP][SAFI_UNICAST])
3073 +rib_score_proto_table (proto, zvrf->table[AFI_IP6][SAFI_UNICAST]);
3074
3075 return cnt;
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003076}
3077
paul718e3742002-12-13 20:15:29 +00003078/* Close RIB and clean up kernel routes. */
Feng Lu267ceb22015-05-22 11:40:09 +02003079void
paul718e3742002-12-13 20:15:29 +00003080rib_close_table (struct route_table *table)
3081{
3082 struct route_node *rn;
David Lamparter7ce9e6a2015-01-12 07:05:06 +01003083 rib_table_info_t *info = table->info;
paul718e3742002-12-13 20:15:29 +00003084 struct rib *rib;
3085
3086 if (table)
3087 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003088 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00003089 {
Timo Teräs325823a2016-01-15 17:36:31 +02003090 if (!CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003091 continue;
3092
David Lamparter7ce9e6a2015-01-12 07:05:06 +01003093 if (info->safi == SAFI_UNICAST)
3094 zfpm_trigger_update (rn, NULL);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00003095
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003096 if (! RIB_SYSTEM_ROUTE (rib))
Timo Teräs0abf6792016-01-15 17:36:29 +02003097 rib_update_kernel (rn, rib, NULL);
Paul Jakma6d691122006-07-27 21:49:00 +00003098 }
paul718e3742002-12-13 20:15:29 +00003099}
3100
3101/* Close all RIB tables. */
3102void
paula1ac18c2005-06-28 17:17:12 +00003103rib_close (void)
paul718e3742002-12-13 20:15:29 +00003104{
Feng Lu0d0686f2015-05-22 11:40:02 +02003105 vrf_iter_t iter;
3106 struct zebra_vrf *zvrf;
3107
3108 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3109 if ((zvrf = vrf_iter2info (iter)) != NULL)
3110 {
3111 rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
3112 rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
3113 }
paul718e3742002-12-13 20:15:29 +00003114}
David Lamparter6b0655a2014-06-04 06:53:35 +02003115
paul718e3742002-12-13 20:15:29 +00003116/* Routing information base initialize. */
3117void
paula1ac18c2005-06-28 17:17:12 +00003118rib_init (void)
paul718e3742002-12-13 20:15:29 +00003119{
paul4d38fdb2005-04-28 17:35:14 +00003120 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00003121}
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003122
3123/*
3124 * vrf_id_get_next
3125 *
3126 * Get the first vrf id that is greater than the given vrf id if any.
3127 *
3128 * Returns TRUE if a vrf id was found, FALSE otherwise.
3129 */
3130static inline int
Feng Lu41f44a22015-05-22 11:39:56 +02003131vrf_id_get_next (vrf_id_t vrf_id, vrf_id_t *next_id_p)
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003132{
Feng Lu41f44a22015-05-22 11:39:56 +02003133 vrf_iter_t iter = vrf_iterator (vrf_id);
3134 struct zebra_vrf *zvrf = vrf_iter2info (iter);
3135
3136 /* The same one ? Then find out the next. */
3137 if (zvrf && (zvrf->vrf_id == vrf_id))
3138 zvrf = vrf_iter2info (vrf_next (iter));
3139
3140 if (zvrf)
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003141 {
Feng Lu41f44a22015-05-22 11:39:56 +02003142 *next_id_p = zvrf->vrf_id;
3143 return 1;
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003144 }
3145
3146 return 0;
3147}
3148
3149/*
3150 * rib_tables_iter_next
3151 *
3152 * Returns the next table in the iteration.
3153 */
3154struct route_table *
3155rib_tables_iter_next (rib_tables_iter_t *iter)
3156{
3157 struct route_table *table;
3158
3159 /*
3160 * Array that helps us go over all AFI/SAFI combinations via one
3161 * index.
3162 */
3163 static struct {
3164 afi_t afi;
3165 safi_t safi;
3166 } afi_safis[] = {
3167 { AFI_IP, SAFI_UNICAST },
3168 { AFI_IP, SAFI_MULTICAST },
3169 { AFI_IP6, SAFI_UNICAST },
3170 { AFI_IP6, SAFI_MULTICAST },
3171 };
3172
3173 table = NULL;
3174
3175 switch (iter->state)
3176 {
3177
3178 case RIB_TABLES_ITER_S_INIT:
Donald Sharp0d271292015-11-19 07:21:30 -05003179 iter->vrf_id = VRF_DEFAULT;
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003180 iter->afi_safi_ix = -1;
3181
3182 /* Fall through */
3183
3184 case RIB_TABLES_ITER_S_ITERATING:
3185 iter->afi_safi_ix++;
3186 while (1)
3187 {
3188
3189 while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
3190 {
Feng Lu41f44a22015-05-22 11:39:56 +02003191 table = zebra_vrf_table (afi_safis[iter->afi_safi_ix].afi,
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003192 afi_safis[iter->afi_safi_ix].safi,
3193 iter->vrf_id);
3194 if (table)
3195 break;
3196
3197 iter->afi_safi_ix++;
3198 }
3199
3200 /*
3201 * Found another table in this vrf.
3202 */
3203 if (table)
3204 break;
3205
3206 /*
3207 * Done with all tables in the current vrf, go to the next
3208 * one.
3209 */
3210 if (!vrf_id_get_next (iter->vrf_id, &iter->vrf_id))
3211 break;
3212
3213 iter->afi_safi_ix = 0;
3214 }
3215
3216 break;
3217
3218 case RIB_TABLES_ITER_S_DONE:
3219 return NULL;
3220 }
3221
3222 if (table)
3223 iter->state = RIB_TABLES_ITER_S_ITERATING;
3224 else
3225 iter->state = RIB_TABLES_ITER_S_DONE;
3226
3227 return table;
3228}
Feng Lu41f44a22015-05-22 11:39:56 +02003229
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05003230/* Lookup VRF by identifier. */
3231struct zebra_vrf *
3232zebra_vrf_lookup (vrf_id_t vrf_id)
3233{
3234 return vrf_info_lookup (vrf_id);
3235}
3236
Feng Lu41f44a22015-05-22 11:39:56 +02003237/*
3238 * Create a routing table for the specific AFI/SAFI in the given VRF.
3239 */
3240static void
3241zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi)
3242{
3243 rib_table_info_t *info;
3244 struct route_table *table;
3245
3246 assert (!zvrf->table[afi][safi]);
3247
3248 table = route_table_init ();
3249 zvrf->table[afi][safi] = table;
3250
3251 info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
3252 info->zvrf = zvrf;
3253 info->afi = afi;
3254 info->safi = safi;
3255 table->info = info;
3256}
3257
3258/* Allocate new zebra VRF. */
3259struct zebra_vrf *
3260zebra_vrf_alloc (vrf_id_t vrf_id)
3261{
3262 struct zebra_vrf *zvrf;
Feng Lu758fb8f2014-07-03 18:23:09 +08003263#ifdef HAVE_NETLINK
3264 char nl_name[64];
3265#endif
Feng Lu41f44a22015-05-22 11:39:56 +02003266
3267 zvrf = XCALLOC (MTYPE_ZEBRA_VRF, sizeof (struct zebra_vrf));
3268
3269 /* Allocate routing table and static table. */
3270 zebra_vrf_table_create (zvrf, AFI_IP, SAFI_UNICAST);
3271 zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_UNICAST);
3272 zvrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
3273 zvrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
3274 zebra_vrf_table_create (zvrf, AFI_IP, SAFI_MULTICAST);
3275 zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_MULTICAST);
3276 zvrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
3277 zvrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
3278
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05003279 zvrf->rnh_table[AFI_IP] = route_table_init();
3280 zvrf->rnh_table[AFI_IP6] = route_table_init();
3281
Feng Lu41f44a22015-05-22 11:39:56 +02003282 /* Set VRF ID */
3283 zvrf->vrf_id = vrf_id;
3284
Feng Lu758fb8f2014-07-03 18:23:09 +08003285#ifdef HAVE_NETLINK
3286 /* Initialize netlink sockets */
3287 snprintf (nl_name, 64, "netlink-listen (vrf %u)", vrf_id);
3288 zvrf->netlink.sock = -1;
3289 zvrf->netlink.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name);
3290
3291 snprintf (nl_name, 64, "netlink-cmd (vrf %u)", vrf_id);
3292 zvrf->netlink_cmd.sock = -1;
3293 zvrf->netlink_cmd.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name);
3294#endif
3295
Feng Lu41f44a22015-05-22 11:39:56 +02003296 return zvrf;
3297}
3298
3299/* Lookup the routing table in an enabled VRF. */
3300struct route_table *
3301zebra_vrf_table (afi_t afi, safi_t safi, vrf_id_t vrf_id)
3302{
3303 struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);
3304
3305 if (!zvrf)
3306 return NULL;
3307
3308 if (afi >= AFI_MAX || safi >= SAFI_MAX)
3309 return NULL;
3310
3311 return zvrf->table[afi][safi];
3312}
3313
3314/* Lookup the static routing table in a VRF. */
3315struct route_table *
3316zebra_vrf_static_table (afi_t afi, safi_t safi, vrf_id_t vrf_id)
3317{
3318 struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);
3319
3320 if (!zvrf)
3321 return NULL;
3322
3323 if (afi >= AFI_MAX || safi >= SAFI_MAX)
3324 return NULL;
3325
3326 return zvrf->stable[afi][safi];
3327}
3328