blob: 0aa516cd927e726f8aaef9fa5baa2651db053501 [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 {
2082 if (fib && type == ZEBRA_ROUTE_KERNEL)
2083 {
2084 /* Unset flags. */
2085 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2086 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2087
Timo Teräs325823a2016-01-15 17:36:31 +02002088 UNSET_FLAG (fib->status, RIB_ENTRY_SELECTED_FIB);
paul718e3742002-12-13 20:15:29 +00002089 }
2090 else
2091 {
2092 if (IS_ZEBRA_DEBUG_KERNEL)
2093 {
2094 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002095 zlog_debug ("route %s vrf %u via %s ifindex %d type %d "
2096 "doesn't exist in rib",
2097 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002098 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002099 ifindex,
2100 type);
2101 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002102 zlog_debug ("route %s vrf %u ifindex %d type %d doesn't exist in rib",
2103 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002104 ifindex,
2105 type);
2106 }
2107 route_unlock_node (rn);
2108 return ZEBRA_ERR_RTNOEXIST;
2109 }
2110 }
paul4d38fdb2005-04-28 17:35:14 +00002111
paul718e3742002-12-13 20:15:29 +00002112 if (same)
2113 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002114
paul718e3742002-12-13 20:15:29 +00002115 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002116 return 0;
2117}
David Lamparter6b0655a2014-06-04 06:53:35 +02002118
paul718e3742002-12-13 20:15:29 +00002119/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002120static void
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002121static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si)
paul718e3742002-12-13 20:15:29 +00002122{
2123 struct rib *rib;
2124 struct route_node *rn;
2125 struct route_table *table;
2126
2127 /* Lookup table. */
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002128 table = zebra_vrf_table (afi, safi, si->vrf_id);
paul718e3742002-12-13 20:15:29 +00002129 if (! table)
2130 return;
2131
2132 /* Lookup existing route */
2133 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002134 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002135 {
2136 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2137 continue;
2138
2139 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2140 break;
2141 }
paul718e3742002-12-13 20:15:29 +00002142
2143 if (rib)
2144 {
2145 /* Same distance static route is there. Update it with new
2146 nexthop. */
paul718e3742002-12-13 20:15:29 +00002147 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002148 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002149 {
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002150 case STATIC_IPV4_GATEWAY:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002151 rib_nexthop_ipv4_add (rib, &si->addr.ipv4, NULL);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002152 break;
2153 case STATIC_IPV4_IFNAME:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002154 rib_nexthop_ifname_add (rib, si->ifname);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002155 break;
2156 case STATIC_IPV4_BLACKHOLE:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002157 rib_nexthop_blackhole_add (rib);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002158 break;
2159 case STATIC_IPV6_GATEWAY:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002160 rib_nexthop_ipv6_add (rib, &si->addr.ipv6);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002161 break;
2162 case STATIC_IPV6_IFNAME:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002163 rib_nexthop_ifname_add (rib, si->ifname);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002164 break;
2165 case STATIC_IPV6_GATEWAY_IFNAME:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002166 rib_nexthop_ipv6_ifname_add (rib, &si->addr.ipv6, si->ifname);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002167 break;
paul4d38fdb2005-04-28 17:35:14 +00002168 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002169 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002170 }
2171 else
2172 {
2173 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002174 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2175
paul718e3742002-12-13 20:15:29 +00002176 rib->type = ZEBRA_ROUTE_STATIC;
2177 rib->distance = si->distance;
2178 rib->metric = 0;
Feng Lu7aaf4ea2015-05-22 11:40:06 +02002179 rib->vrf_id = si->vrf_id;
Nolan Leakeb0145dd2012-09-13 17:17:31 +00002180 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002181 rib->nexthop_num = 0;
2182
2183 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002184 {
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002185 case STATIC_IPV4_GATEWAY:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002186 rib_nexthop_ipv4_add (rib, &si->addr.ipv4, NULL);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002187 break;
2188 case STATIC_IPV4_IFNAME:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002189 rib_nexthop_ifname_add (rib, si->ifname);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002190 break;
2191 case STATIC_IPV4_BLACKHOLE:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002192 rib_nexthop_blackhole_add (rib);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002193 break;
2194 case STATIC_IPV6_GATEWAY:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002195 rib_nexthop_ipv6_add (rib, &si->addr.ipv6);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002196 break;
2197 case STATIC_IPV6_IFNAME:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002198 rib_nexthop_ifname_add (rib, si->ifname);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002199 break;
2200 case STATIC_IPV6_GATEWAY_IFNAME:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002201 rib_nexthop_ipv6_ifname_add (rib, &si->addr.ipv6, si->ifname);
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002202 break;
paul7021c422003-07-15 12:52:22 +00002203 }
paul718e3742002-12-13 20:15:29 +00002204
hasso81dfcaa2003-05-25 19:21:25 +00002205 /* Save the flags of this static routes (reject, blackhole) */
2206 rib->flags = si->flags;
2207
paul718e3742002-12-13 20:15:29 +00002208 /* Link this rib to the tree. */
2209 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002210 }
2211}
2212
paula1ac18c2005-06-28 17:17:12 +00002213static int
Donald Sharpa979ab72015-11-04 13:26:38 -05002214static_nexthop_same (struct nexthop *nexthop, struct static_route *si)
paul718e3742002-12-13 20:15:29 +00002215{
2216 if (nexthop->type == NEXTHOP_TYPE_IPV4
2217 && si->type == STATIC_IPV4_GATEWAY
Donald Sharpd4c27d62015-11-04 13:26:35 -05002218 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->addr.ipv4))
paul718e3742002-12-13 20:15:29 +00002219 return 1;
2220 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2221 && si->type == STATIC_IPV4_IFNAME
Donald Sharpd4c27d62015-11-04 13:26:35 -05002222 && strcmp (nexthop->ifname, si->ifname) == 0)
paul718e3742002-12-13 20:15:29 +00002223 return 1;
paul595db7f2003-05-25 21:35:06 +00002224 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2225 && si->type == STATIC_IPV4_BLACKHOLE)
2226 return 1;
Donald Sharpa979ab72015-11-04 13:26:38 -05002227 if (nexthop->type == NEXTHOP_TYPE_IPV6
2228 && si->type == STATIC_IPV6_GATEWAY
2229 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6))
2230 return 1;
2231 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2232 && si->type == STATIC_IPV6_IFNAME
2233 && strcmp (nexthop->ifname, si->ifname) == 0)
2234 return 1;
2235 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2236 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2237 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6)
2238 && strcmp (nexthop->ifname, si->ifname) == 0)
2239 return 1;
paule8e19462006-01-19 20:16:55 +00002240 return 0;
paul718e3742002-12-13 20:15:29 +00002241}
2242
2243/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002244static void
Donald Sharp949b7192015-11-04 13:26:39 -05002245static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si)
paul718e3742002-12-13 20:15:29 +00002246{
2247 struct route_node *rn;
2248 struct rib *rib;
2249 struct nexthop *nexthop;
2250 struct route_table *table;
2251
2252 /* Lookup table. */
Donald Sharp949b7192015-11-04 13:26:39 -05002253 table = zebra_vrf_table (afi, safi, si->vrf_id);
paul718e3742002-12-13 20:15:29 +00002254 if (! table)
2255 return;
paul4d38fdb2005-04-28 17:35:14 +00002256
paul718e3742002-12-13 20:15:29 +00002257 /* Lookup existing route with type and distance. */
2258 rn = route_node_lookup (table, p);
2259 if (! rn)
2260 return;
2261
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002262 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002263 {
2264 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2265 continue;
2266
2267 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2268 break;
2269 }
paul718e3742002-12-13 20:15:29 +00002270
2271 if (! rib)
2272 {
2273 route_unlock_node (rn);
2274 return;
2275 }
2276
2277 /* Lookup nexthop. */
2278 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Donald Sharpa979ab72015-11-04 13:26:38 -05002279 if (static_nexthop_same (nexthop, si))
paul718e3742002-12-13 20:15:29 +00002280 break;
2281
2282 /* Can't find nexthop. */
2283 if (! nexthop)
2284 {
2285 route_unlock_node (rn);
2286 return;
2287 }
2288
2289 /* Check nexthop. */
2290 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002291 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002292 else
2293 {
paul6baeb982003-10-28 03:47:15 +00002294 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2295 rib_uninstall (rn, rib);
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002296 rib_nexthop_delete (rib, nexthop);
paul319572c2005-09-21 12:30:08 +00002297 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002298 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002299 }
paul718e3742002-12-13 20:15:29 +00002300 /* Unlock node. */
2301 route_unlock_node (rn);
2302}
2303
paul718e3742002-12-13 20:15:29 +00002304int
Everton Marques33d86db2014-07-14 11:19:00 -03002305static_add_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate,
2306 const char *ifname, u_char flags, u_char distance,
Feng Lu0d0686f2015-05-22 11:40:02 +02002307 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002308{
2309 u_char type = 0;
2310 struct route_node *rn;
Donald Sharpd4c27d62015-11-04 13:26:35 -05002311 struct static_route *si;
2312 struct static_route *pp;
2313 struct static_route *cp;
2314 struct static_route *update = NULL;
Feng Lu0d0686f2015-05-22 11:40:02 +02002315 struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
2316 struct route_table *stable = zvrf->stable[AFI_IP][safi];
paul718e3742002-12-13 20:15:29 +00002317
paul718e3742002-12-13 20:15:29 +00002318 if (! stable)
2319 return -1;
2320
2321 /* Lookup static route prefix. */
2322 rn = route_node_get (stable, p);
2323
2324 /* Make flags. */
2325 if (gate)
2326 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002327 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002328 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002329 else
2330 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002331
2332 /* Do nothing if there is a same static route. */
2333 for (si = rn->info; si; si = si->next)
2334 {
2335 if (type == si->type
Donald Sharpd4c27d62015-11-04 13:26:35 -05002336 && (! gate || IPV4_ADDR_SAME (gate, &si->addr.ipv4))
2337 && (! ifname || strcmp (ifname, si->ifname) == 0))
paul718e3742002-12-13 20:15:29 +00002338 {
2339 if (distance == si->distance)
2340 {
2341 route_unlock_node (rn);
2342 return 0;
2343 }
2344 else
2345 update = si;
2346 }
2347 }
2348
Paul Jakma3c0755d2006-12-08 00:53:14 +00002349 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002350 if (update)
Everton Marques33d86db2014-07-14 11:19:00 -03002351 static_delete_ipv4_safi (safi, p, gate, ifname, update->distance, vrf_id);
paul718e3742002-12-13 20:15:29 +00002352
2353 /* Make new static route structure. */
Donald Sharpd4c27d62015-11-04 13:26:35 -05002354 si = XCALLOC (MTYPE_STATIC_ROUTE, sizeof (struct static_route));
paul718e3742002-12-13 20:15:29 +00002355
2356 si->type = type;
2357 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002358 si->flags = flags;
Feng Lu7aaf4ea2015-05-22 11:40:06 +02002359 si->vrf_id = vrf_id;
paul718e3742002-12-13 20:15:29 +00002360
2361 if (gate)
Donald Sharpd4c27d62015-11-04 13:26:35 -05002362 si->addr.ipv4 = *gate;
paul718e3742002-12-13 20:15:29 +00002363 if (ifname)
David Lamparter23757db2016-02-24 06:26:02 +01002364 si->ifname = XSTRDUP (MTYPE_TMP, ifname);
paul718e3742002-12-13 20:15:29 +00002365
2366 /* Add new static route information to the tree with sort by
2367 distance value and gateway address. */
2368 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2369 {
2370 if (si->distance < cp->distance)
2371 break;
2372 if (si->distance > cp->distance)
2373 continue;
2374 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2375 {
Donald Sharpd4c27d62015-11-04 13:26:35 -05002376 if (ntohl (si->addr.ipv4.s_addr) < ntohl (cp->addr.ipv4.s_addr))
paul718e3742002-12-13 20:15:29 +00002377 break;
Donald Sharpd4c27d62015-11-04 13:26:35 -05002378 if (ntohl (si->addr.ipv4.s_addr) > ntohl (cp->addr.ipv4.s_addr))
paul718e3742002-12-13 20:15:29 +00002379 continue;
2380 }
2381 }
2382
2383 /* Make linked list. */
2384 if (pp)
2385 pp->next = si;
2386 else
2387 rn->info = si;
2388 if (cp)
2389 cp->prev = si;
2390 si->prev = pp;
2391 si->next = cp;
2392
2393 /* Install into rib. */
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002394 static_install_route (AFI_IP, safi, p, si);
paul718e3742002-12-13 20:15:29 +00002395
2396 return 1;
2397}
2398
paul718e3742002-12-13 20:15:29 +00002399int
Everton Marques33d86db2014-07-14 11:19:00 -03002400static_delete_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate,
Feng Lu0d0686f2015-05-22 11:40:02 +02002401 const char *ifname, u_char distance, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002402{
2403 u_char type = 0;
2404 struct route_node *rn;
Donald Sharpd4c27d62015-11-04 13:26:35 -05002405 struct static_route *si;
paul718e3742002-12-13 20:15:29 +00002406 struct route_table *stable;
2407
2408 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02002409 stable = zebra_vrf_static_table (AFI_IP, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002410 if (! stable)
2411 return -1;
2412
2413 /* Lookup static route prefix. */
2414 rn = route_node_lookup (stable, p);
2415 if (! rn)
2416 return 0;
2417
2418 /* Make flags. */
2419 if (gate)
2420 type = STATIC_IPV4_GATEWAY;
2421 else if (ifname)
2422 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002423 else
2424 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002425
2426 /* Find same static route is the tree */
2427 for (si = rn->info; si; si = si->next)
2428 if (type == si->type
Donald Sharpd4c27d62015-11-04 13:26:35 -05002429 && (! gate || IPV4_ADDR_SAME (gate, &si->addr.ipv4))
2430 && (! ifname || strcmp (ifname, si->ifname) == 0))
paul718e3742002-12-13 20:15:29 +00002431 break;
2432
2433 /* Can't find static route. */
2434 if (! si)
2435 {
2436 route_unlock_node (rn);
2437 return 0;
2438 }
2439
2440 /* Install into rib. */
Donald Sharp949b7192015-11-04 13:26:39 -05002441 static_uninstall_route (AFI_IP, safi, p, si);
paul718e3742002-12-13 20:15:29 +00002442
2443 /* Unlink static route from linked list. */
2444 if (si->prev)
2445 si->prev->next = si->next;
2446 else
2447 rn->info = si->next;
2448 if (si->next)
2449 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002450 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002451
2452 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002453 if (ifname)
Donald Sharpd4c27d62015-11-04 13:26:35 -05002454 XFREE (0, si->ifname);
2455 XFREE (MTYPE_STATIC_ROUTE, si);
paul718e3742002-12-13 20:15:29 +00002456
paul143a3852003-09-29 20:06:13 +00002457 route_unlock_node (rn);
2458
paul718e3742002-12-13 20:15:29 +00002459 return 1;
2460}
2461
paul718e3742002-12-13 20:15:29 +00002462int
2463rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
Paul Jakma9099f9b2016-01-18 10:12:10 +00002464 struct in6_addr *gate, ifindex_t ifindex,
Feng Lu0d0686f2015-05-22 11:40:02 +02002465 vrf_id_t vrf_id, int table_id,
Timo Teräsb11f3b52015-11-02 16:50:07 +02002466 u_int32_t metric, u_int32_t mtu, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002467{
2468 struct rib *rib;
2469 struct rib *same = NULL;
2470 struct route_table *table;
2471 struct route_node *rn;
2472 struct nexthop *nexthop;
2473
paul718e3742002-12-13 20:15:29 +00002474 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02002475 table = zebra_vrf_table (AFI_IP6, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002476 if (! table)
2477 return 0;
2478
2479 /* Make sure mask is applied. */
2480 apply_mask_ipv6 (p);
2481
2482 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002483 if (!distance)
2484 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002485
2486 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2487 distance = 200;
2488
paul718e3742002-12-13 20:15:29 +00002489 /* Lookup route node.*/
2490 rn = route_node_get (table, (struct prefix *) p);
2491
2492 /* If same type of route are installed, treat it as a implicit
2493 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002494 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002495 {
Paul Jakma6d691122006-07-27 21:49:00 +00002496 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2497 continue;
2498
hassoebf1ead2005-09-21 14:58:20 +00002499 if (rib->type != type)
2500 continue;
2501 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002502 {
2503 same = rib;
paul718e3742002-12-13 20:15:29 +00002504 break;
2505 }
hassoebf1ead2005-09-21 14:58:20 +00002506 else if ((nexthop = rib->nexthop) &&
2507 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2508 nexthop->ifindex == ifindex)
2509 {
2510 rib->refcnt++;
2511 return 0;
2512 }
paul718e3742002-12-13 20:15:29 +00002513 }
2514
2515 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002516 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2517
paul718e3742002-12-13 20:15:29 +00002518 rib->type = type;
2519 rib->distance = distance;
2520 rib->flags = flags;
2521 rib->metric = metric;
Timo Teräsb11f3b52015-11-02 16:50:07 +02002522 rib->mtu = mtu;
Feng Lu0d0686f2015-05-22 11:40:02 +02002523 rib->vrf_id = vrf_id;
2524 rib->table = table_id;
paul718e3742002-12-13 20:15:29 +00002525 rib->nexthop_num = 0;
2526 rib->uptime = time (NULL);
2527
2528 /* Nexthop settings. */
2529 if (gate)
2530 {
2531 if (ifindex)
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002532 rib_nexthop_ipv6_ifindex_add (rib, gate, ifindex);
paul718e3742002-12-13 20:15:29 +00002533 else
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002534 rib_nexthop_ipv6_add (rib, gate);
paul718e3742002-12-13 20:15:29 +00002535 }
2536 else
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05002537 rib_nexthop_ifindex_add (rib, ifindex);
paul718e3742002-12-13 20:15:29 +00002538
2539 /* If this route is kernel route, set FIB flag to the route. */
2540 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2541 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2542 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2543
2544 /* Link new rib to node.*/
2545 rib_addnode (rn, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002546 if (IS_ZEBRA_DEBUG_RIB)
2547 {
2548 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01002549 __func__, (void *)rn, (void *)rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00002550 rib_dump (p, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002551 }
paul718e3742002-12-13 20:15:29 +00002552
paul718e3742002-12-13 20:15:29 +00002553 /* Free implicit route.*/
2554 if (same)
Vincent Bernatfed643f2012-10-23 16:00:42 +00002555 {
2556 if (IS_ZEBRA_DEBUG_RIB)
2557 {
2558 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01002559 __func__, (void *)rn, (void *)same);
David Lamparterf7bf4152013-10-22 17:10:21 +00002560 rib_dump (p, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002561 }
paul4d38fdb2005-04-28 17:35:14 +00002562 rib_delnode (rn, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002563 }
paul4d38fdb2005-04-28 17:35:14 +00002564
2565 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002566 return 0;
2567}
2568
Ayan Banerjee34c5d892015-11-09 20:14:53 -05002569int
2570rib_add_ipv6_multipath (struct prefix_ipv6 *p, struct rib *rib, safi_t safi)
2571{
2572 struct route_table *table;
2573 struct route_node *rn;
2574 struct rib *same = NULL;
2575 struct nexthop *nexthop;
2576 int ret = 0;
2577
2578 if (!rib)
2579 return 0; /* why are we getting called with NULL rib */
2580
2581 /* Lookup table. */
2582 table = zebra_vrf_table (AFI_IP6, safi, rib->vrf_id);
2583
2584 if (! table)
2585 return 0;
2586
2587 /* Make sure mask is applied. */
2588 apply_mask_ipv6 (p);
2589
2590 /* Set default distance by route type. */
2591 if (rib->distance == 0)
2592 {
2593 rib->distance = route_info[rib->type].distance;
2594
2595 /* iBGP distance is 200. */
2596 if (rib->type == ZEBRA_ROUTE_BGP
2597 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
2598 rib->distance = 200;
2599 }
2600
2601 /* Lookup route node.*/
2602 rn = route_node_get (table, (struct prefix *) p);
2603
2604 /* If same type of route are installed, treat it as a implicit
2605 withdraw. */
2606 RNODE_FOREACH_RIB (rn, same) {
2607 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED)) {
2608 continue;
2609 }
2610 if (same->type != rib->type) {
2611 continue;
2612 }
2613
2614 if (same->table != rib->table) {
2615 continue;
2616 }
2617 if (same->type != ZEBRA_ROUTE_CONNECT) {
2618 break;
2619 }
2620 }
2621
2622 /* If this route is kernel route, set FIB flag to the route. */
2623 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT) {
2624 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) {
2625 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2626 }
2627 }
2628
2629 /* Link new rib to node.*/
2630 rib_addnode (rn, rib);
2631 ret = 1;
2632 /* Free implicit route.*/
2633 if (same)
2634 {
2635 if (IS_ZEBRA_DEBUG_RIB)
2636 {
2637 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
2638 __func__, rn, same);
2639 rib_dump ((struct prefix *)p, same);
2640 }
2641 rib_delnode (rn, same);
2642 ret = -1;
2643 }
2644
2645 route_unlock_node (rn);
2646 return ret;
2647}
2648
hassoebf1ead2005-09-21 14:58:20 +00002649/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002650int
2651rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
Paul Jakma9099f9b2016-01-18 10:12:10 +00002652 struct in6_addr *gate, ifindex_t ifindex,
2653 vrf_id_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002654{
2655 struct route_table *table;
2656 struct route_node *rn;
2657 struct rib *rib;
2658 struct rib *fib = NULL;
2659 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002660 struct nexthop *nexthop, *tnexthop;
2661 int recursing;
Timo Teräsbe6335d2015-05-23 11:08:41 +03002662 char buf1[PREFIX_STRLEN];
Stephen Hemminger81cce012009-04-28 14:28:00 -07002663 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002664
2665 /* Apply mask. */
2666 apply_mask_ipv6 (p);
2667
2668 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02002669 table = zebra_vrf_table (AFI_IP6, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002670 if (! table)
2671 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002672
paul718e3742002-12-13 20:15:29 +00002673 /* Lookup route node. */
2674 rn = route_node_lookup (table, (struct prefix *) p);
2675 if (! rn)
2676 {
2677 if (IS_ZEBRA_DEBUG_KERNEL)
2678 {
2679 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002680 zlog_debug ("route %s vrf %u via %s ifindex %d doesn't exist in rib",
2681 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002682 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002683 ifindex);
2684 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002685 zlog_debug ("route %s vrf %u ifindex %d doesn't exist in rib",
2686 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002687 ifindex);
2688 }
2689 return ZEBRA_ERR_RTNOEXIST;
2690 }
2691
2692 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002693 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002694 {
Paul Jakma6d691122006-07-27 21:49:00 +00002695 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2696 continue;
2697
Timo Teräs325823a2016-01-15 17:36:31 +02002698 if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB))
paul718e3742002-12-13 20:15:29 +00002699 fib = rib;
2700
hassoebf1ead2005-09-21 14:58:20 +00002701 if (rib->type != type)
2702 continue;
2703 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002704 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002705 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002706 if (nexthop->ifindex != ifindex)
2707 continue;
hassoebf1ead2005-09-21 14:58:20 +00002708 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002709 {
hassoebf1ead2005-09-21 14:58:20 +00002710 rib->refcnt--;
2711 route_unlock_node (rn);
2712 route_unlock_node (rn);
2713 return 0;
paul718e3742002-12-13 20:15:29 +00002714 }
hassoebf1ead2005-09-21 14:58:20 +00002715 same = rib;
2716 break;
paul718e3742002-12-13 20:15:29 +00002717 }
hassoebf1ead2005-09-21 14:58:20 +00002718 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002719 else
2720 {
2721 if (gate == NULL)
2722 {
2723 same = rib;
2724 break;
2725 }
2726 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2727 if (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate))
2728 {
2729 same = rib;
2730 break;
2731 }
2732 if (same)
2733 break;
2734 }
paul718e3742002-12-13 20:15:29 +00002735 }
2736
2737 /* If same type of route can't be found and this message is from
2738 kernel. */
2739 if (! same)
2740 {
2741 if (fib && type == ZEBRA_ROUTE_KERNEL)
2742 {
2743 /* Unset flags. */
2744 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2745 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2746
Timo Teräs325823a2016-01-15 17:36:31 +02002747 UNSET_FLAG (fib->status, RIB_ENTRY_SELECTED_FIB);
paul718e3742002-12-13 20:15:29 +00002748 }
2749 else
2750 {
2751 if (IS_ZEBRA_DEBUG_KERNEL)
2752 {
2753 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002754 zlog_debug ("route %s vrf %u via %s ifindex %d type %d "
2755 "doesn't exist in rib",
2756 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002757 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002758 ifindex,
2759 type);
2760 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002761 zlog_debug ("route %s vrf %u ifindex %d type %d doesn't exist in rib",
2762 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002763 ifindex,
2764 type);
2765 }
2766 route_unlock_node (rn);
2767 return ZEBRA_ERR_RTNOEXIST;
2768 }
2769 }
2770
2771 if (same)
2772 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002773
paul718e3742002-12-13 20:15:29 +00002774 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002775 return 0;
2776}
David Lamparter6b0655a2014-06-04 06:53:35 +02002777
paul718e3742002-12-13 20:15:29 +00002778/* Add static route into static route configuration. */
2779int
2780static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002781 const char *ifname, u_char flags, u_char distance,
Feng Lu0d0686f2015-05-22 11:40:02 +02002782 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002783{
2784 struct route_node *rn;
Donald Sharpd4c27d62015-11-04 13:26:35 -05002785 struct static_route *si;
2786 struct static_route *pp;
2787 struct static_route *cp;
Donald Sharpc1900e02015-11-04 13:26:40 -05002788 struct static_route *update = NULL;
Feng Lu0d0686f2015-05-22 11:40:02 +02002789 struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
2790 struct route_table *stable = zvrf->stable[AFI_IP6][SAFI_UNICAST];
paul718e3742002-12-13 20:15:29 +00002791
paul718e3742002-12-13 20:15:29 +00002792 if (! stable)
2793 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00002794
2795 if (!gate &&
2796 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
2797 return -1;
2798
2799 if (!ifname &&
2800 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
2801 return -1;
paul718e3742002-12-13 20:15:29 +00002802
2803 /* Lookup static route prefix. */
2804 rn = route_node_get (stable, p);
2805
2806 /* Do nothing if there is a same static route. */
2807 for (si = rn->info; si; si = si->next)
2808 {
Donald Sharpc1900e02015-11-04 13:26:40 -05002809 if (type == si->type
Donald Sharpd4c27d62015-11-04 13:26:35 -05002810 && (! gate || IPV6_ADDR_SAME (gate, &si->addr.ipv6))
paul718e3742002-12-13 20:15:29 +00002811 && (! ifname || strcmp (ifname, si->ifname) == 0))
2812 {
Donald Sharpc1900e02015-11-04 13:26:40 -05002813 if (distance == si->distance)
2814 {
2815 route_unlock_node (rn);
2816 return 0;
2817 }
2818 else
2819 update = si;
paul718e3742002-12-13 20:15:29 +00002820 }
2821 }
2822
Donald Sharpc1900e02015-11-04 13:26:40 -05002823 if (update)
2824 static_delete_ipv6(p, type, gate, ifname, si->distance, vrf_id);
2825
paul718e3742002-12-13 20:15:29 +00002826 /* Make new static route structure. */
Donald Sharpd4c27d62015-11-04 13:26:35 -05002827 si = XCALLOC (MTYPE_STATIC_ROUTE, sizeof (struct static_route));
paul718e3742002-12-13 20:15:29 +00002828
2829 si->type = type;
2830 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002831 si->flags = flags;
Feng Lu7aaf4ea2015-05-22 11:40:06 +02002832 si->vrf_id = vrf_id;
paul718e3742002-12-13 20:15:29 +00002833
2834 switch (type)
2835 {
2836 case STATIC_IPV6_GATEWAY:
Donald Sharpd4c27d62015-11-04 13:26:35 -05002837 si->addr.ipv6 = *gate;
paul718e3742002-12-13 20:15:29 +00002838 break;
2839 case STATIC_IPV6_IFNAME:
David Lamparter23757db2016-02-24 06:26:02 +01002840 si->ifname = XSTRDUP (MTYPE_TMP, ifname);
paul718e3742002-12-13 20:15:29 +00002841 break;
2842 case STATIC_IPV6_GATEWAY_IFNAME:
Donald Sharpd4c27d62015-11-04 13:26:35 -05002843 si->addr.ipv6 = *gate;
David Lamparter23757db2016-02-24 06:26:02 +01002844 si->ifname = XSTRDUP (MTYPE_TMP, ifname);
paul718e3742002-12-13 20:15:29 +00002845 break;
2846 }
2847
2848 /* Add new static route information to the tree with sort by
2849 distance value and gateway address. */
2850 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2851 {
2852 if (si->distance < cp->distance)
2853 break;
2854 if (si->distance > cp->distance)
2855 continue;
2856 }
2857
2858 /* Make linked list. */
2859 if (pp)
2860 pp->next = si;
2861 else
2862 rn->info = si;
2863 if (cp)
2864 cp->prev = si;
2865 si->prev = pp;
2866 si->next = cp;
2867
2868 /* Install into rib. */
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002869 static_install_route (AFI_IP6, SAFI_UNICAST, p, si);
paul718e3742002-12-13 20:15:29 +00002870
2871 return 1;
2872}
2873
2874/* Delete static route from static route configuration. */
2875int
2876static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
Feng Lu0d0686f2015-05-22 11:40:02 +02002877 const char *ifname, u_char distance, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002878{
2879 struct route_node *rn;
Donald Sharpd4c27d62015-11-04 13:26:35 -05002880 struct static_route *si;
paul718e3742002-12-13 20:15:29 +00002881 struct route_table *stable;
2882
2883 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02002884 stable = zebra_vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +00002885 if (! stable)
2886 return -1;
2887
2888 /* Lookup static route prefix. */
2889 rn = route_node_lookup (stable, p);
2890 if (! rn)
2891 return 0;
2892
2893 /* Find same static route is the tree */
2894 for (si = rn->info; si; si = si->next)
2895 if (distance == si->distance
2896 && type == si->type
Donald Sharpd4c27d62015-11-04 13:26:35 -05002897 && (! gate || IPV6_ADDR_SAME (gate, &si->addr.ipv6))
paul718e3742002-12-13 20:15:29 +00002898 && (! ifname || strcmp (ifname, si->ifname) == 0))
2899 break;
2900
2901 /* Can't find static route. */
2902 if (! si)
2903 {
2904 route_unlock_node (rn);
2905 return 0;
2906 }
2907
2908 /* Install into rib. */
Donald Sharp949b7192015-11-04 13:26:39 -05002909 static_uninstall_route (AFI_IP6, SAFI_UNICAST, p, si);
paul718e3742002-12-13 20:15:29 +00002910
2911 /* Unlink static route from linked list. */
2912 if (si->prev)
2913 si->prev->next = si->next;
2914 else
2915 rn->info = si->next;
2916 if (si->next)
2917 si->next->prev = si->prev;
2918
2919 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002920 if (ifname)
2921 XFREE (0, si->ifname);
Donald Sharpd4c27d62015-11-04 13:26:35 -05002922 XFREE (MTYPE_STATIC_ROUTE, si);
paul718e3742002-12-13 20:15:29 +00002923
2924 return 1;
2925}
David Lamparter6b0655a2014-06-04 06:53:35 +02002926
paul718e3742002-12-13 20:15:29 +00002927/* RIB update function. */
2928void
Feng Lu0d0686f2015-05-22 11:40:02 +02002929rib_update (vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002930{
2931 struct route_node *rn;
2932 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00002933
Feng Lu0d0686f2015-05-22 11:40:02 +02002934 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +00002935 if (table)
2936 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002937 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00002938 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002939
Feng Lu0d0686f2015-05-22 11:40:02 +02002940 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +00002941 if (table)
2942 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002943 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00002944 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002945}
2946
David Lamparter6b0655a2014-06-04 06:53:35 +02002947
paul718e3742002-12-13 20:15:29 +00002948/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00002949static void
paul718e3742002-12-13 20:15:29 +00002950rib_weed_table (struct route_table *table)
2951{
2952 struct route_node *rn;
2953 struct rib *rib;
2954 struct rib *next;
2955
2956 if (table)
2957 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002958 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00002959 {
Paul Jakma6d691122006-07-27 21:49:00 +00002960 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2961 continue;
2962
paulb21b19c2003-06-15 01:28:29 +00002963 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00002964 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00002965 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002966 }
2967}
2968
2969/* Delete all routes from non main table. */
2970void
paula1ac18c2005-06-28 17:17:12 +00002971rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00002972{
Feng Lu0d0686f2015-05-22 11:40:02 +02002973 vrf_iter_t iter;
2974 struct zebra_vrf *zvrf;
2975
2976 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
2977 if ((zvrf = vrf_iter2info (iter)) != NULL)
2978 {
2979 rib_weed_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
2980 rib_weed_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
2981 }
paul718e3742002-12-13 20:15:29 +00002982}
David Lamparter6b0655a2014-06-04 06:53:35 +02002983
Feng Lu0d0686f2015-05-22 11:40:02 +02002984#if 0
paul718e3742002-12-13 20:15:29 +00002985/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00002986static void
paul718e3742002-12-13 20:15:29 +00002987rib_sweep_table (struct route_table *table)
2988{
2989 struct route_node *rn;
2990 struct rib *rib;
2991 struct rib *next;
2992 int ret = 0;
2993
2994 if (table)
2995 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002996 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00002997 {
Paul Jakma6d691122006-07-27 21:49:00 +00002998 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2999 continue;
3000
paul718e3742002-12-13 20:15:29 +00003001 if (rib->type == ZEBRA_ROUTE_KERNEL &&
3002 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
3003 {
Timo Teräs0abf6792016-01-15 17:36:29 +02003004 ret = rib_update_kernel (rn, rib, NULL);
paul718e3742002-12-13 20:15:29 +00003005 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00003006 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003007 }
3008 }
3009}
Feng Lu0d0686f2015-05-22 11:40:02 +02003010#endif
paul718e3742002-12-13 20:15:29 +00003011
3012/* Sweep all RIB tables. */
3013void
paula1ac18c2005-06-28 17:17:12 +00003014rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00003015{
Feng Lu0d0686f2015-05-22 11:40:02 +02003016 vrf_iter_t iter;
3017 struct zebra_vrf *zvrf;
3018
3019 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3020 if ((zvrf = vrf_iter2info (iter)) != NULL)
3021 {
3022 rib_weed_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
3023 rib_weed_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
3024 }
paul718e3742002-12-13 20:15:29 +00003025}
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003026
3027/* Remove specific by protocol routes from 'table'. */
3028static unsigned long
3029rib_score_proto_table (u_char proto, struct route_table *table)
3030{
3031 struct route_node *rn;
3032 struct rib *rib;
3033 struct rib *next;
3034 unsigned long n = 0;
3035
3036 if (table)
3037 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003038 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003039 {
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003040 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3041 continue;
3042 if (rib->type == proto)
3043 {
3044 rib_delnode (rn, rib);
3045 n++;
3046 }
3047 }
3048
3049 return n;
3050}
3051
3052/* Remove specific by protocol routes. */
3053unsigned long
3054rib_score_proto (u_char proto)
3055{
Feng Lu0d0686f2015-05-22 11:40:02 +02003056 vrf_iter_t iter;
3057 struct zebra_vrf *zvrf;
3058 unsigned long cnt = 0;
3059
3060 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3061 if ((zvrf = vrf_iter2info (iter)) != NULL)
3062 cnt += rib_score_proto_table (proto, zvrf->table[AFI_IP][SAFI_UNICAST])
3063 +rib_score_proto_table (proto, zvrf->table[AFI_IP6][SAFI_UNICAST]);
3064
3065 return cnt;
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003066}
3067
paul718e3742002-12-13 20:15:29 +00003068/* Close RIB and clean up kernel routes. */
Feng Lu267ceb22015-05-22 11:40:09 +02003069void
paul718e3742002-12-13 20:15:29 +00003070rib_close_table (struct route_table *table)
3071{
3072 struct route_node *rn;
David Lamparter7ce9e6a2015-01-12 07:05:06 +01003073 rib_table_info_t *info = table->info;
paul718e3742002-12-13 20:15:29 +00003074 struct rib *rib;
3075
3076 if (table)
3077 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003078 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00003079 {
Timo Teräs325823a2016-01-15 17:36:31 +02003080 if (!CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003081 continue;
3082
David Lamparter7ce9e6a2015-01-12 07:05:06 +01003083 if (info->safi == SAFI_UNICAST)
3084 zfpm_trigger_update (rn, NULL);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00003085
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003086 if (! RIB_SYSTEM_ROUTE (rib))
Timo Teräs0abf6792016-01-15 17:36:29 +02003087 rib_update_kernel (rn, rib, NULL);
Paul Jakma6d691122006-07-27 21:49:00 +00003088 }
paul718e3742002-12-13 20:15:29 +00003089}
3090
3091/* Close all RIB tables. */
3092void
paula1ac18c2005-06-28 17:17:12 +00003093rib_close (void)
paul718e3742002-12-13 20:15:29 +00003094{
Feng Lu0d0686f2015-05-22 11:40:02 +02003095 vrf_iter_t iter;
3096 struct zebra_vrf *zvrf;
3097
3098 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3099 if ((zvrf = vrf_iter2info (iter)) != NULL)
3100 {
3101 rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
3102 rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
3103 }
paul718e3742002-12-13 20:15:29 +00003104}
David Lamparter6b0655a2014-06-04 06:53:35 +02003105
paul718e3742002-12-13 20:15:29 +00003106/* Routing information base initialize. */
3107void
paula1ac18c2005-06-28 17:17:12 +00003108rib_init (void)
paul718e3742002-12-13 20:15:29 +00003109{
paul4d38fdb2005-04-28 17:35:14 +00003110 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00003111}
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003112
3113/*
3114 * vrf_id_get_next
3115 *
3116 * Get the first vrf id that is greater than the given vrf id if any.
3117 *
3118 * Returns TRUE if a vrf id was found, FALSE otherwise.
3119 */
3120static inline int
Feng Lu41f44a22015-05-22 11:39:56 +02003121vrf_id_get_next (vrf_id_t vrf_id, vrf_id_t *next_id_p)
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003122{
Feng Lu41f44a22015-05-22 11:39:56 +02003123 vrf_iter_t iter = vrf_iterator (vrf_id);
3124 struct zebra_vrf *zvrf = vrf_iter2info (iter);
3125
3126 /* The same one ? Then find out the next. */
3127 if (zvrf && (zvrf->vrf_id == vrf_id))
3128 zvrf = vrf_iter2info (vrf_next (iter));
3129
3130 if (zvrf)
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003131 {
Feng Lu41f44a22015-05-22 11:39:56 +02003132 *next_id_p = zvrf->vrf_id;
3133 return 1;
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003134 }
3135
3136 return 0;
3137}
3138
3139/*
3140 * rib_tables_iter_next
3141 *
3142 * Returns the next table in the iteration.
3143 */
3144struct route_table *
3145rib_tables_iter_next (rib_tables_iter_t *iter)
3146{
3147 struct route_table *table;
3148
3149 /*
3150 * Array that helps us go over all AFI/SAFI combinations via one
3151 * index.
3152 */
3153 static struct {
3154 afi_t afi;
3155 safi_t safi;
3156 } afi_safis[] = {
3157 { AFI_IP, SAFI_UNICAST },
3158 { AFI_IP, SAFI_MULTICAST },
3159 { AFI_IP6, SAFI_UNICAST },
3160 { AFI_IP6, SAFI_MULTICAST },
3161 };
3162
3163 table = NULL;
3164
3165 switch (iter->state)
3166 {
3167
3168 case RIB_TABLES_ITER_S_INIT:
Donald Sharp0d271292015-11-19 07:21:30 -05003169 iter->vrf_id = VRF_DEFAULT;
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003170 iter->afi_safi_ix = -1;
3171
3172 /* Fall through */
3173
3174 case RIB_TABLES_ITER_S_ITERATING:
3175 iter->afi_safi_ix++;
3176 while (1)
3177 {
3178
3179 while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
3180 {
Feng Lu41f44a22015-05-22 11:39:56 +02003181 table = zebra_vrf_table (afi_safis[iter->afi_safi_ix].afi,
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003182 afi_safis[iter->afi_safi_ix].safi,
3183 iter->vrf_id);
3184 if (table)
3185 break;
3186
3187 iter->afi_safi_ix++;
3188 }
3189
3190 /*
3191 * Found another table in this vrf.
3192 */
3193 if (table)
3194 break;
3195
3196 /*
3197 * Done with all tables in the current vrf, go to the next
3198 * one.
3199 */
3200 if (!vrf_id_get_next (iter->vrf_id, &iter->vrf_id))
3201 break;
3202
3203 iter->afi_safi_ix = 0;
3204 }
3205
3206 break;
3207
3208 case RIB_TABLES_ITER_S_DONE:
3209 return NULL;
3210 }
3211
3212 if (table)
3213 iter->state = RIB_TABLES_ITER_S_ITERATING;
3214 else
3215 iter->state = RIB_TABLES_ITER_S_DONE;
3216
3217 return table;
3218}
Feng Lu41f44a22015-05-22 11:39:56 +02003219
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05003220/* Lookup VRF by identifier. */
3221struct zebra_vrf *
3222zebra_vrf_lookup (vrf_id_t vrf_id)
3223{
3224 return vrf_info_lookup (vrf_id);
3225}
3226
Feng Lu41f44a22015-05-22 11:39:56 +02003227/*
3228 * Create a routing table for the specific AFI/SAFI in the given VRF.
3229 */
3230static void
3231zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi)
3232{
3233 rib_table_info_t *info;
3234 struct route_table *table;
3235
3236 assert (!zvrf->table[afi][safi]);
3237
3238 table = route_table_init ();
3239 zvrf->table[afi][safi] = table;
3240
3241 info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
3242 info->zvrf = zvrf;
3243 info->afi = afi;
3244 info->safi = safi;
3245 table->info = info;
3246}
3247
3248/* Allocate new zebra VRF. */
3249struct zebra_vrf *
3250zebra_vrf_alloc (vrf_id_t vrf_id)
3251{
3252 struct zebra_vrf *zvrf;
Feng Lu758fb8f2014-07-03 18:23:09 +08003253#ifdef HAVE_NETLINK
3254 char nl_name[64];
3255#endif
Feng Lu41f44a22015-05-22 11:39:56 +02003256
3257 zvrf = XCALLOC (MTYPE_ZEBRA_VRF, sizeof (struct zebra_vrf));
3258
3259 /* Allocate routing table and static table. */
3260 zebra_vrf_table_create (zvrf, AFI_IP, SAFI_UNICAST);
3261 zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_UNICAST);
3262 zvrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
3263 zvrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
3264 zebra_vrf_table_create (zvrf, AFI_IP, SAFI_MULTICAST);
3265 zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_MULTICAST);
3266 zvrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
3267 zvrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
3268
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05003269 zvrf->rnh_table[AFI_IP] = route_table_init();
3270 zvrf->rnh_table[AFI_IP6] = route_table_init();
3271
Feng Lu41f44a22015-05-22 11:39:56 +02003272 /* Set VRF ID */
3273 zvrf->vrf_id = vrf_id;
3274
Feng Lu758fb8f2014-07-03 18:23:09 +08003275#ifdef HAVE_NETLINK
3276 /* Initialize netlink sockets */
3277 snprintf (nl_name, 64, "netlink-listen (vrf %u)", vrf_id);
3278 zvrf->netlink.sock = -1;
3279 zvrf->netlink.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name);
3280
3281 snprintf (nl_name, 64, "netlink-cmd (vrf %u)", vrf_id);
3282 zvrf->netlink_cmd.sock = -1;
3283 zvrf->netlink_cmd.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name);
3284#endif
3285
Feng Lu41f44a22015-05-22 11:39:56 +02003286 return zvrf;
3287}
3288
3289/* Lookup the routing table in an enabled VRF. */
3290struct route_table *
3291zebra_vrf_table (afi_t afi, safi_t safi, vrf_id_t vrf_id)
3292{
3293 struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);
3294
3295 if (!zvrf)
3296 return NULL;
3297
3298 if (afi >= AFI_MAX || safi >= SAFI_MAX)
3299 return NULL;
3300
3301 return zvrf->table[afi][safi];
3302}
3303
3304/* Lookup the static routing table in a VRF. */
3305struct route_table *
3306zebra_vrf_static_table (afi_t afi, safi_t safi, vrf_id_t vrf_id)
3307{
3308 struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);
3309
3310 if (!zvrf)
3311 return NULL;
3312
3313 if (afi >= AFI_MAX || safi >= SAFI_MAX)
3314 return NULL;
3315
3316 return zvrf->stable[afi][safi];
3317}
3318