blob: 1d098158a4ca78c98ce06cc3e48e23a53d38960e [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"
paul718e3742002-12-13 20:15:29 +000038
39#include "zebra/rib.h"
40#include "zebra/rt.h"
41#include "zebra/zserv.h"
42#include "zebra/redistribute.h"
43#include "zebra/debug.h"
Avneesh Sachdev5adc2522012-11-13 22:48:59 +000044#include "zebra/zebra_fpm.h"
paul718e3742002-12-13 20:15:29 +000045
46/* Default rtm_table for all clients */
paulb21b19c2003-06-15 01:28:29 +000047extern struct zebra_t zebrad;
paul718e3742002-12-13 20:15:29 +000048
Paul Jakma457eb9a2006-07-27 19:59:58 +000049/* Hold time for RIB process, should be very minimal.
50 * it is useful to able to set it otherwise for testing, hence exported
51 * as global here for test-rig code.
52 */
53int rib_process_hold_time = 10;
54
paul718e3742002-12-13 20:15:29 +000055/* Each route type's string and default distance value. */
Stephen Hemmingerd145bc02008-08-17 17:41:37 +010056static const struct
paul718e3742002-12-13 20:15:29 +000057{
58 int key;
59 int distance;
Paul Jakma57345092011-12-25 17:52:09 +010060} route_info[ZEBRA_ROUTE_MAX] =
paul718e3742002-12-13 20:15:29 +000061{
Paul Jakma57345092011-12-25 17:52:09 +010062 [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0},
63 [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0},
64 [ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0},
65 [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1},
66 [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120},
67 [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120},
68 [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110},
69 [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110},
70 [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115},
71 [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */},
72 [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 95},
David Lamparter7052f222009-08-27 00:28:28 +020073 /* no entry/default: 150 */
paul718e3742002-12-13 20:15:29 +000074};
David Lamparter6b0655a2014-06-04 06:53:35 +020075
David Lamparterbd078122015-01-06 19:53:24 +010076/* RPF lookup behaviour */
77static enum multicast_mode ipv4_multicast_mode = MCAST_NO_CONFIG;
78
David Lampartereed3c482015-03-03 08:51:53 +010079static void __attribute__((format (printf, 4, 5)))
David Lamparter94813742014-04-24 20:22:53 +020080_rnode_zlog(const char *_func, struct route_node *rn, int priority,
81 const char *msgfmt, ...)
82{
Feng Lu0d0686f2015-05-22 11:40:02 +020083 char prefix[PREFIX_STRLEN], buf[256];
David Lamparter94813742014-04-24 20:22:53 +020084 char msgbuf[512];
85 va_list ap;
86
87 va_start(ap, msgfmt);
88 vsnprintf(msgbuf, sizeof(msgbuf), msgfmt, ap);
89 va_end(ap);
90
91 if (rn)
92 {
David Lamparterab2ba612015-01-22 19:02:13 +010093 rib_table_info_t *info = rn->table->info;
94
Feng Lu0d0686f2015-05-22 11:40:02 +020095 snprintf(buf, sizeof(buf), "%s%s vrf %u",
96 prefix2str(&rn->p, prefix, sizeof(prefix)),
97 info->safi == SAFI_MULTICAST ? " (MRIB)" : "",
98 info->zvrf->vrf_id);
David Lamparter94813742014-04-24 20:22:53 +020099 }
100 else
101 {
102 snprintf(buf, sizeof(buf), "{(route_node *) NULL}");
103 }
104
105 zlog (NULL, priority, "%s: %s: %s", _func, buf, msgbuf);
106}
107
108#define rnode_debug(node, ...) \
109 _rnode_zlog(__func__, node, LOG_DEBUG, __VA_ARGS__)
110#define rnode_info(node, ...) \
111 _rnode_zlog(__func__, node, LOG_INFO, __VA_ARGS__)
112
Avneesh Sachdev1b5ed1b2012-11-13 22:48:54 +0000113/*
Avneesh Sachdev78deec42012-11-13 22:48:56 +0000114 * nexthop_type_to_str
115 */
116const char *
117nexthop_type_to_str (enum nexthop_types_t nh_type)
118{
119 static const char *desc[] = {
120 "none",
121 "Directly connected",
122 "Interface route",
123 "IPv4 nexthop",
124 "IPv4 nexthop with ifindex",
125 "IPv4 nexthop with ifname",
126 "IPv6 nexthop",
127 "IPv6 nexthop with ifindex",
128 "IPv6 nexthop with ifname",
129 "Null0 nexthop",
130 };
131
132 if (nh_type >= ZEBRA_NUM_OF (desc))
133 return "<Invalid nh type>";
134
135 return desc[nh_type];
136}
137
Christian Frankefa713d92013-07-05 15:35:37 +0000138/* Add nexthop to the end of a nexthop list. */
paula1ac18c2005-06-28 17:17:12 +0000139static void
Christian Frankefa713d92013-07-05 15:35:37 +0000140_nexthop_add (struct nexthop **target, struct nexthop *nexthop)
paul718e3742002-12-13 20:15:29 +0000141{
142 struct nexthop *last;
143
Christian Frankefa713d92013-07-05 15:35:37 +0000144 for (last = *target; last && last->next; last = last->next)
paul718e3742002-12-13 20:15:29 +0000145 ;
146 if (last)
147 last->next = nexthop;
148 else
Christian Frankefa713d92013-07-05 15:35:37 +0000149 *target = nexthop;
paul718e3742002-12-13 20:15:29 +0000150 nexthop->prev = last;
Christian Frankefa713d92013-07-05 15:35:37 +0000151}
paul718e3742002-12-13 20:15:29 +0000152
Christian Frankefa713d92013-07-05 15:35:37 +0000153/* Add nexthop to the end of a rib node's nexthop list */
154static void
155nexthop_add (struct rib *rib, struct nexthop *nexthop)
156{
157 _nexthop_add(&rib->nexthop, nexthop);
paul718e3742002-12-13 20:15:29 +0000158 rib->nexthop_num++;
159}
160
161/* Delete specified nexthop from the list. */
paula1ac18c2005-06-28 17:17:12 +0000162static void
paul718e3742002-12-13 20:15:29 +0000163nexthop_delete (struct rib *rib, struct nexthop *nexthop)
164{
165 if (nexthop->next)
166 nexthop->next->prev = nexthop->prev;
167 if (nexthop->prev)
168 nexthop->prev->next = nexthop->next;
169 else
170 rib->nexthop = nexthop->next;
171 rib->nexthop_num--;
172}
173
Christian Frankefa713d92013-07-05 15:35:37 +0000174static void nexthops_free(struct nexthop *nexthop);
175
paul718e3742002-12-13 20:15:29 +0000176/* Free nexthop. */
paula1ac18c2005-06-28 17:17:12 +0000177static void
paul718e3742002-12-13 20:15:29 +0000178nexthop_free (struct nexthop *nexthop)
179{
paula4b70762003-05-16 17:19:48 +0000180 if (nexthop->ifname)
181 XFREE (0, nexthop->ifname);
Christian Frankefa713d92013-07-05 15:35:37 +0000182 if (nexthop->resolved)
183 nexthops_free(nexthop->resolved);
paul718e3742002-12-13 20:15:29 +0000184 XFREE (MTYPE_NEXTHOP, nexthop);
185}
186
Christian Frankefa713d92013-07-05 15:35:37 +0000187/* Frees a list of nexthops */
188static void
189nexthops_free (struct nexthop *nexthop)
190{
191 struct nexthop *nh, *next;
192
193 for (nh = nexthop; nh; nh = next)
194 {
195 next = nh->next;
196 nexthop_free (nh);
197 }
198}
199
paul718e3742002-12-13 20:15:29 +0000200struct nexthop *
201nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
202{
203 struct nexthop *nexthop;
204
Stephen Hemminger393deb92008-08-18 14:13:29 -0700205 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000206 nexthop->type = NEXTHOP_TYPE_IFINDEX;
207 nexthop->ifindex = ifindex;
208
209 nexthop_add (rib, nexthop);
210
211 return nexthop;
212}
213
214struct nexthop *
215nexthop_ifname_add (struct rib *rib, char *ifname)
216{
217 struct nexthop *nexthop;
218
Stephen Hemminger393deb92008-08-18 14:13:29 -0700219 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000220 nexthop->type = NEXTHOP_TYPE_IFNAME;
paula4b70762003-05-16 17:19:48 +0000221 nexthop->ifname = XSTRDUP (0, ifname);
paul718e3742002-12-13 20:15:29 +0000222
223 nexthop_add (rib, nexthop);
224
225 return nexthop;
226}
227
228struct nexthop *
Paul Jakma7514fb72007-05-02 16:05:35 +0000229nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src)
paul718e3742002-12-13 20:15:29 +0000230{
231 struct nexthop *nexthop;
232
Stephen Hemminger393deb92008-08-18 14:13:29 -0700233 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000234 nexthop->type = NEXTHOP_TYPE_IPV4;
235 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000236 if (src)
237 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000238
239 nexthop_add (rib, nexthop);
240
241 return nexthop;
242}
243
Josh Bailey26e2ae32012-03-22 01:09:21 -0700244struct nexthop *
paul718e3742002-12-13 20:15:29 +0000245nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
Paul Jakma7514fb72007-05-02 16:05:35 +0000246 struct in_addr *src, unsigned int ifindex)
paul718e3742002-12-13 20:15:29 +0000247{
248 struct nexthop *nexthop;
249
Stephen Hemminger393deb92008-08-18 14:13:29 -0700250 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000251 nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
252 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000253 if (src)
254 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000255 nexthop->ifindex = ifindex;
256
257 nexthop_add (rib, nexthop);
258
259 return nexthop;
260}
261
262#ifdef HAVE_IPV6
263struct nexthop *
264nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
265{
266 struct nexthop *nexthop;
267
Stephen Hemminger393deb92008-08-18 14:13:29 -0700268 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000269 nexthop->type = NEXTHOP_TYPE_IPV6;
270 nexthop->gate.ipv6 = *ipv6;
271
272 nexthop_add (rib, nexthop);
273
274 return nexthop;
275}
276
paula1ac18c2005-06-28 17:17:12 +0000277static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000278nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
279 char *ifname)
280{
281 struct nexthop *nexthop;
282
Stephen Hemminger393deb92008-08-18 14:13:29 -0700283 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000284 nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
285 nexthop->gate.ipv6 = *ipv6;
286 nexthop->ifname = XSTRDUP (0, ifname);
287
288 nexthop_add (rib, nexthop);
289
290 return nexthop;
291}
292
paula1ac18c2005-06-28 17:17:12 +0000293static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000294nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
295 unsigned int ifindex)
296{
297 struct nexthop *nexthop;
298
Stephen Hemminger393deb92008-08-18 14:13:29 -0700299 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000300 nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
301 nexthop->gate.ipv6 = *ipv6;
302 nexthop->ifindex = ifindex;
303
304 nexthop_add (rib, nexthop);
305
306 return nexthop;
307}
308#endif /* HAVE_IPV6 */
309
paul595db7f2003-05-25 21:35:06 +0000310struct nexthop *
311nexthop_blackhole_add (struct rib *rib)
312{
313 struct nexthop *nexthop;
314
Stephen Hemminger393deb92008-08-18 14:13:29 -0700315 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul595db7f2003-05-25 21:35:06 +0000316 nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
317 SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
318
319 nexthop_add (rib, nexthop);
320
321 return nexthop;
322}
323
Christian Frankefa713d92013-07-05 15:35:37 +0000324/* This method checks whether a recursive nexthop has at
325 * least one resolved nexthop in the fib.
326 */
327int
328nexthop_has_fib_child(struct nexthop *nexthop)
329{
330 struct nexthop *nh;
331
332 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
333 return 0;
334
335 for (nh = nexthop->resolved; nh; nh = nh->next)
336 if (CHECK_FLAG (nh->flags, NEXTHOP_FLAG_FIB))
337 return 1;
338
339 return 0;
340}
341
paul718e3742002-12-13 20:15:29 +0000342/* If force flag is not set, do not modify falgs at all for uninstall
343 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000344static int
paul718e3742002-12-13 20:15:29 +0000345nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
346 struct route_node *top)
347{
348 struct prefix_ipv4 p;
349 struct route_table *table;
350 struct route_node *rn;
351 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000352 int resolved;
paul718e3742002-12-13 20:15:29 +0000353 struct nexthop *newhop;
Christian Frankefa713d92013-07-05 15:35:37 +0000354 struct nexthop *resolved_hop;
paul718e3742002-12-13 20:15:29 +0000355
356 if (nexthop->type == NEXTHOP_TYPE_IPV4)
357 nexthop->ifindex = 0;
358
359 if (set)
Christian Frankefa713d92013-07-05 15:35:37 +0000360 {
361 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
362 nexthops_free(nexthop->resolved);
363 nexthop->resolved = NULL;
Timo Teräsb11f3b52015-11-02 16:50:07 +0200364 rib->nexthop_mtu = 0;
Christian Frankefa713d92013-07-05 15:35:37 +0000365 }
paul718e3742002-12-13 20:15:29 +0000366
367 /* Make lookup prefix. */
368 memset (&p, 0, sizeof (struct prefix_ipv4));
369 p.family = AF_INET;
370 p.prefixlen = IPV4_MAX_PREFIXLEN;
371 p.prefix = nexthop->gate.ipv4;
372
373 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200374 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, rib->vrf_id);
paul718e3742002-12-13 20:15:29 +0000375 if (! table)
376 return 0;
377
378 rn = route_node_match (table, (struct prefix *) &p);
379 while (rn)
380 {
381 route_unlock_node (rn);
382
David Warda50c1072009-12-03 15:34:39 +0300383 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000384 if (rn == top)
385 return 0;
386
387 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000388 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100389 {
390 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
391 continue;
392 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
393 break;
394 }
paul718e3742002-12-13 20:15:29 +0000395
396 /* If there is no selected route or matched route is EGP, go up
397 tree. */
398 if (! match
399 || match->type == ZEBRA_ROUTE_BGP)
400 {
401 do {
402 rn = rn->parent;
403 } while (rn && rn->info == NULL);
404 if (rn)
405 route_lock_node (rn);
406 }
407 else
408 {
Christian Franke48a53dc2013-07-05 15:35:38 +0000409 /* If the longest prefix match for the nexthop yields
410 * a blackhole, mark it as inactive. */
411 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE)
412 || CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT))
413 return 0;
414
paul718e3742002-12-13 20:15:29 +0000415 if (match->type == ZEBRA_ROUTE_CONNECT)
416 {
417 /* Directly point connected route. */
418 newhop = match->nexthop;
419 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
420 nexthop->ifindex = newhop->ifindex;
421
422 return 1;
423 }
424 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
425 {
Christian Frankefa713d92013-07-05 15:35:37 +0000426 resolved = 0;
paul718e3742002-12-13 20:15:29 +0000427 for (newhop = match->nexthop; newhop; newhop = newhop->next)
428 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
429 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
430 {
431 if (set)
432 {
433 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
Christian Frankefa713d92013-07-05 15:35:37 +0000434
435 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
436 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
Christian Frankec3e6b592013-07-05 15:35:40 +0000437 /* If the resolving route specifies a gateway, use it */
438 if (newhop->type == NEXTHOP_TYPE_IPV4
439 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX
440 || newhop->type == NEXTHOP_TYPE_IPV4_IFNAME)
441 {
442 resolved_hop->type = newhop->type;
443 resolved_hop->gate.ipv4 = newhop->gate.ipv4;
Christian Frankefa713d92013-07-05 15:35:37 +0000444
Christian Frankec3e6b592013-07-05 15:35:40 +0000445 if (newhop->ifindex)
446 {
447 resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
448 resolved_hop->ifindex = newhop->ifindex;
449 }
450 }
Christian Frankefa713d92013-07-05 15:35:37 +0000451
Christian Frankec3e6b592013-07-05 15:35:40 +0000452 /* If the resolving route is an interface route,
453 * it means the gateway we are looking up is connected
454 * to that interface. (The actual network is _not_ onlink).
455 * Therefore, the resolved route should have the original
456 * gateway as nexthop as it is directly connected.
457 *
458 * On Linux, we have to set the onlink netlink flag because
459 * otherwise, the kernel won't accept the route. */
paul718e3742002-12-13 20:15:29 +0000460 if (newhop->type == NEXTHOP_TYPE_IFINDEX
Christian Frankec3e6b592013-07-05 15:35:40 +0000461 || newhop->type == NEXTHOP_TYPE_IFNAME)
462 {
463 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
464 resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
465 resolved_hop->gate.ipv4 = nexthop->gate.ipv4;
466 resolved_hop->ifindex = newhop->ifindex;
467 }
Christian Frankefa713d92013-07-05 15:35:37 +0000468
469 _nexthop_add(&nexthop->resolved, resolved_hop);
paul718e3742002-12-13 20:15:29 +0000470 }
Christian Frankefa713d92013-07-05 15:35:37 +0000471 resolved = 1;
paul718e3742002-12-13 20:15:29 +0000472 }
Timo Teräsb11f3b52015-11-02 16:50:07 +0200473 if (resolved && set)
474 rib->nexthop_mtu = match->mtu;
Christian Frankefa713d92013-07-05 15:35:37 +0000475 return resolved;
paul718e3742002-12-13 20:15:29 +0000476 }
477 else
478 {
479 return 0;
480 }
481 }
482 }
483 return 0;
484}
485
486#ifdef HAVE_IPV6
487/* If force flag is not set, do not modify falgs at all for uninstall
488 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000489static int
paul718e3742002-12-13 20:15:29 +0000490nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
491 struct route_node *top)
492{
493 struct prefix_ipv6 p;
494 struct route_table *table;
495 struct route_node *rn;
496 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000497 int resolved;
paul718e3742002-12-13 20:15:29 +0000498 struct nexthop *newhop;
Christian Frankefa713d92013-07-05 15:35:37 +0000499 struct nexthop *resolved_hop;
paul718e3742002-12-13 20:15:29 +0000500
501 if (nexthop->type == NEXTHOP_TYPE_IPV6)
502 nexthop->ifindex = 0;
503
504 if (set)
Christian Frankefa713d92013-07-05 15:35:37 +0000505 {
506 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
507 nexthops_free(nexthop->resolved);
508 nexthop->resolved = NULL;
509 }
paul718e3742002-12-13 20:15:29 +0000510
511 /* Make lookup prefix. */
512 memset (&p, 0, sizeof (struct prefix_ipv6));
513 p.family = AF_INET6;
514 p.prefixlen = IPV6_MAX_PREFIXLEN;
515 p.prefix = nexthop->gate.ipv6;
516
517 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200518 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, rib->vrf_id);
paul718e3742002-12-13 20:15:29 +0000519 if (! table)
520 return 0;
521
522 rn = route_node_match (table, (struct prefix *) &p);
523 while (rn)
524 {
525 route_unlock_node (rn);
526
David Warda50c1072009-12-03 15:34:39 +0300527 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000528 if (rn == top)
529 return 0;
530
531 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000532 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100533 {
534 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
535 continue;
536 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
537 break;
538 }
paul718e3742002-12-13 20:15:29 +0000539
540 /* If there is no selected route or matched route is EGP, go up
541 tree. */
542 if (! match
543 || match->type == ZEBRA_ROUTE_BGP)
544 {
545 do {
546 rn = rn->parent;
547 } while (rn && rn->info == NULL);
548 if (rn)
549 route_lock_node (rn);
550 }
551 else
552 {
Christian Franke48a53dc2013-07-05 15:35:38 +0000553 /* If the longest prefix match for the nexthop yields
554 * a blackhole, mark it as inactive. */
555 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE)
556 || CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT))
557 return 0;
558
paul718e3742002-12-13 20:15:29 +0000559 if (match->type == ZEBRA_ROUTE_CONNECT)
560 {
561 /* Directly point connected route. */
562 newhop = match->nexthop;
563
564 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
565 nexthop->ifindex = newhop->ifindex;
566
567 return 1;
568 }
569 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
570 {
Christian Frankefa713d92013-07-05 15:35:37 +0000571 resolved = 0;
paul718e3742002-12-13 20:15:29 +0000572 for (newhop = match->nexthop; newhop; newhop = newhop->next)
573 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
574 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
575 {
576 if (set)
577 {
578 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
Christian Frankefa713d92013-07-05 15:35:37 +0000579
580 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
581 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
Christian Frankec3e6b592013-07-05 15:35:40 +0000582 /* See nexthop_active_ipv4 for a description how the
583 * resolved nexthop is constructed. */
paul718e3742002-12-13 20:15:29 +0000584 if (newhop->type == NEXTHOP_TYPE_IPV6
585 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
586 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
Christian Frankec3e6b592013-07-05 15:35:40 +0000587 {
588 resolved_hop->type = newhop->type;
589 resolved_hop->gate.ipv6 = newhop->gate.ipv6;
590
591 if (newhop->ifindex)
592 {
593 resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
594 resolved_hop->ifindex = newhop->ifindex;
595 }
596 }
Christian Frankefa713d92013-07-05 15:35:37 +0000597
paul718e3742002-12-13 20:15:29 +0000598 if (newhop->type == NEXTHOP_TYPE_IFINDEX
Christian Frankec3e6b592013-07-05 15:35:40 +0000599 || newhop->type == NEXTHOP_TYPE_IFNAME)
600 {
601 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
602 resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
603 resolved_hop->gate.ipv6 = nexthop->gate.ipv6;
604 resolved_hop->ifindex = newhop->ifindex;
605 }
Christian Frankefa713d92013-07-05 15:35:37 +0000606
607 _nexthop_add(&nexthop->resolved, resolved_hop);
paul718e3742002-12-13 20:15:29 +0000608 }
Christian Frankefa713d92013-07-05 15:35:37 +0000609 resolved = 1;
paul718e3742002-12-13 20:15:29 +0000610 }
Christian Frankefa713d92013-07-05 15:35:37 +0000611 return resolved;
paul718e3742002-12-13 20:15:29 +0000612 }
613 else
614 {
615 return 0;
616 }
617 }
618 }
619 return 0;
620}
621#endif /* HAVE_IPV6 */
622
623struct rib *
David Lamparter24480d42015-01-22 19:09:36 +0100624rib_match_ipv4_safi (struct in_addr addr, safi_t safi, int skip_bgp,
Feng Lu0d0686f2015-05-22 11:40:02 +0200625 struct route_node **rn_out, vrf_id_t vrf_id)
Everton Marques3dea1782014-09-22 19:35:51 -0300626{
627 struct route_table *table;
628 struct route_node *rn;
629 struct rib *match;
630 struct nexthop *newhop, *tnewhop;
631 int recursing;
632
633 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200634 table = zebra_vrf_table (AFI_IP, safi, vrf_id);
Everton Marques3dea1782014-09-22 19:35:51 -0300635 if (! table)
636 return 0;
637
638 rn = route_node_match_ipv4 (table, &addr);
639
640 while (rn)
641 {
642 route_unlock_node (rn);
643
644 /* Pick up selected route. */
645 RNODE_FOREACH_RIB (rn, match)
646 {
647 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
648 continue;
649 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
650 break;
651 }
652
653 /* If there is no selected route or matched route is EGP, go up
654 tree. */
Everton Marques83d71122014-09-19 16:39:34 -0300655 if (!match || (skip_bgp && (match->type == ZEBRA_ROUTE_BGP)))
Everton Marques3dea1782014-09-22 19:35:51 -0300656 {
657 do {
658 rn = rn->parent;
659 } while (rn && rn->info == NULL);
660 if (rn)
661 route_lock_node (rn);
662 }
663 else
664 {
David Lamparter24480d42015-01-22 19:09:36 +0100665 if (match->type != ZEBRA_ROUTE_CONNECT)
Everton Marques3dea1782014-09-22 19:35:51 -0300666 {
David Lamparter24480d42015-01-22 19:09:36 +0100667 int found = 0;
Everton Marques3dea1782014-09-22 19:35:51 -0300668 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
669 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
David Lamparter24480d42015-01-22 19:09:36 +0100670 {
671 found = 1;
672 break;
673 }
674 if (!found)
675 return NULL;
Everton Marques3dea1782014-09-22 19:35:51 -0300676 }
David Lamparter24480d42015-01-22 19:09:36 +0100677
678 if (rn_out)
679 *rn_out = rn;
680 return match;
Everton Marques3dea1782014-09-22 19:35:51 -0300681 }
682 }
683 return NULL;
684}
685
686struct rib *
Feng Lu0d0686f2015-05-22 11:40:02 +0200687rib_match_ipv4_multicast (struct in_addr addr, struct route_node **rn_out,
688 vrf_id_t vrf_id)
David Lamparterbd078122015-01-06 19:53:24 +0100689{
690 struct rib *rib = NULL, *mrib = NULL, *urib = NULL;
691 struct route_node *m_rn = NULL, *u_rn = NULL;
692 int skip_bgp = 0; /* bool */
693
694 switch (ipv4_multicast_mode)
695 {
696 case MCAST_MRIB_ONLY:
Feng Lu0d0686f2015-05-22 11:40:02 +0200697 return rib_match_ipv4_safi (addr, SAFI_MULTICAST, skip_bgp, rn_out,
698 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100699 case MCAST_URIB_ONLY:
Feng Lu0d0686f2015-05-22 11:40:02 +0200700 return rib_match_ipv4_safi (addr, SAFI_UNICAST, skip_bgp, rn_out,
701 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100702 case MCAST_NO_CONFIG:
703 case MCAST_MIX_MRIB_FIRST:
Feng Lu0d0686f2015-05-22 11:40:02 +0200704 rib = mrib = rib_match_ipv4_safi (addr, SAFI_MULTICAST, skip_bgp, &m_rn,
705 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100706 if (!mrib)
Feng Lu0d0686f2015-05-22 11:40:02 +0200707 rib = urib = rib_match_ipv4_safi (addr, SAFI_UNICAST, skip_bgp, &u_rn,
708 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100709 break;
710 case MCAST_MIX_DISTANCE:
Feng Lu0d0686f2015-05-22 11:40:02 +0200711 mrib = rib_match_ipv4_safi (addr, SAFI_MULTICAST, skip_bgp, &m_rn,
712 vrf_id);
713 urib = rib_match_ipv4_safi (addr, SAFI_UNICAST, skip_bgp, &u_rn,
714 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100715 if (mrib && urib)
716 rib = urib->distance < mrib->distance ? urib : mrib;
717 else if (mrib)
718 rib = mrib;
719 else if (urib)
720 rib = urib;
721 break;
722 case MCAST_MIX_PFXLEN:
Feng Lu0d0686f2015-05-22 11:40:02 +0200723 mrib = rib_match_ipv4_safi (addr, SAFI_MULTICAST, skip_bgp, &m_rn,
724 vrf_id);
725 urib = rib_match_ipv4_safi (addr, SAFI_UNICAST, skip_bgp, &u_rn,
726 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100727 if (mrib && urib)
728 rib = u_rn->p.prefixlen > m_rn->p.prefixlen ? urib : mrib;
729 else if (mrib)
730 rib = mrib;
731 else if (urib)
732 rib = urib;
733 break;
734 }
735
736 if (rn_out)
737 *rn_out = (rib == mrib) ? m_rn : u_rn;
738
739 if (IS_ZEBRA_DEBUG_RIB)
740 {
741 char buf[BUFSIZ];
742 inet_ntop (AF_INET, &addr, buf, BUFSIZ);
743
Feng Lu0d0686f2015-05-22 11:40:02 +0200744 zlog_debug("%s: %s vrf %u: found %s, using %s",
745 __func__, buf, vrf_id,
David Lamparterbd078122015-01-06 19:53:24 +0100746 mrib ? (urib ? "MRIB+URIB" : "MRIB") :
747 urib ? "URIB" : "nothing",
748 rib == urib ? "URIB" : rib == mrib ? "MRIB" : "none");
749 }
750 return rib;
751}
752
753void
754multicast_mode_ipv4_set (enum multicast_mode mode)
755{
756 if (IS_ZEBRA_DEBUG_RIB)
757 zlog_debug("%s: multicast lookup mode set (%d)", __func__, mode);
758 ipv4_multicast_mode = mode;
759}
760
761enum multicast_mode
762multicast_mode_ipv4_get (void)
763{
764 return ipv4_multicast_mode;
765}
766
767struct rib *
Feng Lu0d0686f2015-05-22 11:40:02 +0200768rib_lookup_ipv4 (struct prefix_ipv4 *p, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000769{
770 struct route_table *table;
771 struct route_node *rn;
772 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000773 struct nexthop *nexthop, *tnexthop;
774 int recursing;
paul718e3742002-12-13 20:15:29 +0000775
776 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200777 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +0000778 if (! table)
779 return 0;
780
781 rn = route_node_lookup (table, (struct prefix *) p);
782
783 /* No route for this prefix. */
784 if (! rn)
785 return NULL;
786
787 /* Unlock node. */
788 route_unlock_node (rn);
789
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000790 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100791 {
792 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
793 continue;
794 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
795 break;
796 }
paul718e3742002-12-13 20:15:29 +0000797
798 if (! match || match->type == ZEBRA_ROUTE_BGP)
799 return NULL;
800
801 if (match->type == ZEBRA_ROUTE_CONNECT)
802 return match;
803
Christian Frankefa713d92013-07-05 15:35:37 +0000804 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +0000805 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
806 return match;
807
808 return NULL;
809}
810
Denis Ovsienkodc958242007-08-13 16:03:06 +0000811/*
812 * This clone function, unlike its original rib_lookup_ipv4(), checks
813 * if specified IPv4 route record (prefix/mask -> gate) exists in
814 * the whole RIB and has ZEBRA_FLAG_SELECTED set.
815 *
816 * Return values:
817 * -1: error
818 * 0: exact match found
819 * 1: a match was found with a different gate
820 * 2: connected route found
821 * 3: no matches found
822 */
823int
Feng Lu0d0686f2015-05-22 11:40:02 +0200824rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate,
825 vrf_id_t vrf_id)
Denis Ovsienkodc958242007-08-13 16:03:06 +0000826{
827 struct route_table *table;
828 struct route_node *rn;
829 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000830 struct nexthop *nexthop, *tnexthop;
831 int recursing;
832 int nexthops_active;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000833
834 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200835 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
Denis Ovsienkodc958242007-08-13 16:03:06 +0000836 if (! table)
837 return ZEBRA_RIB_LOOKUP_ERROR;
838
839 /* Scan the RIB table for exactly matching RIB entry. */
840 rn = route_node_lookup (table, (struct prefix *) p);
841
842 /* No route for this prefix. */
843 if (! rn)
844 return ZEBRA_RIB_NOTFOUND;
845
846 /* Unlock node. */
847 route_unlock_node (rn);
848
849 /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000850 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100851 {
852 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
853 continue;
854 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
855 break;
856 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000857
858 /* None such found :( */
859 if (!match)
860 return ZEBRA_RIB_NOTFOUND;
861
862 if (match->type == ZEBRA_ROUTE_CONNECT)
863 return ZEBRA_RIB_FOUND_CONNECTED;
864
865 /* Ok, we have a cood candidate, let's check it's nexthop list... */
Christian Frankefa713d92013-07-05 15:35:37 +0000866 nexthops_active = 0;
867 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000868 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000869 {
Christian Frankefa713d92013-07-05 15:35:37 +0000870 nexthops_active = 1;
871 if (nexthop->gate.ipv4.s_addr == sockunion2ip (qgate))
872 return ZEBRA_RIB_FOUND_EXACT;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000873 if (IS_ZEBRA_DEBUG_RIB)
Christian Frankefa713d92013-07-05 15:35:37 +0000874 {
875 char gate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
876 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
877 inet_ntop (AF_INET, &sockunion2ip(qgate), qgate_buf, INET_ADDRSTRLEN);
878 zlog_debug ("%s: qgate == %s, %s == %s", __func__,
879 qgate_buf, recursing ? "rgate" : "gate", gate_buf);
880 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000881 }
Christian Frankefa713d92013-07-05 15:35:37 +0000882
883 if (nexthops_active)
884 return ZEBRA_RIB_FOUND_NOGATE;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000885
886 return ZEBRA_RIB_NOTFOUND;
887}
888
paul718e3742002-12-13 20:15:29 +0000889#ifdef HAVE_IPV6
890struct rib *
Feng Lu0d0686f2015-05-22 11:40:02 +0200891rib_match_ipv6 (struct in6_addr *addr, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000892{
893 struct prefix_ipv6 p;
894 struct route_table *table;
895 struct route_node *rn;
896 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000897 struct nexthop *newhop, *tnewhop;
898 int recursing;
paul718e3742002-12-13 20:15:29 +0000899
900 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200901 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +0000902 if (! table)
903 return 0;
904
905 memset (&p, 0, sizeof (struct prefix_ipv6));
906 p.family = AF_INET6;
907 p.prefixlen = IPV6_MAX_PREFIXLEN;
908 IPV6_ADDR_COPY (&p.prefix, addr);
909
910 rn = route_node_match (table, (struct prefix *) &p);
911
912 while (rn)
913 {
914 route_unlock_node (rn);
915
916 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000917 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100918 {
919 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
920 continue;
921 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
922 break;
923 }
paul718e3742002-12-13 20:15:29 +0000924
925 /* If there is no selected route or matched route is EGP, go up
926 tree. */
927 if (! match
928 || match->type == ZEBRA_ROUTE_BGP)
929 {
930 do {
931 rn = rn->parent;
932 } while (rn && rn->info == NULL);
933 if (rn)
934 route_lock_node (rn);
935 }
936 else
937 {
938 if (match->type == ZEBRA_ROUTE_CONNECT)
939 /* Directly point connected route. */
940 return match;
941 else
942 {
Christian Frankefa713d92013-07-05 15:35:37 +0000943 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
paul718e3742002-12-13 20:15:29 +0000944 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
945 return match;
946 return NULL;
947 }
948 }
949 }
950 return NULL;
951}
952#endif /* HAVE_IPV6 */
953
Paul Jakma7514fb72007-05-02 16:05:35 +0000954#define RIB_SYSTEM_ROUTE(R) \
955 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
956
Denis Ovsienkodc958242007-08-13 16:03:06 +0000957/* This function verifies reachability of one given nexthop, which can be
958 * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
959 * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
960 * nexthop->ifindex will be updated appropriately as well.
961 * An existing route map can turn (otherwise active) nexthop into inactive, but
962 * not vice versa.
963 *
964 * The return value is the final value of 'ACTIVE' flag.
965 */
966
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300967static unsigned
paul718e3742002-12-13 20:15:29 +0000968nexthop_active_check (struct route_node *rn, struct rib *rib,
969 struct nexthop *nexthop, int set)
970{
Christian Frankef3a17322013-07-05 15:35:41 +0000971 rib_table_info_t *info = rn->table->info;
paul718e3742002-12-13 20:15:29 +0000972 struct interface *ifp;
Paul Jakma7514fb72007-05-02 16:05:35 +0000973 route_map_result_t ret = RMAP_MATCH;
974 extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
975 struct route_map *rmap;
976 int family;
paul718e3742002-12-13 20:15:29 +0000977
Paul Jakma7514fb72007-05-02 16:05:35 +0000978 family = 0;
paul718e3742002-12-13 20:15:29 +0000979 switch (nexthop->type)
980 {
981 case NEXTHOP_TYPE_IFINDEX:
Feng Lu0d0686f2015-05-22 11:40:02 +0200982 ifp = if_lookup_by_index_vrf (nexthop->ifindex, rib->vrf_id);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000983 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000984 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
985 else
986 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
987 break;
paul718e3742002-12-13 20:15:29 +0000988 case NEXTHOP_TYPE_IPV6_IFNAME:
Paul Jakma7514fb72007-05-02 16:05:35 +0000989 family = AFI_IP6;
990 case NEXTHOP_TYPE_IFNAME:
Feng Lu0d0686f2015-05-22 11:40:02 +0200991 ifp = if_lookup_by_name_vrf (nexthop->ifname, rib->vrf_id);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000992 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000993 {
994 if (set)
995 nexthop->ifindex = ifp->ifindex;
996 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
997 }
998 else
999 {
1000 if (set)
1001 nexthop->ifindex = 0;
1002 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1003 }
1004 break;
1005 case NEXTHOP_TYPE_IPV4:
1006 case NEXTHOP_TYPE_IPV4_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +00001007 family = AFI_IP;
paul718e3742002-12-13 20:15:29 +00001008 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
1009 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1010 else
1011 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1012 break;
1013#ifdef HAVE_IPV6
1014 case NEXTHOP_TYPE_IPV6:
Paul Jakma7514fb72007-05-02 16:05:35 +00001015 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +00001016 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
1017 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1018 else
1019 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1020 break;
1021 case NEXTHOP_TYPE_IPV6_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +00001022 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +00001023 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
1024 {
Feng Lu0d0686f2015-05-22 11:40:02 +02001025 ifp = if_lookup_by_index_vrf (nexthop->ifindex, rib->vrf_id);
Andrew J. Schorr3f087672008-01-08 20:12:46 +00001026 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001027 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1028 else
1029 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1030 }
1031 else
1032 {
1033 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
1034 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1035 else
1036 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1037 }
1038 break;
1039#endif /* HAVE_IPV6 */
paul595db7f2003-05-25 21:35:06 +00001040 case NEXTHOP_TYPE_BLACKHOLE:
1041 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1042 break;
paul718e3742002-12-13 20:15:29 +00001043 default:
1044 break;
1045 }
Paul Jakma7514fb72007-05-02 16:05:35 +00001046 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1047 return 0;
1048
Christian Frankef3a17322013-07-05 15:35:41 +00001049 /* XXX: What exactly do those checks do? Do we support
1050 * e.g. IPv4 routes with IPv6 nexthops or vice versa? */
Paul Jakma7514fb72007-05-02 16:05:35 +00001051 if (RIB_SYSTEM_ROUTE(rib) ||
1052 (family == AFI_IP && rn->p.family != AF_INET) ||
1053 (family == AFI_IP6 && rn->p.family != AF_INET6))
1054 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1055
Christian Frankef3a17322013-07-05 15:35:41 +00001056 /* The original code didn't determine the family correctly
1057 * e.g. for NEXTHOP_TYPE_IFINDEX. Retrieve the correct afi
1058 * from the rib_table_info in those cases.
1059 * Possibly it may be better to use only the rib_table_info
1060 * in every case.
1061 */
1062 if (!family)
1063 family = info->afi;
1064
Paul Jakma7514fb72007-05-02 16:05:35 +00001065 rmap = 0;
1066 if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
1067 proto_rm[family][rib->type])
1068 rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
1069 if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
1070 rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
1071 if (rmap) {
Feng Lu1885d0a2015-05-22 11:40:04 +02001072 struct nexthop_vrfid nh_vrf = {nexthop, rib->vrf_id};
1073 ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, &nh_vrf);
Paul Jakma7514fb72007-05-02 16:05:35 +00001074 }
1075
1076 if (ret == RMAP_DENYMATCH)
1077 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
paul718e3742002-12-13 20:15:29 +00001078 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1079}
1080
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001081/* Iterate over all nexthops of the given RIB entry and refresh their
1082 * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
1083 * nexthop is found to toggle the ACTIVE flag, the whole rib structure
Timo Teräs7eb61362015-11-02 16:50:05 +02001084 * is flagged with RIB_ENTRY_CHANGED. The 4th 'set' argument is
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001085 * transparently passed to nexthop_active_check().
1086 *
1087 * Return value is the new number of active nexthops.
1088 */
1089
paula1ac18c2005-06-28 17:17:12 +00001090static int
paul718e3742002-12-13 20:15:29 +00001091nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
1092{
1093 struct nexthop *nexthop;
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001094 unsigned int prev_active, prev_index, new_active;
paul718e3742002-12-13 20:15:29 +00001095
1096 rib->nexthop_active_num = 0;
Timo Teräs7eb61362015-11-02 16:50:05 +02001097 UNSET_FLAG (rib->status, RIB_ENTRY_CHANGED);
paul718e3742002-12-13 20:15:29 +00001098
1099 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001100 {
1101 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001102 prev_index = nexthop->ifindex;
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001103 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
1104 rib->nexthop_active_num++;
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001105 if (prev_active != new_active ||
1106 prev_index != nexthop->ifindex)
Timo Teräs7eb61362015-11-02 16:50:05 +02001107 SET_FLAG (rib->status, RIB_ENTRY_CHANGED);
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001108 }
paul718e3742002-12-13 20:15:29 +00001109 return rib->nexthop_active_num;
1110}
paul6baeb982003-10-28 03:47:15 +00001111
David Lamparter6b0655a2014-06-04 06:53:35 +02001112
paul718e3742002-12-13 20:15:29 +00001113
paula1ac18c2005-06-28 17:17:12 +00001114static void
paul718e3742002-12-13 20:15:29 +00001115rib_install_kernel (struct route_node *rn, struct rib *rib)
1116{
1117 int ret = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001118 struct nexthop *nexthop, *tnexthop;
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001119 rib_table_info_t *info = rn->table->info;
Christian Frankefa713d92013-07-05 15:35:37 +00001120 int recursing;
paul718e3742002-12-13 20:15:29 +00001121
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001122 if (info->safi != SAFI_UNICAST)
1123 {
1124 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1125 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1126 return;
1127 }
1128
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001129 /*
1130 * Make sure we update the FPM any time we send new information to
1131 * the kernel.
1132 */
1133 zfpm_trigger_update (rn, "installing in kernel");
paul718e3742002-12-13 20:15:29 +00001134 switch (PREFIX_FAMILY (&rn->p))
1135 {
1136 case AF_INET:
1137 ret = kernel_add_ipv4 (&rn->p, rib);
1138 break;
1139#ifdef HAVE_IPV6
1140 case AF_INET6:
1141 ret = kernel_add_ipv6 (&rn->p, rib);
1142 break;
1143#endif /* HAVE_IPV6 */
1144 }
1145
Denis Ovsienkodc958242007-08-13 16:03:06 +00001146 /* This condition is never met, if we are using rt_socket.c */
paul718e3742002-12-13 20:15:29 +00001147 if (ret < 0)
1148 {
Christian Frankefa713d92013-07-05 15:35:37 +00001149 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +00001150 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1151 }
1152}
1153
1154/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001155static int
paul718e3742002-12-13 20:15:29 +00001156rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
1157{
1158 int ret = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001159 struct nexthop *nexthop, *tnexthop;
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001160 rib_table_info_t *info = rn->table->info;
Christian Frankefa713d92013-07-05 15:35:37 +00001161 int recursing;
paul718e3742002-12-13 20:15:29 +00001162
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001163 if (info->safi != SAFI_UNICAST)
1164 {
1165 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1166 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1167 return ret;
1168 }
1169
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001170 /*
1171 * Make sure we update the FPM any time we send new information to
1172 * the kernel.
1173 */
1174 zfpm_trigger_update (rn, "uninstalling from kernel");
1175
paul718e3742002-12-13 20:15:29 +00001176 switch (PREFIX_FAMILY (&rn->p))
1177 {
1178 case AF_INET:
1179 ret = kernel_delete_ipv4 (&rn->p, rib);
1180 break;
1181#ifdef HAVE_IPV6
1182 case AF_INET6:
1183 ret = kernel_delete_ipv6 (&rn->p, rib);
1184 break;
1185#endif /* HAVE_IPV6 */
1186 }
1187
Christian Frankefa713d92013-07-05 15:35:37 +00001188 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +00001189 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1190
1191 return ret;
1192}
1193
1194/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001195static void
paul718e3742002-12-13 20:15:29 +00001196rib_uninstall (struct route_node *rn, struct rib *rib)
1197{
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001198 rib_table_info_t *info = rn->table->info;
1199
paul718e3742002-12-13 20:15:29 +00001200 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1201 {
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001202 if (info->safi == SAFI_UNICAST)
1203 zfpm_trigger_update (rn, "rib_uninstall");
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001204
paul718e3742002-12-13 20:15:29 +00001205 redistribute_delete (&rn->p, rib);
1206 if (! RIB_SYSTEM_ROUTE (rib))
1207 rib_uninstall_kernel (rn, rib);
1208 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
1209 }
1210}
1211
Paul Jakma6d691122006-07-27 21:49:00 +00001212static void rib_unlink (struct route_node *, struct rib *);
1213
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001214/*
1215 * rib_can_delete_dest
1216 *
1217 * Returns TRUE if the given dest can be deleted from the table.
1218 */
1219static int
1220rib_can_delete_dest (rib_dest_t *dest)
1221{
1222 if (dest->routes)
1223 {
1224 return 0;
1225 }
1226
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001227 /*
1228 * Don't delete the dest if we have to update the FPM about this
1229 * prefix.
1230 */
1231 if (CHECK_FLAG (dest->flags, RIB_DEST_UPDATE_FPM) ||
1232 CHECK_FLAG (dest->flags, RIB_DEST_SENT_TO_FPM))
1233 return 0;
1234
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001235 return 1;
1236}
1237
1238/*
1239 * rib_gc_dest
1240 *
1241 * Garbage collect the rib dest corresponding to the given route node
1242 * if appropriate.
1243 *
1244 * Returns TRUE if the dest was deleted, FALSE otherwise.
1245 */
1246int
1247rib_gc_dest (struct route_node *rn)
1248{
1249 rib_dest_t *dest;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001250
1251 dest = rib_dest_from_rnode (rn);
1252 if (!dest)
1253 return 0;
1254
1255 if (!rib_can_delete_dest (dest))
1256 return 0;
1257
1258 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001259 rnode_debug (rn, "removing dest from table");
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001260
1261 dest->rnode = NULL;
1262 XFREE (MTYPE_RIB_DEST, dest);
1263 rn->info = NULL;
1264
1265 /*
1266 * Release the one reference that we keep on the route node.
1267 */
1268 route_unlock_node (rn);
1269 return 1;
1270}
1271
paul718e3742002-12-13 20:15:29 +00001272/* Core function for processing routing information base. */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001273static void
1274rib_process (struct route_node *rn)
paul718e3742002-12-13 20:15:29 +00001275{
1276 struct rib *rib;
1277 struct rib *next;
1278 struct rib *fib = NULL;
1279 struct rib *select = NULL;
Paul Jakma6d691122006-07-27 21:49:00 +00001280 struct rib *del = NULL;
pauld753e9e2003-01-22 19:45:50 +00001281 int installed = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001282 struct nexthop *nexthop = NULL, *tnexthop;
1283 int recursing;
Balaji95116332014-10-23 15:25:25 +00001284 rib_table_info_t *info;
1285
paul4d38fdb2005-04-28 17:35:14 +00001286 assert (rn);
Balaji95116332014-10-23 15:25:25 +00001287
1288 info = rn->table->info;
1289
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001290 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00001291 {
paul718e3742002-12-13 20:15:29 +00001292 /* Currently installed rib. */
1293 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Paul Jakma6d691122006-07-27 21:49:00 +00001294 {
1295 assert (fib == NULL);
1296 fib = rib;
1297 }
1298
1299 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1300 * which we need to do do further work with below.
1301 */
1302 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1303 {
1304 if (rib != fib)
1305 {
1306 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001307 rnode_debug (rn, "rn %p, removing rib %p",
1308 (void *)rn, (void *)rib);
1309 rib_unlink (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001310 }
1311 else
1312 del = rib;
1313
1314 continue;
1315 }
paul4d38fdb2005-04-28 17:35:14 +00001316
paul718e3742002-12-13 20:15:29 +00001317 /* Skip unreachable nexthop. */
1318 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +00001319 continue;
paul718e3742002-12-13 20:15:29 +00001320
1321 /* Infinit distance. */
1322 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +00001323 continue;
paul718e3742002-12-13 20:15:29 +00001324
paulaf887b52006-01-18 14:52:52 +00001325 /* Newly selected rib, the common case. */
1326 if (!select)
1327 {
1328 select = rib;
1329 continue;
1330 }
1331
1332 /* filter route selection in following order:
paulaf887b52006-01-18 14:52:52 +00001333 * - connected beats other types
paula8d9c1f2006-01-25 06:31:04 +00001334 * - lower distance beats higher
paulaf887b52006-01-18 14:52:52 +00001335 * - lower metric beats higher for equal distance
1336 * - last, hence oldest, route wins tie break.
1337 */
paula1038a12006-01-30 14:08:51 +00001338
1339 /* Connected routes. Pick the last connected
1340 * route of the set of lowest metric connected routes.
1341 */
paula8d9c1f2006-01-25 06:31:04 +00001342 if (rib->type == ZEBRA_ROUTE_CONNECT)
1343 {
paula1038a12006-01-30 14:08:51 +00001344 if (select->type != ZEBRA_ROUTE_CONNECT
paula8d9c1f2006-01-25 06:31:04 +00001345 || rib->metric <= select->metric)
paula1038a12006-01-30 14:08:51 +00001346 select = rib;
1347 continue;
paula8d9c1f2006-01-25 06:31:04 +00001348 }
1349 else if (select->type == ZEBRA_ROUTE_CONNECT)
1350 continue;
1351
1352 /* higher distance loses */
1353 if (rib->distance > select->distance)
1354 continue;
1355
1356 /* lower wins */
1357 if (rib->distance < select->distance)
1358 {
paulaf887b52006-01-18 14:52:52 +00001359 select = rib;
paula8d9c1f2006-01-25 06:31:04 +00001360 continue;
1361 }
1362
1363 /* metric tie-breaks equal distance */
1364 if (rib->metric <= select->metric)
1365 select = rib;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001366 } /* RNODE_FOREACH_RIB_SAFE */
Denis Ovsienkodc958242007-08-13 16:03:06 +00001367
1368 /* After the cycle is finished, the following pointers will be set:
1369 * select --- the winner RIB entry, if any was found, otherwise NULL
1370 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1371 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1372 * rib --- NULL
1373 */
1374
1375 /* Same RIB entry is selected. Update FIB and finish. */
paul718e3742002-12-13 20:15:29 +00001376 if (select && select == fib)
1377 {
Paul Jakma6d691122006-07-27 21:49:00 +00001378 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001379 rnode_debug (rn, "Updating existing route, select %p, fib %p",
David Lampartereed3c482015-03-03 08:51:53 +01001380 (void *)select, (void *)fib);
Timo Teräs7eb61362015-11-02 16:50:05 +02001381 if (CHECK_FLAG (select->status, RIB_ENTRY_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +00001382 {
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001383 if (info->safi == SAFI_UNICAST)
1384 zfpm_trigger_update (rn, "updating existing route");
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001385
paul4d38fdb2005-04-28 17:35:14 +00001386 redistribute_delete (&rn->p, select);
1387 if (! RIB_SYSTEM_ROUTE (select))
1388 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001389
paul4d38fdb2005-04-28 17:35:14 +00001390 /* Set real nexthop. */
1391 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +00001392
paul4d38fdb2005-04-28 17:35:14 +00001393 if (! RIB_SYSTEM_ROUTE (select))
1394 rib_install_kernel (rn, select);
1395 redistribute_add (&rn->p, select);
1396 }
pauld753e9e2003-01-22 19:45:50 +00001397 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001398 {
1399 /* Housekeeping code to deal with
1400 race conditions in kernel with linux
1401 netlink reporting interface up before IPv4 or IPv6 protocol
1402 is ready to add routes.
1403 This makes sure the routes are IN the kernel.
1404 */
pauld753e9e2003-01-22 19:45:50 +00001405
Christian Frankefa713d92013-07-05 15:35:37 +00001406 for (ALL_NEXTHOPS_RO(select->nexthop, nexthop, tnexthop, recursing))
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001407 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
paul4d38fdb2005-04-28 17:35:14 +00001408 {
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001409 installed = 1;
1410 break;
paul4d38fdb2005-04-28 17:35:14 +00001411 }
1412 if (! installed)
1413 rib_install_kernel (rn, select);
1414 }
Paul Jakma6d691122006-07-27 21:49:00 +00001415 goto end;
paul718e3742002-12-13 20:15:29 +00001416 }
1417
Denis Ovsienkodc958242007-08-13 16:03:06 +00001418 /* At this point we either haven't found the best RIB entry or it is
1419 * different from what we currently intend to flag with SELECTED. In both
1420 * cases, if a RIB block is present in FIB, it should be withdrawn.
1421 */
paul718e3742002-12-13 20:15:29 +00001422 if (fib)
1423 {
Paul Jakma6d691122006-07-27 21:49:00 +00001424 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001425 rnode_debug (rn, "Removing existing route, fib %p", (void *)fib);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001426
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001427 if (info->safi == SAFI_UNICAST)
1428 zfpm_trigger_update (rn, "removing existing route");
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001429
paul718e3742002-12-13 20:15:29 +00001430 redistribute_delete (&rn->p, fib);
1431 if (! RIB_SYSTEM_ROUTE (fib))
1432 rib_uninstall_kernel (rn, fib);
1433 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1434
1435 /* Set real nexthop. */
1436 nexthop_active_update (rn, fib, 1);
1437 }
1438
Denis Ovsienkodc958242007-08-13 16:03:06 +00001439 /* Regardless of some RIB entry being SELECTED or not before, now we can
1440 * tell, that if a new winner exists, FIB is still not updated with this
1441 * data, but ready to be.
1442 */
paul718e3742002-12-13 20:15:29 +00001443 if (select)
1444 {
Paul Jakma6d691122006-07-27 21:49:00 +00001445 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001446 rnode_debug (rn, "Adding route, select %p", (void *)select);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001447
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001448 if (info->safi == SAFI_UNICAST)
1449 zfpm_trigger_update (rn, "new route selected");
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001450
paul718e3742002-12-13 20:15:29 +00001451 /* Set real nexthop. */
1452 nexthop_active_update (rn, select, 1);
1453
1454 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001455 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001456 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1457 redistribute_add (&rn->p, select);
1458 }
paul4d38fdb2005-04-28 17:35:14 +00001459
Paul Jakma6d691122006-07-27 21:49:00 +00001460 /* FIB route was removed, should be deleted */
1461 if (del)
1462 {
1463 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001464 rnode_debug (rn, "Deleting fib %p, rn %p", (void *)del, (void *)rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001465 rib_unlink (rn, del);
1466 }
paul4d38fdb2005-04-28 17:35:14 +00001467
Paul Jakma6d691122006-07-27 21:49:00 +00001468end:
1469 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lampartereed3c482015-03-03 08:51:53 +01001470 rnode_debug (rn, "rn %p dequeued", (void *)rn);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001471
1472 /*
1473 * Check if the dest can be deleted now.
1474 */
1475 rib_gc_dest (rn);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001476}
1477
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001478/* Take a list of route_node structs and return 1, if there was a record
1479 * picked from it and processed by rib_process(). Don't process more,
1480 * than one RN record; operate only in the specified sub-queue.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001481 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001482static unsigned int
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001483process_subq (struct list * subq, u_char qindex)
1484{
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001485 struct listnode *lnode = listhead (subq);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001486 struct route_node *rnode;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001487
1488 if (!lnode)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001489 return 0;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001490
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001491 rnode = listgetdata (lnode);
1492 rib_process (rnode);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001493
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001494 if (rnode->info)
1495 UNSET_FLAG (rib_dest_from_rnode (rnode)->flags, RIB_ROUTE_QUEUED (qindex));
1496
Chris Caputo67b94672009-07-18 04:02:26 +00001497#if 0
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001498 else
1499 {
1500 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1501 __func__, rnode, rnode->lock);
1502 zlog_backtrace(LOG_DEBUG);
1503 }
Chris Caputo67b94672009-07-18 04:02:26 +00001504#endif
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001505 route_unlock_node (rnode);
1506 list_delete_node (subq, lnode);
1507 return 1;
1508}
1509
1510/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1511 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1512 * is pointed to the meta queue structure.
1513 */
1514static wq_item_status
1515meta_queue_process (struct work_queue *dummy, void *data)
1516{
1517 struct meta_queue * mq = data;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001518 unsigned i;
1519
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001520 for (i = 0; i < MQ_SIZE; i++)
1521 if (process_subq (mq->subq[i], i))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001522 {
1523 mq->size--;
1524 break;
1525 }
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001526 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1527}
1528
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001529/*
1530 * Map from rib types to queue type (priority) in meta queue
1531 */
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001532static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
1533 [ZEBRA_ROUTE_SYSTEM] = 4,
1534 [ZEBRA_ROUTE_KERNEL] = 0,
1535 [ZEBRA_ROUTE_CONNECT] = 0,
1536 [ZEBRA_ROUTE_STATIC] = 1,
1537 [ZEBRA_ROUTE_RIP] = 2,
1538 [ZEBRA_ROUTE_RIPNG] = 2,
1539 [ZEBRA_ROUTE_OSPF] = 2,
1540 [ZEBRA_ROUTE_OSPF6] = 2,
1541 [ZEBRA_ROUTE_ISIS] = 2,
1542 [ZEBRA_ROUTE_BGP] = 3,
1543 [ZEBRA_ROUTE_HSLS] = 4,
Paul Jakma57345092011-12-25 17:52:09 +01001544 [ZEBRA_ROUTE_BABEL] = 2,
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001545};
1546
1547/* Look into the RN and queue it into one or more priority queues,
1548 * increasing the size for each data push done.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001549 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001550static void
1551rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001552{
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001553 struct rib *rib;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001554
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001555 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001556 {
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001557 u_char qindex = meta_queue_map[rib->type];
1558
1559 /* Invariant: at this point we always have rn->info set. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001560 if (CHECK_FLAG (rib_dest_from_rnode (rn)->flags,
1561 RIB_ROUTE_QUEUED (qindex)))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001562 {
1563 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lamparter94813742014-04-24 20:22:53 +02001564 rnode_debug (rn, "rn %p is already queued in sub-queue %u",
David Lampartereed3c482015-03-03 08:51:53 +01001565 (void *)rn, qindex);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001566 continue;
1567 }
1568
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001569 SET_FLAG (rib_dest_from_rnode (rn)->flags, RIB_ROUTE_QUEUED (qindex));
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001570 listnode_add (mq->subq[qindex], rn);
1571 route_lock_node (rn);
1572 mq->size++;
1573
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001574 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lamparter94813742014-04-24 20:22:53 +02001575 rnode_debug (rn, "queued rn %p into sub-queue %u",
David Lampartereed3c482015-03-03 08:51:53 +01001576 (void *)rn, qindex);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001577 }
paul4d38fdb2005-04-28 17:35:14 +00001578}
1579
Paul Jakma6d691122006-07-27 21:49:00 +00001580/* Add route_node to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001581static void
Paul Jakma6d691122006-07-27 21:49:00 +00001582rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
paul4d38fdb2005-04-28 17:35:14 +00001583{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001584 assert (zebra && rn);
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001585
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001586 /* Pointless to queue a route_node with no RIB entries to add or remove */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001587 if (!rnode_to_ribs (rn))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001588 {
1589 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
David Lampartereed3c482015-03-03 08:51:53 +01001590 __func__, (void *)rn, rn->lock);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001591 zlog_backtrace(LOG_DEBUG);
1592 return;
1593 }
1594
1595 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lamparter94813742014-04-24 20:22:53 +02001596 rnode_info (rn, "work queue added");
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001597
1598 assert (zebra);
1599
1600 if (zebra->ribq == NULL)
1601 {
1602 zlog_err ("%s: work_queue does not exist!", __func__);
1603 return;
Paul Jakma6d691122006-07-27 21:49:00 +00001604 }
paul4d38fdb2005-04-28 17:35:14 +00001605
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001606 /*
1607 * The RIB queue should normally be either empty or holding the only
1608 * work_queue_item element. In the latter case this element would
1609 * hold a pointer to the meta queue structure, which must be used to
1610 * actually queue the route nodes to process. So create the MQ
1611 * holder, if necessary, then push the work into it in any case.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001612 * This semantics was introduced after 0.99.9 release.
1613 */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001614 if (!zebra->ribq->items->count)
1615 work_queue_add (zebra->ribq, zebra->mq);
1616
1617 rib_meta_queue_add (zebra->mq, rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001618
1619 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lampartereed3c482015-03-03 08:51:53 +01001620 rnode_debug (rn, "rn %p queued", (void *)rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001621
1622 return;
paul4d38fdb2005-04-28 17:35:14 +00001623}
1624
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001625/* Create new meta queue.
1626 A destructor function doesn't seem to be necessary here.
1627 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001628static struct meta_queue *
1629meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001630{
1631 struct meta_queue *new;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001632 unsigned i;
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001633
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001634 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1635 assert(new);
1636
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001637 for (i = 0; i < MQ_SIZE; i++)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001638 {
1639 new->subq[i] = list_new ();
1640 assert(new->subq[i]);
1641 }
1642
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001643 return new;
1644}
1645
paul4d38fdb2005-04-28 17:35:14 +00001646/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001647static void
paul4d38fdb2005-04-28 17:35:14 +00001648rib_queue_init (struct zebra_t *zebra)
1649{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001650 assert (zebra);
1651
paul4d38fdb2005-04-28 17:35:14 +00001652 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001653 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001654 {
Paul Jakma6d691122006-07-27 21:49:00 +00001655 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001656 return;
1657 }
1658
1659 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001660 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001661 zebra->ribq->spec.errorfunc = NULL;
paul4d38fdb2005-04-28 17:35:14 +00001662 /* XXX: TODO: These should be runtime configurable via vty */
1663 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001664 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001665
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001666 if (!(zebra->mq = meta_queue_new ()))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001667 {
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001668 zlog_err ("%s: could not initialise meta queue!", __func__);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001669 return;
1670 }
1671 return;
paul718e3742002-12-13 20:15:29 +00001672}
1673
Paul Jakma6d691122006-07-27 21:49:00 +00001674/* RIB updates are processed via a queue of pointers to route_nodes.
1675 *
1676 * The queue length is bounded by the maximal size of the routing table,
1677 * as a route_node will not be requeued, if already queued.
1678 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001679 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1680 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1681 * and then submit route_node to queue for best-path selection later.
1682 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001683 *
1684 * Deleted RIBs are reaped during best-path selection.
1685 *
1686 * rib_addnode
1687 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001688 * |-------->| | best RIB, if required
1689 * | |
1690 * static_install->|->rib_addqueue...... -> rib_process
1691 * | |
1692 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001693 * |-> set RIB_ENTRY_REMOVE |
1694 * rib_delnode (RIB freed)
1695 *
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001696 * The 'info' pointer of a route_node points to a rib_dest_t
1697 * ('dest'). Queueing state for a route_node is kept on the dest. The
1698 * dest is created on-demand by rib_link() and is kept around at least
1699 * as long as there are ribs hanging off it (@see rib_gc_dest()).
Paul Jakma6d691122006-07-27 21:49:00 +00001700 *
1701 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1702 *
1703 * - route_nodes: refcounted by:
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001704 * - dest attached to route_node:
1705 * - managed by: rib_link/rib_gc_dest
Paul Jakma6d691122006-07-27 21:49:00 +00001706 * - route_node processing queue
1707 * - managed by: rib_addqueue, rib_process.
1708 *
1709 */
1710
paul718e3742002-12-13 20:15:29 +00001711/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001712static void
Paul Jakma6d691122006-07-27 21:49:00 +00001713rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001714{
1715 struct rib *head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001716 rib_dest_t *dest;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001717
paul4d38fdb2005-04-28 17:35:14 +00001718 assert (rib && rn);
1719
Paul Jakma6d691122006-07-27 21:49:00 +00001720 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001721 rnode_debug (rn, "rn %p, rib %p", (void *)rn, (void *)rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001722
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001723 dest = rib_dest_from_rnode (rn);
1724 if (!dest)
Paul Jakma6d691122006-07-27 21:49:00 +00001725 {
1726 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001727 rnode_debug (rn, "adding dest to table");
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001728
1729 dest = XCALLOC (MTYPE_RIB_DEST, sizeof (rib_dest_t));
1730 route_lock_node (rn); /* rn route table reference */
1731 rn->info = dest;
1732 dest->rnode = rn;
1733 }
1734
1735 head = dest->routes;
1736 if (head)
1737 {
Paul Jakma6d691122006-07-27 21:49:00 +00001738 head->prev = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001739 }
paul718e3742002-12-13 20:15:29 +00001740 rib->next = head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001741 dest->routes = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001742 rib_queue_add (&zebrad, rn);
1743}
1744
1745static void
1746rib_addnode (struct route_node *rn, struct rib *rib)
1747{
1748 /* RIB node has been un-removed before route-node is processed.
1749 * route_node must hence already be on the queue for processing..
1750 */
1751 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1752 {
1753 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001754 rnode_debug (rn, "rn %p, un-removed rib %p", (void *)rn, (void *)rib);
David Lamparter94813742014-04-24 20:22:53 +02001755
Paul Jakma6d691122006-07-27 21:49:00 +00001756 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1757 return;
1758 }
1759 rib_link (rn, rib);
1760}
1761
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001762/*
1763 * rib_unlink
1764 *
1765 * Detach a rib structure from a route_node.
1766 *
1767 * Note that a call to rib_unlink() should be followed by a call to
1768 * rib_gc_dest() at some point. This allows a rib_dest_t that is no
1769 * longer required to be deleted.
1770 */
Paul Jakma6d691122006-07-27 21:49:00 +00001771static void
1772rib_unlink (struct route_node *rn, struct rib *rib)
1773{
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001774 rib_dest_t *dest;
Paul Jakma6d691122006-07-27 21:49:00 +00001775
1776 assert (rn && rib);
1777
1778 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001779 rnode_debug (rn, "rn %p, rib %p", (void *)rn, (void *)rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001780
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001781 dest = rib_dest_from_rnode (rn);
1782
Paul Jakma6d691122006-07-27 21:49:00 +00001783 if (rib->next)
1784 rib->next->prev = rib->prev;
1785
1786 if (rib->prev)
1787 rib->prev->next = rib->next;
1788 else
1789 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001790 dest->routes = rib->next;
Paul Jakma6d691122006-07-27 21:49:00 +00001791 }
1792
1793 /* free RIB and nexthops */
Christian Frankefa713d92013-07-05 15:35:37 +00001794 nexthops_free(rib->nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00001795 XFREE (MTYPE_RIB, rib);
1796
paul718e3742002-12-13 20:15:29 +00001797}
1798
paula1ac18c2005-06-28 17:17:12 +00001799static void
paul718e3742002-12-13 20:15:29 +00001800rib_delnode (struct route_node *rn, struct rib *rib)
1801{
Paul Jakma6d691122006-07-27 21:49:00 +00001802 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001803 rnode_debug (rn, "rn %p, rib %p, removing", (void *)rn, (void *)rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001804 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1805 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001806}
1807
1808int
1809rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001810 struct in_addr *gate, struct in_addr *src,
Feng Lu0d0686f2015-05-22 11:40:02 +02001811 unsigned int ifindex, vrf_id_t vrf_id, int table_id,
Timo Teräsb11f3b52015-11-02 16:50:07 +02001812 u_int32_t metric, u_int32_t mtu, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001813{
1814 struct rib *rib;
1815 struct rib *same = NULL;
1816 struct route_table *table;
1817 struct route_node *rn;
1818 struct nexthop *nexthop;
1819
1820 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02001821 table = zebra_vrf_table (AFI_IP, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00001822 if (! table)
1823 return 0;
1824
1825 /* Make it sure prefixlen is applied to the prefix. */
1826 apply_mask_ipv4 (p);
1827
1828 /* Set default distance by route type. */
1829 if (distance == 0)
1830 {
Balaji.G837d16c2012-09-26 14:09:10 +05301831 if ((unsigned)type >= array_size(route_info))
David Lamparter7052f222009-08-27 00:28:28 +02001832 distance = 150;
1833 else
1834 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00001835
1836 /* iBGP distance is 200. */
1837 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1838 distance = 200;
1839 }
1840
1841 /* Lookup route node.*/
1842 rn = route_node_get (table, (struct prefix *) p);
1843
1844 /* If same type of route are installed, treat it as a implicit
1845 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001846 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00001847 {
Paul Jakma6d691122006-07-27 21:49:00 +00001848 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1849 continue;
1850
hassoebf1ead2005-09-21 14:58:20 +00001851 if (rib->type != type)
1852 continue;
1853 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001854 {
1855 same = rib;
1856 break;
1857 }
hassoebf1ead2005-09-21 14:58:20 +00001858 /* Duplicate connected route comes in. */
1859 else if ((nexthop = rib->nexthop) &&
1860 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001861 nexthop->ifindex == ifindex &&
1862 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001863 {
1864 rib->refcnt++;
1865 return 0 ;
1866 }
paul718e3742002-12-13 20:15:29 +00001867 }
1868
1869 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001870 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001871 rib->type = type;
1872 rib->distance = distance;
1873 rib->flags = flags;
1874 rib->metric = metric;
Timo Teräsb11f3b52015-11-02 16:50:07 +02001875 rib->mtu = mtu;
Feng Lu0d0686f2015-05-22 11:40:02 +02001876 rib->vrf_id = vrf_id;
1877 rib->table = table_id;
paul718e3742002-12-13 20:15:29 +00001878 rib->nexthop_num = 0;
1879 rib->uptime = time (NULL);
1880
1881 /* Nexthop settings. */
1882 if (gate)
1883 {
1884 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001885 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001886 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001887 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001888 }
1889 else
1890 nexthop_ifindex_add (rib, ifindex);
1891
1892 /* If this route is kernel route, set FIB flag to the route. */
1893 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1894 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1895 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1896
1897 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001898 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001899 zlog_debug ("%s: calling rib_addnode (%p, %p)",
1900 __func__, (void *)rn, (void *)rib);
paul718e3742002-12-13 20:15:29 +00001901 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001902
paul718e3742002-12-13 20:15:29 +00001903 /* Free implicit route.*/
1904 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001905 {
1906 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001907 zlog_debug ("%s: calling rib_delnode (%p, %p)",
1908 __func__, (void *)rn, (void *)rib);
paul4d38fdb2005-04-28 17:35:14 +00001909 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001910 }
paul4d38fdb2005-04-28 17:35:14 +00001911
1912 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001913 return 0;
1914}
1915
Denis Ovsienkodc958242007-08-13 16:03:06 +00001916/* This function dumps the contents of a given RIB entry into
1917 * standard debug log. Calling function name and IP prefix in
1918 * question are passed as 1st and 2nd arguments.
1919 */
1920
David Lamparterf7bf4152013-10-22 17:10:21 +00001921void _rib_dump (const char * func,
1922 union prefix46constptr pp, const struct rib * rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001923{
David Lamparterf7bf4152013-10-22 17:10:21 +00001924 const struct prefix *p = pp.p;
Timo Teräsbe6335d2015-05-23 11:08:41 +03001925 char straddr[PREFIX_STRLEN];
Christian Frankefa713d92013-07-05 15:35:37 +00001926 struct nexthop *nexthop, *tnexthop;
1927 int recursing;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001928
Feng Lu0d0686f2015-05-22 11:40:02 +02001929 zlog_debug ("%s: dumping RIB entry %p for %s vrf %u", func, (void *)rib,
1930 prefix2str(p, straddr, sizeof(straddr)), rib->vrf_id);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001931 zlog_debug
1932 (
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001933 "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
Denis Ovsienkodc958242007-08-13 16:03:06 +00001934 func,
1935 rib->refcnt,
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001936 (unsigned long) rib->uptime,
Denis Ovsienkodc958242007-08-13 16:03:06 +00001937 rib->type,
1938 rib->table
1939 );
1940 zlog_debug
1941 (
1942 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1943 func,
1944 rib->metric,
1945 rib->distance,
1946 rib->flags,
1947 rib->status
1948 );
1949 zlog_debug
1950 (
1951 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1952 func,
1953 rib->nexthop_num,
1954 rib->nexthop_active_num,
1955 rib->nexthop_fib_num
1956 );
Vincent Bernatfed643f2012-10-23 16:00:42 +00001957
Christian Frankefa713d92013-07-05 15:35:37 +00001958 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1959 {
Vincent Bernatfed643f2012-10-23 16:00:42 +00001960 inet_ntop (p->family, &nexthop->gate, straddr, INET6_ADDRSTRLEN);
Christian Frankefa713d92013-07-05 15:35:37 +00001961 zlog_debug
1962 (
1963 "%s: %s %s with flags %s%s%s",
1964 func,
1965 (recursing ? " NH" : "NH"),
1966 straddr,
1967 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1968 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1969 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1970 );
1971 }
Denis Ovsienkodc958242007-08-13 16:03:06 +00001972 zlog_debug ("%s: dump complete", func);
1973}
1974
1975/* This is an exported helper to rtm_read() to dump the strange
1976 * RIB entry found by rib_lookup_ipv4_route()
1977 */
1978
1979void rib_lookup_and_dump (struct prefix_ipv4 * p)
1980{
1981 struct route_table *table;
1982 struct route_node *rn;
1983 struct rib *rib;
1984 char prefix_buf[INET_ADDRSTRLEN];
1985
1986 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02001987 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001988 if (! table)
1989 {
Feng Lu41f44a22015-05-22 11:39:56 +02001990 zlog_err ("%s: zebra_vrf_table() returned NULL", __func__);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001991 return;
1992 }
1993
Denis Ovsienkodc958242007-08-13 16:03:06 +00001994 /* Scan the RIB table for exactly matching RIB entry. */
1995 rn = route_node_lookup (table, (struct prefix *) p);
1996
1997 /* No route for this prefix. */
1998 if (! rn)
1999 {
Timo Teräsbe6335d2015-05-23 11:08:41 +03002000 zlog_debug ("%s: lookup failed for %s", __func__,
2001 prefix2str((struct prefix*) p, prefix_buf, sizeof(prefix_buf)));
Denis Ovsienkodc958242007-08-13 16:03:06 +00002002 return;
2003 }
2004
2005 /* Unlock node. */
2006 route_unlock_node (rn);
2007
2008 /* let's go */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002009 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00002010 {
2011 zlog_debug
2012 (
2013 "%s: rn %p, rib %p: %s, %s",
2014 __func__,
David Lampartereed3c482015-03-03 08:51:53 +01002015 (void *)rn,
2016 (void *)rib,
Denis Ovsienkodc958242007-08-13 16:03:06 +00002017 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
2018 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
2019 );
David Lamparterf7bf4152013-10-22 17:10:21 +00002020 rib_dump (p, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002021 }
2022}
2023
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002024/* Check if requested address assignment will fail due to another
2025 * route being installed by zebra in FIB already. Take necessary
2026 * actions, if needed: remove such a route from FIB and deSELECT
2027 * corresponding RIB entry. Then put affected RN into RIBQ head.
2028 */
2029void rib_lookup_and_pushup (struct prefix_ipv4 * p)
2030{
2031 struct route_table *table;
2032 struct route_node *rn;
2033 struct rib *rib;
2034 unsigned changed = 0;
2035
Feng Lu41f44a22015-05-22 11:39:56 +02002036 if (NULL == (table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT)))
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002037 {
Feng Lu41f44a22015-05-22 11:39:56 +02002038 zlog_err ("%s: zebra_vrf_table() returned NULL", __func__);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002039 return;
2040 }
2041
2042 /* No matches would be the simplest case. */
2043 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
2044 return;
2045
2046 /* Unlock node. */
2047 route_unlock_node (rn);
2048
2049 /* Check all RIB entries. In case any changes have to be done, requeue
2050 * the RN into RIBQ head. If the routing message about the new connected
2051 * route (generated by the IP address we are going to assign very soon)
2052 * comes before the RIBQ is processed, the new RIB entry will join
2053 * RIBQ record already on head. This is necessary for proper revalidation
2054 * of the rest of the RIB.
2055 */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002056 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002057 {
2058 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
2059 ! RIB_SYSTEM_ROUTE (rib))
2060 {
2061 changed = 1;
2062 if (IS_ZEBRA_DEBUG_RIB)
2063 {
Timo Teräsbe6335d2015-05-23 11:08:41 +03002064 char buf[PREFIX_STRLEN];
2065 zlog_debug ("%s: freeing way for connected prefix %s", __func__,
2066 prefix2str(&rn->p, buf, sizeof(buf)));
David Lamparterf7bf4152013-10-22 17:10:21 +00002067 rib_dump (&rn->p, rib);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002068 }
2069 rib_uninstall (rn, rib);
2070 }
2071 }
2072 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002073 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002074}
2075
paul718e3742002-12-13 20:15:29 +00002076int
G.Balajicddf3912011-11-26 21:59:32 +04002077rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002078{
2079 struct route_table *table;
2080 struct route_node *rn;
2081 struct rib *same;
2082 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00002083
paul718e3742002-12-13 20:15:29 +00002084 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02002085 table = zebra_vrf_table (AFI_IP, safi, rib->vrf_id);
paul718e3742002-12-13 20:15:29 +00002086 if (! table)
2087 return 0;
G.Balajicddf3912011-11-26 21:59:32 +04002088
paul718e3742002-12-13 20:15:29 +00002089 /* Make it sure prefixlen is applied to the prefix. */
2090 apply_mask_ipv4 (p);
2091
2092 /* Set default distance by route type. */
2093 if (rib->distance == 0)
2094 {
2095 rib->distance = route_info[rib->type].distance;
2096
2097 /* iBGP distance is 200. */
2098 if (rib->type == ZEBRA_ROUTE_BGP
2099 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
2100 rib->distance = 200;
2101 }
2102
2103 /* Lookup route node.*/
2104 rn = route_node_get (table, (struct prefix *) p);
2105
2106 /* If same type of route are installed, treat it as a implicit
2107 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002108 RNODE_FOREACH_RIB (rn, same)
paul718e3742002-12-13 20:15:29 +00002109 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00002110 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00002111 continue;
2112
paul718e3742002-12-13 20:15:29 +00002113 if (same->type == rib->type && same->table == rib->table
2114 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00002115 break;
paul718e3742002-12-13 20:15:29 +00002116 }
paul4d38fdb2005-04-28 17:35:14 +00002117
paul718e3742002-12-13 20:15:29 +00002118 /* If this route is kernel route, set FIB flag to the route. */
2119 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
2120 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2121 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2122
2123 /* Link new rib to node.*/
2124 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002125 if (IS_ZEBRA_DEBUG_RIB)
2126 {
2127 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01002128 __func__, (void *)rn, (void *)rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00002129 rib_dump (p, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002130 }
paul718e3742002-12-13 20:15:29 +00002131
paul718e3742002-12-13 20:15:29 +00002132 /* Free implicit route.*/
2133 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00002134 {
2135 if (IS_ZEBRA_DEBUG_RIB)
2136 {
2137 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01002138 __func__, (void *)rn, (void *)same);
David Lamparterf7bf4152013-10-22 17:10:21 +00002139 rib_dump (p, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002140 }
paul4d38fdb2005-04-28 17:35:14 +00002141 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002142 }
paul4d38fdb2005-04-28 17:35:14 +00002143
2144 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002145 return 0;
2146}
2147
hassoebf1ead2005-09-21 14:58:20 +00002148/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002149int
2150rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Feng Lu0d0686f2015-05-22 11:40:02 +02002151 struct in_addr *gate, unsigned int ifindex, vrf_id_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002152{
2153 struct route_table *table;
2154 struct route_node *rn;
2155 struct rib *rib;
2156 struct rib *fib = NULL;
2157 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002158 struct nexthop *nexthop, *tnexthop;
2159 int recursing;
Timo Teräsbe6335d2015-05-23 11:08:41 +03002160 char buf1[PREFIX_STRLEN];
Stephen Hemminger81cce012009-04-28 14:28:00 -07002161 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002162
2163 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02002164 table = zebra_vrf_table (AFI_IP, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002165 if (! table)
2166 return 0;
2167
2168 /* Apply mask. */
2169 apply_mask_ipv4 (p);
2170
Christian Frankeb52aef12013-11-27 17:06:15 +00002171 if (IS_ZEBRA_DEBUG_KERNEL)
2172 {
2173 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002174 zlog_debug ("rib_delete_ipv4(): route delete %s vrf %u via %s ifindex %d",
2175 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Christian Frankeb52aef12013-11-27 17:06:15 +00002176 inet_ntoa (*gate),
2177 ifindex);
2178 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002179 zlog_debug ("rib_delete_ipv4(): route delete %s vrf %u ifindex %d",
2180 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Christian Frankeb52aef12013-11-27 17:06:15 +00002181 ifindex);
2182 }
paul5ec90d22003-06-19 01:41:37 +00002183
paul718e3742002-12-13 20:15:29 +00002184 /* Lookup route node. */
2185 rn = route_node_lookup (table, (struct prefix *) p);
2186 if (! rn)
2187 {
2188 if (IS_ZEBRA_DEBUG_KERNEL)
2189 {
2190 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002191 zlog_debug ("route %s vrf %u via %s ifindex %d doesn't exist in rib",
2192 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002193 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002194 ifindex);
2195 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002196 zlog_debug ("route %s vrf %u ifindex %d doesn't exist in rib",
2197 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002198 ifindex);
2199 }
2200 return ZEBRA_ERR_RTNOEXIST;
2201 }
2202
2203 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002204 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002205 {
Paul Jakma6d691122006-07-27 21:49:00 +00002206 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2207 continue;
2208
paul718e3742002-12-13 20:15:29 +00002209 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2210 fib = rib;
2211
hassoebf1ead2005-09-21 14:58:20 +00002212 if (rib->type != type)
2213 continue;
2214 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002215 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002216 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002217 if (nexthop->ifindex != ifindex)
2218 continue;
hassoebf1ead2005-09-21 14:58:20 +00002219 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002220 {
hassoebf1ead2005-09-21 14:58:20 +00002221 rib->refcnt--;
2222 route_unlock_node (rn);
2223 route_unlock_node (rn);
2224 return 0;
paul718e3742002-12-13 20:15:29 +00002225 }
hassoebf1ead2005-09-21 14:58:20 +00002226 same = rib;
2227 break;
paul718e3742002-12-13 20:15:29 +00002228 }
hassoebf1ead2005-09-21 14:58:20 +00002229 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002230 else
paul5ec90d22003-06-19 01:41:37 +00002231 {
Christian Frankefa713d92013-07-05 15:35:37 +00002232 if (gate == NULL)
2233 {
2234 same = rib;
2235 break;
2236 }
2237 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2238 if (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate))
2239 {
2240 same = rib;
2241 break;
2242 }
2243 if (same)
2244 break;
2245 }
paul718e3742002-12-13 20:15:29 +00002246 }
paul718e3742002-12-13 20:15:29 +00002247 /* If same type of route can't be found and this message is from
2248 kernel. */
2249 if (! same)
2250 {
2251 if (fib && type == ZEBRA_ROUTE_KERNEL)
2252 {
2253 /* Unset flags. */
2254 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2255 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2256
2257 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2258 }
2259 else
2260 {
2261 if (IS_ZEBRA_DEBUG_KERNEL)
2262 {
2263 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002264 zlog_debug ("route %s vrf %u via %s ifindex %d type %d "
2265 "doesn't exist in rib",
2266 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002267 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002268 ifindex,
2269 type);
2270 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002271 zlog_debug ("route %s vrf %u ifindex %d type %d doesn't exist in rib",
2272 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002273 ifindex,
2274 type);
2275 }
2276 route_unlock_node (rn);
2277 return ZEBRA_ERR_RTNOEXIST;
2278 }
2279 }
paul4d38fdb2005-04-28 17:35:14 +00002280
paul718e3742002-12-13 20:15:29 +00002281 if (same)
2282 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002283
paul718e3742002-12-13 20:15:29 +00002284 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002285 return 0;
2286}
David Lamparter6b0655a2014-06-04 06:53:35 +02002287
paul718e3742002-12-13 20:15:29 +00002288/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002289static void
Everton Marques33d86db2014-07-14 11:19:00 -03002290static_install_ipv4 (safi_t safi, struct prefix *p, struct static_ipv4 *si)
paul718e3742002-12-13 20:15:29 +00002291{
2292 struct rib *rib;
2293 struct route_node *rn;
2294 struct route_table *table;
2295
2296 /* Lookup table. */
Feng Lu7aaf4ea2015-05-22 11:40:06 +02002297 table = zebra_vrf_table (AFI_IP, safi, si->vrf_id);
paul718e3742002-12-13 20:15:29 +00002298 if (! table)
2299 return;
2300
2301 /* Lookup existing route */
2302 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002303 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002304 {
2305 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2306 continue;
2307
2308 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2309 break;
2310 }
paul718e3742002-12-13 20:15:29 +00002311
2312 if (rib)
2313 {
2314 /* Same distance static route is there. Update it with new
2315 nexthop. */
paul718e3742002-12-13 20:15:29 +00002316 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002317 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002318 {
2319 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002320 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002321 break;
2322 case STATIC_IPV4_IFNAME:
2323 nexthop_ifname_add (rib, si->gate.ifname);
2324 break;
2325 case STATIC_IPV4_BLACKHOLE:
2326 nexthop_blackhole_add (rib);
2327 break;
paul4d38fdb2005-04-28 17:35:14 +00002328 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002329 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002330 }
2331 else
2332 {
2333 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002334 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2335
paul718e3742002-12-13 20:15:29 +00002336 rib->type = ZEBRA_ROUTE_STATIC;
2337 rib->distance = si->distance;
2338 rib->metric = 0;
Feng Lu7aaf4ea2015-05-22 11:40:06 +02002339 rib->vrf_id = si->vrf_id;
Nolan Leakeb0145dd2012-09-13 17:17:31 +00002340 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002341 rib->nexthop_num = 0;
2342
2343 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002344 {
2345 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002346 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002347 break;
2348 case STATIC_IPV4_IFNAME:
2349 nexthop_ifname_add (rib, si->gate.ifname);
2350 break;
2351 case STATIC_IPV4_BLACKHOLE:
2352 nexthop_blackhole_add (rib);
2353 break;
2354 }
paul718e3742002-12-13 20:15:29 +00002355
hasso81dfcaa2003-05-25 19:21:25 +00002356 /* Save the flags of this static routes (reject, blackhole) */
2357 rib->flags = si->flags;
2358
paul718e3742002-12-13 20:15:29 +00002359 /* Link this rib to the tree. */
2360 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002361 }
2362}
2363
paula1ac18c2005-06-28 17:17:12 +00002364static int
paul718e3742002-12-13 20:15:29 +00002365static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2366{
2367 if (nexthop->type == NEXTHOP_TYPE_IPV4
2368 && si->type == STATIC_IPV4_GATEWAY
2369 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2370 return 1;
2371 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2372 && si->type == STATIC_IPV4_IFNAME
2373 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2374 return 1;
paul595db7f2003-05-25 21:35:06 +00002375 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2376 && si->type == STATIC_IPV4_BLACKHOLE)
2377 return 1;
paule8e19462006-01-19 20:16:55 +00002378 return 0;
paul718e3742002-12-13 20:15:29 +00002379}
2380
2381/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002382static void
Everton Marques33d86db2014-07-14 11:19:00 -03002383static_uninstall_ipv4 (safi_t safi, struct prefix *p, struct static_ipv4 *si)
paul718e3742002-12-13 20:15:29 +00002384{
2385 struct route_node *rn;
2386 struct rib *rib;
2387 struct nexthop *nexthop;
2388 struct route_table *table;
2389
2390 /* Lookup table. */
Feng Lu7aaf4ea2015-05-22 11:40:06 +02002391 table = zebra_vrf_table (AFI_IP, safi, si->vrf_id);
paul718e3742002-12-13 20:15:29 +00002392 if (! table)
2393 return;
paul4d38fdb2005-04-28 17:35:14 +00002394
paul718e3742002-12-13 20:15:29 +00002395 /* Lookup existing route with type and distance. */
2396 rn = route_node_lookup (table, p);
2397 if (! rn)
2398 return;
2399
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002400 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002401 {
2402 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2403 continue;
2404
2405 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2406 break;
2407 }
paul718e3742002-12-13 20:15:29 +00002408
2409 if (! rib)
2410 {
2411 route_unlock_node (rn);
2412 return;
2413 }
2414
2415 /* Lookup nexthop. */
2416 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2417 if (static_ipv4_nexthop_same (nexthop, si))
2418 break;
2419
2420 /* Can't find nexthop. */
2421 if (! nexthop)
2422 {
2423 route_unlock_node (rn);
2424 return;
2425 }
2426
2427 /* Check nexthop. */
2428 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002429 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002430 else
2431 {
paul6baeb982003-10-28 03:47:15 +00002432 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2433 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002434 nexthop_delete (rib, nexthop);
2435 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002436 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002437 }
paul718e3742002-12-13 20:15:29 +00002438 /* Unlock node. */
2439 route_unlock_node (rn);
2440}
2441
paul718e3742002-12-13 20:15:29 +00002442int
Everton Marques33d86db2014-07-14 11:19:00 -03002443static_add_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate,
2444 const char *ifname, u_char flags, u_char distance,
Feng Lu0d0686f2015-05-22 11:40:02 +02002445 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002446{
2447 u_char type = 0;
2448 struct route_node *rn;
2449 struct static_ipv4 *si;
2450 struct static_ipv4 *pp;
2451 struct static_ipv4 *cp;
2452 struct static_ipv4 *update = NULL;
Feng Lu0d0686f2015-05-22 11:40:02 +02002453 struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
2454 struct route_table *stable = zvrf->stable[AFI_IP][safi];
paul718e3742002-12-13 20:15:29 +00002455
paul718e3742002-12-13 20:15:29 +00002456 if (! stable)
2457 return -1;
2458
2459 /* Lookup static route prefix. */
2460 rn = route_node_get (stable, p);
2461
2462 /* Make flags. */
2463 if (gate)
2464 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002465 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002466 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002467 else
2468 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002469
2470 /* Do nothing if there is a same static route. */
2471 for (si = rn->info; si; si = si->next)
2472 {
2473 if (type == si->type
2474 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2475 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2476 {
2477 if (distance == si->distance)
2478 {
2479 route_unlock_node (rn);
2480 return 0;
2481 }
2482 else
2483 update = si;
2484 }
2485 }
2486
Paul Jakma3c0755d2006-12-08 00:53:14 +00002487 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002488 if (update)
Everton Marques33d86db2014-07-14 11:19:00 -03002489 static_delete_ipv4_safi (safi, p, gate, ifname, update->distance, vrf_id);
paul718e3742002-12-13 20:15:29 +00002490
2491 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002492 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
paul718e3742002-12-13 20:15:29 +00002493
2494 si->type = type;
2495 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002496 si->flags = flags;
Feng Lu7aaf4ea2015-05-22 11:40:06 +02002497 si->vrf_id = vrf_id;
paul718e3742002-12-13 20:15:29 +00002498
2499 if (gate)
2500 si->gate.ipv4 = *gate;
2501 if (ifname)
2502 si->gate.ifname = XSTRDUP (0, ifname);
2503
2504 /* Add new static route information to the tree with sort by
2505 distance value and gateway address. */
2506 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2507 {
2508 if (si->distance < cp->distance)
2509 break;
2510 if (si->distance > cp->distance)
2511 continue;
2512 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2513 {
2514 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2515 break;
2516 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2517 continue;
2518 }
2519 }
2520
2521 /* Make linked list. */
2522 if (pp)
2523 pp->next = si;
2524 else
2525 rn->info = si;
2526 if (cp)
2527 cp->prev = si;
2528 si->prev = pp;
2529 si->next = cp;
2530
2531 /* Install into rib. */
Everton Marques33d86db2014-07-14 11:19:00 -03002532 static_install_ipv4 (safi, p, si);
paul718e3742002-12-13 20:15:29 +00002533
2534 return 1;
2535}
2536
paul718e3742002-12-13 20:15:29 +00002537int
Everton Marques33d86db2014-07-14 11:19:00 -03002538static_delete_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate,
Feng Lu0d0686f2015-05-22 11:40:02 +02002539 const char *ifname, u_char distance, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002540{
2541 u_char type = 0;
2542 struct route_node *rn;
2543 struct static_ipv4 *si;
2544 struct route_table *stable;
2545
2546 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02002547 stable = zebra_vrf_static_table (AFI_IP, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002548 if (! stable)
2549 return -1;
2550
2551 /* Lookup static route prefix. */
2552 rn = route_node_lookup (stable, p);
2553 if (! rn)
2554 return 0;
2555
2556 /* Make flags. */
2557 if (gate)
2558 type = STATIC_IPV4_GATEWAY;
2559 else if (ifname)
2560 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002561 else
2562 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002563
2564 /* Find same static route is the tree */
2565 for (si = rn->info; si; si = si->next)
2566 if (type == si->type
2567 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2568 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2569 break;
2570
2571 /* Can't find static route. */
2572 if (! si)
2573 {
2574 route_unlock_node (rn);
2575 return 0;
2576 }
2577
2578 /* Install into rib. */
Everton Marques33d86db2014-07-14 11:19:00 -03002579 static_uninstall_ipv4 (safi, p, si);
paul718e3742002-12-13 20:15:29 +00002580
2581 /* Unlink static route from linked list. */
2582 if (si->prev)
2583 si->prev->next = si->next;
2584 else
2585 rn->info = si->next;
2586 if (si->next)
2587 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002588 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002589
2590 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002591 if (ifname)
2592 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002593 XFREE (MTYPE_STATIC_IPV4, si);
2594
paul143a3852003-09-29 20:06:13 +00002595 route_unlock_node (rn);
2596
paul718e3742002-12-13 20:15:29 +00002597 return 1;
2598}
2599
paul718e3742002-12-13 20:15:29 +00002600#ifdef HAVE_IPV6
paul718e3742002-12-13 20:15:29 +00002601int
2602rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
Feng Lu0d0686f2015-05-22 11:40:02 +02002603 struct in6_addr *gate, unsigned int ifindex,
2604 vrf_id_t vrf_id, int table_id,
Timo Teräsb11f3b52015-11-02 16:50:07 +02002605 u_int32_t metric, u_int32_t mtu, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002606{
2607 struct rib *rib;
2608 struct rib *same = NULL;
2609 struct route_table *table;
2610 struct route_node *rn;
2611 struct nexthop *nexthop;
2612
paul718e3742002-12-13 20:15:29 +00002613 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02002614 table = zebra_vrf_table (AFI_IP6, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002615 if (! table)
2616 return 0;
2617
2618 /* Make sure mask is applied. */
2619 apply_mask_ipv6 (p);
2620
2621 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002622 if (!distance)
2623 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002624
2625 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2626 distance = 200;
2627
paul718e3742002-12-13 20:15:29 +00002628 /* Lookup route node.*/
2629 rn = route_node_get (table, (struct prefix *) p);
2630
2631 /* If same type of route are installed, treat it as a implicit
2632 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002633 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002634 {
Paul Jakma6d691122006-07-27 21:49:00 +00002635 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2636 continue;
2637
hassoebf1ead2005-09-21 14:58:20 +00002638 if (rib->type != type)
2639 continue;
2640 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002641 {
2642 same = rib;
paul718e3742002-12-13 20:15:29 +00002643 break;
2644 }
hassoebf1ead2005-09-21 14:58:20 +00002645 else if ((nexthop = rib->nexthop) &&
2646 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2647 nexthop->ifindex == ifindex)
2648 {
2649 rib->refcnt++;
2650 return 0;
2651 }
paul718e3742002-12-13 20:15:29 +00002652 }
2653
2654 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002655 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2656
paul718e3742002-12-13 20:15:29 +00002657 rib->type = type;
2658 rib->distance = distance;
2659 rib->flags = flags;
2660 rib->metric = metric;
Timo Teräsb11f3b52015-11-02 16:50:07 +02002661 rib->mtu = mtu;
Feng Lu0d0686f2015-05-22 11:40:02 +02002662 rib->vrf_id = vrf_id;
2663 rib->table = table_id;
paul718e3742002-12-13 20:15:29 +00002664 rib->nexthop_num = 0;
2665 rib->uptime = time (NULL);
2666
2667 /* Nexthop settings. */
2668 if (gate)
2669 {
2670 if (ifindex)
2671 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2672 else
2673 nexthop_ipv6_add (rib, gate);
2674 }
2675 else
2676 nexthop_ifindex_add (rib, ifindex);
2677
2678 /* If this route is kernel route, set FIB flag to the route. */
2679 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2680 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2681 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2682
2683 /* Link new rib to node.*/
2684 rib_addnode (rn, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002685 if (IS_ZEBRA_DEBUG_RIB)
2686 {
2687 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01002688 __func__, (void *)rn, (void *)rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00002689 rib_dump (p, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002690 }
paul718e3742002-12-13 20:15:29 +00002691
paul718e3742002-12-13 20:15:29 +00002692 /* Free implicit route.*/
2693 if (same)
Vincent Bernatfed643f2012-10-23 16:00:42 +00002694 {
2695 if (IS_ZEBRA_DEBUG_RIB)
2696 {
2697 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01002698 __func__, (void *)rn, (void *)same);
David Lamparterf7bf4152013-10-22 17:10:21 +00002699 rib_dump (p, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002700 }
paul4d38fdb2005-04-28 17:35:14 +00002701 rib_delnode (rn, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002702 }
paul4d38fdb2005-04-28 17:35:14 +00002703
2704 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002705 return 0;
2706}
2707
hassoebf1ead2005-09-21 14:58:20 +00002708/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002709int
2710rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
Feng Lu0d0686f2015-05-22 11:40:02 +02002711 struct in6_addr *gate, unsigned int ifindex, vrf_id_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002712{
2713 struct route_table *table;
2714 struct route_node *rn;
2715 struct rib *rib;
2716 struct rib *fib = NULL;
2717 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002718 struct nexthop *nexthop, *tnexthop;
2719 int recursing;
Timo Teräsbe6335d2015-05-23 11:08:41 +03002720 char buf1[PREFIX_STRLEN];
Stephen Hemminger81cce012009-04-28 14:28:00 -07002721 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002722
2723 /* Apply mask. */
2724 apply_mask_ipv6 (p);
2725
2726 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02002727 table = zebra_vrf_table (AFI_IP6, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002728 if (! table)
2729 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002730
paul718e3742002-12-13 20:15:29 +00002731 /* Lookup route node. */
2732 rn = route_node_lookup (table, (struct prefix *) p);
2733 if (! rn)
2734 {
2735 if (IS_ZEBRA_DEBUG_KERNEL)
2736 {
2737 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002738 zlog_debug ("route %s vrf %u via %s ifindex %d doesn't exist in rib",
2739 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002740 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002741 ifindex);
2742 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002743 zlog_debug ("route %s vrf %u ifindex %d doesn't exist in rib",
2744 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002745 ifindex);
2746 }
2747 return ZEBRA_ERR_RTNOEXIST;
2748 }
2749
2750 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002751 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002752 {
Paul Jakma6d691122006-07-27 21:49:00 +00002753 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2754 continue;
2755
paul718e3742002-12-13 20:15:29 +00002756 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2757 fib = rib;
2758
hassoebf1ead2005-09-21 14:58:20 +00002759 if (rib->type != type)
2760 continue;
2761 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002762 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002763 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002764 if (nexthop->ifindex != ifindex)
2765 continue;
hassoebf1ead2005-09-21 14:58:20 +00002766 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002767 {
hassoebf1ead2005-09-21 14:58:20 +00002768 rib->refcnt--;
2769 route_unlock_node (rn);
2770 route_unlock_node (rn);
2771 return 0;
paul718e3742002-12-13 20:15:29 +00002772 }
hassoebf1ead2005-09-21 14:58:20 +00002773 same = rib;
2774 break;
paul718e3742002-12-13 20:15:29 +00002775 }
hassoebf1ead2005-09-21 14:58:20 +00002776 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002777 else
2778 {
2779 if (gate == NULL)
2780 {
2781 same = rib;
2782 break;
2783 }
2784 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2785 if (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate))
2786 {
2787 same = rib;
2788 break;
2789 }
2790 if (same)
2791 break;
2792 }
paul718e3742002-12-13 20:15:29 +00002793 }
2794
2795 /* If same type of route can't be found and this message is from
2796 kernel. */
2797 if (! same)
2798 {
2799 if (fib && type == ZEBRA_ROUTE_KERNEL)
2800 {
2801 /* Unset flags. */
2802 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2803 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2804
2805 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2806 }
2807 else
2808 {
2809 if (IS_ZEBRA_DEBUG_KERNEL)
2810 {
2811 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002812 zlog_debug ("route %s vrf %u via %s ifindex %d type %d "
2813 "doesn't exist in rib",
2814 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002815 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002816 ifindex,
2817 type);
2818 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002819 zlog_debug ("route %s vrf %u ifindex %d type %d doesn't exist in rib",
2820 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002821 ifindex,
2822 type);
2823 }
2824 route_unlock_node (rn);
2825 return ZEBRA_ERR_RTNOEXIST;
2826 }
2827 }
2828
2829 if (same)
2830 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002831
paul718e3742002-12-13 20:15:29 +00002832 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002833 return 0;
2834}
David Lamparter6b0655a2014-06-04 06:53:35 +02002835
paul718e3742002-12-13 20:15:29 +00002836/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002837static void
paul718e3742002-12-13 20:15:29 +00002838static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2839{
2840 struct rib *rib;
2841 struct route_table *table;
2842 struct route_node *rn;
2843
2844 /* Lookup table. */
Feng Lu7aaf4ea2015-05-22 11:40:06 +02002845 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, si->vrf_id);
paul718e3742002-12-13 20:15:29 +00002846 if (! table)
2847 return;
2848
2849 /* Lookup existing route */
2850 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002851 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002852 {
2853 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2854 continue;
2855
2856 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2857 break;
2858 }
paul718e3742002-12-13 20:15:29 +00002859
2860 if (rib)
2861 {
2862 /* Same distance static route is there. Update it with new
2863 nexthop. */
paul718e3742002-12-13 20:15:29 +00002864 route_unlock_node (rn);
2865
2866 switch (si->type)
2867 {
2868 case STATIC_IPV6_GATEWAY:
2869 nexthop_ipv6_add (rib, &si->ipv6);
2870 break;
2871 case STATIC_IPV6_IFNAME:
2872 nexthop_ifname_add (rib, si->ifname);
2873 break;
2874 case STATIC_IPV6_GATEWAY_IFNAME:
2875 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2876 break;
2877 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002878 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002879 }
2880 else
2881 {
2882 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002883 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2884
paul718e3742002-12-13 20:15:29 +00002885 rib->type = ZEBRA_ROUTE_STATIC;
2886 rib->distance = si->distance;
2887 rib->metric = 0;
Feng Lu7aaf4ea2015-05-22 11:40:06 +02002888 rib->vrf_id = si->vrf_id;
Dinesh G Duttd1b09912014-09-30 12:54:13 -07002889 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002890 rib->nexthop_num = 0;
2891
2892 switch (si->type)
2893 {
2894 case STATIC_IPV6_GATEWAY:
2895 nexthop_ipv6_add (rib, &si->ipv6);
2896 break;
2897 case STATIC_IPV6_IFNAME:
2898 nexthop_ifname_add (rib, si->ifname);
2899 break;
2900 case STATIC_IPV6_GATEWAY_IFNAME:
2901 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2902 break;
2903 }
2904
hasso81dfcaa2003-05-25 19:21:25 +00002905 /* Save the flags of this static routes (reject, blackhole) */
2906 rib->flags = si->flags;
2907
paul718e3742002-12-13 20:15:29 +00002908 /* Link this rib to the tree. */
2909 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002910 }
2911}
2912
paula1ac18c2005-06-28 17:17:12 +00002913static int
paul718e3742002-12-13 20:15:29 +00002914static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2915{
2916 if (nexthop->type == NEXTHOP_TYPE_IPV6
2917 && si->type == STATIC_IPV6_GATEWAY
2918 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2919 return 1;
2920 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2921 && si->type == STATIC_IPV6_IFNAME
2922 && strcmp (nexthop->ifname, si->ifname) == 0)
2923 return 1;
2924 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2925 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2926 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2927 && strcmp (nexthop->ifname, si->ifname) == 0)
2928 return 1;
paule8e19462006-01-19 20:16:55 +00002929 return 0;
paul718e3742002-12-13 20:15:29 +00002930}
2931
paula1ac18c2005-06-28 17:17:12 +00002932static void
paul718e3742002-12-13 20:15:29 +00002933static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2934{
2935 struct route_table *table;
2936 struct route_node *rn;
2937 struct rib *rib;
2938 struct nexthop *nexthop;
2939
2940 /* Lookup table. */
Feng Lu7aaf4ea2015-05-22 11:40:06 +02002941 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, si->vrf_id);
paul718e3742002-12-13 20:15:29 +00002942 if (! table)
2943 return;
2944
2945 /* Lookup existing route with type and distance. */
2946 rn = route_node_lookup (table, (struct prefix *) p);
2947 if (! rn)
2948 return;
2949
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002950 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002951 {
2952 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2953 continue;
2954
2955 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2956 break;
2957 }
2958
paul718e3742002-12-13 20:15:29 +00002959 if (! rib)
2960 {
2961 route_unlock_node (rn);
2962 return;
2963 }
2964
2965 /* Lookup nexthop. */
2966 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2967 if (static_ipv6_nexthop_same (nexthop, si))
2968 break;
2969
2970 /* Can't find nexthop. */
2971 if (! nexthop)
2972 {
2973 route_unlock_node (rn);
2974 return;
2975 }
2976
2977 /* Check nexthop. */
2978 if (rib->nexthop_num == 1)
2979 {
2980 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002981 }
2982 else
2983 {
paul6baeb982003-10-28 03:47:15 +00002984 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2985 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002986 nexthop_delete (rib, nexthop);
2987 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002988 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002989 }
paul718e3742002-12-13 20:15:29 +00002990 /* Unlock node. */
2991 route_unlock_node (rn);
2992}
2993
2994/* Add static route into static route configuration. */
2995int
2996static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002997 const char *ifname, u_char flags, u_char distance,
Feng Lu0d0686f2015-05-22 11:40:02 +02002998 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002999{
3000 struct route_node *rn;
3001 struct static_ipv6 *si;
3002 struct static_ipv6 *pp;
3003 struct static_ipv6 *cp;
Feng Lu0d0686f2015-05-22 11:40:02 +02003004 struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
3005 struct route_table *stable = zvrf->stable[AFI_IP6][SAFI_UNICAST];
paul718e3742002-12-13 20:15:29 +00003006
paul718e3742002-12-13 20:15:29 +00003007 if (! stable)
3008 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00003009
3010 if (!gate &&
3011 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
3012 return -1;
3013
3014 if (!ifname &&
3015 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
3016 return -1;
paul718e3742002-12-13 20:15:29 +00003017
3018 /* Lookup static route prefix. */
3019 rn = route_node_get (stable, p);
3020
3021 /* Do nothing if there is a same static route. */
3022 for (si = rn->info; si; si = si->next)
3023 {
3024 if (distance == si->distance
3025 && type == si->type
3026 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
3027 && (! ifname || strcmp (ifname, si->ifname) == 0))
3028 {
3029 route_unlock_node (rn);
3030 return 0;
3031 }
3032 }
3033
3034 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07003035 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
paul718e3742002-12-13 20:15:29 +00003036
3037 si->type = type;
3038 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00003039 si->flags = flags;
Feng Lu7aaf4ea2015-05-22 11:40:06 +02003040 si->vrf_id = vrf_id;
paul718e3742002-12-13 20:15:29 +00003041
3042 switch (type)
3043 {
3044 case STATIC_IPV6_GATEWAY:
3045 si->ipv6 = *gate;
3046 break;
3047 case STATIC_IPV6_IFNAME:
3048 si->ifname = XSTRDUP (0, ifname);
3049 break;
3050 case STATIC_IPV6_GATEWAY_IFNAME:
3051 si->ipv6 = *gate;
3052 si->ifname = XSTRDUP (0, ifname);
3053 break;
3054 }
3055
3056 /* Add new static route information to the tree with sort by
3057 distance value and gateway address. */
3058 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
3059 {
3060 if (si->distance < cp->distance)
3061 break;
3062 if (si->distance > cp->distance)
3063 continue;
3064 }
3065
3066 /* Make linked list. */
3067 if (pp)
3068 pp->next = si;
3069 else
3070 rn->info = si;
3071 if (cp)
3072 cp->prev = si;
3073 si->prev = pp;
3074 si->next = cp;
3075
3076 /* Install into rib. */
3077 static_install_ipv6 (p, si);
3078
3079 return 1;
3080}
3081
3082/* Delete static route from static route configuration. */
3083int
3084static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
Feng Lu0d0686f2015-05-22 11:40:02 +02003085 const char *ifname, u_char distance, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00003086{
3087 struct route_node *rn;
3088 struct static_ipv6 *si;
3089 struct route_table *stable;
3090
3091 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02003092 stable = zebra_vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +00003093 if (! stable)
3094 return -1;
3095
3096 /* Lookup static route prefix. */
3097 rn = route_node_lookup (stable, p);
3098 if (! rn)
3099 return 0;
3100
3101 /* Find same static route is the tree */
3102 for (si = rn->info; si; si = si->next)
3103 if (distance == si->distance
3104 && type == si->type
3105 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
3106 && (! ifname || strcmp (ifname, si->ifname) == 0))
3107 break;
3108
3109 /* Can't find static route. */
3110 if (! si)
3111 {
3112 route_unlock_node (rn);
3113 return 0;
3114 }
3115
3116 /* Install into rib. */
3117 static_uninstall_ipv6 (p, si);
3118
3119 /* Unlink static route from linked list. */
3120 if (si->prev)
3121 si->prev->next = si->next;
3122 else
3123 rn->info = si->next;
3124 if (si->next)
3125 si->next->prev = si->prev;
3126
3127 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00003128 if (ifname)
3129 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00003130 XFREE (MTYPE_STATIC_IPV6, si);
3131
3132 return 1;
3133}
3134#endif /* HAVE_IPV6 */
David Lamparter6b0655a2014-06-04 06:53:35 +02003135
paul718e3742002-12-13 20:15:29 +00003136/* RIB update function. */
3137void
Feng Lu0d0686f2015-05-22 11:40:02 +02003138rib_update (vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00003139{
3140 struct route_node *rn;
3141 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00003142
Feng Lu0d0686f2015-05-22 11:40:02 +02003143 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +00003144 if (table)
3145 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003146 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003147 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003148
Feng Lu0d0686f2015-05-22 11:40:02 +02003149 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +00003150 if (table)
3151 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003152 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003153 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003154}
3155
David Lamparter6b0655a2014-06-04 06:53:35 +02003156
paul718e3742002-12-13 20:15:29 +00003157/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00003158static void
paul718e3742002-12-13 20:15:29 +00003159rib_weed_table (struct route_table *table)
3160{
3161 struct route_node *rn;
3162 struct rib *rib;
3163 struct rib *next;
3164
3165 if (table)
3166 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003167 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003168 {
Paul Jakma6d691122006-07-27 21:49:00 +00003169 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3170 continue;
3171
paulb21b19c2003-06-15 01:28:29 +00003172 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00003173 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00003174 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003175 }
3176}
3177
3178/* Delete all routes from non main table. */
3179void
paula1ac18c2005-06-28 17:17:12 +00003180rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00003181{
Feng Lu0d0686f2015-05-22 11:40:02 +02003182 vrf_iter_t iter;
3183 struct zebra_vrf *zvrf;
3184
3185 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3186 if ((zvrf = vrf_iter2info (iter)) != NULL)
3187 {
3188 rib_weed_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
3189 rib_weed_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
3190 }
paul718e3742002-12-13 20:15:29 +00003191}
David Lamparter6b0655a2014-06-04 06:53:35 +02003192
Feng Lu0d0686f2015-05-22 11:40:02 +02003193#if 0
paul718e3742002-12-13 20:15:29 +00003194/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00003195static void
paul718e3742002-12-13 20:15:29 +00003196rib_sweep_table (struct route_table *table)
3197{
3198 struct route_node *rn;
3199 struct rib *rib;
3200 struct rib *next;
3201 int ret = 0;
3202
3203 if (table)
3204 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003205 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003206 {
Paul Jakma6d691122006-07-27 21:49:00 +00003207 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3208 continue;
3209
paul718e3742002-12-13 20:15:29 +00003210 if (rib->type == ZEBRA_ROUTE_KERNEL &&
3211 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
3212 {
3213 ret = rib_uninstall_kernel (rn, rib);
3214 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00003215 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003216 }
3217 }
3218}
Feng Lu0d0686f2015-05-22 11:40:02 +02003219#endif
paul718e3742002-12-13 20:15:29 +00003220
3221/* Sweep all RIB tables. */
3222void
paula1ac18c2005-06-28 17:17:12 +00003223rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00003224{
Feng Lu0d0686f2015-05-22 11:40:02 +02003225 vrf_iter_t iter;
3226 struct zebra_vrf *zvrf;
3227
3228 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3229 if ((zvrf = vrf_iter2info (iter)) != NULL)
3230 {
3231 rib_weed_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
3232 rib_weed_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
3233 }
paul718e3742002-12-13 20:15:29 +00003234}
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003235
3236/* Remove specific by protocol routes from 'table'. */
3237static unsigned long
3238rib_score_proto_table (u_char proto, struct route_table *table)
3239{
3240 struct route_node *rn;
3241 struct rib *rib;
3242 struct rib *next;
3243 unsigned long n = 0;
3244
3245 if (table)
3246 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003247 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003248 {
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003249 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3250 continue;
3251 if (rib->type == proto)
3252 {
3253 rib_delnode (rn, rib);
3254 n++;
3255 }
3256 }
3257
3258 return n;
3259}
3260
3261/* Remove specific by protocol routes. */
3262unsigned long
3263rib_score_proto (u_char proto)
3264{
Feng Lu0d0686f2015-05-22 11:40:02 +02003265 vrf_iter_t iter;
3266 struct zebra_vrf *zvrf;
3267 unsigned long cnt = 0;
3268
3269 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3270 if ((zvrf = vrf_iter2info (iter)) != NULL)
3271 cnt += rib_score_proto_table (proto, zvrf->table[AFI_IP][SAFI_UNICAST])
3272 +rib_score_proto_table (proto, zvrf->table[AFI_IP6][SAFI_UNICAST]);
3273
3274 return cnt;
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003275}
3276
paul718e3742002-12-13 20:15:29 +00003277/* Close RIB and clean up kernel routes. */
Feng Lu267ceb22015-05-22 11:40:09 +02003278void
paul718e3742002-12-13 20:15:29 +00003279rib_close_table (struct route_table *table)
3280{
3281 struct route_node *rn;
David Lamparter7ce9e6a2015-01-12 07:05:06 +01003282 rib_table_info_t *info = table->info;
paul718e3742002-12-13 20:15:29 +00003283 struct rib *rib;
3284
3285 if (table)
3286 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003287 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00003288 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003289 if (!CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
3290 continue;
3291
David Lamparter7ce9e6a2015-01-12 07:05:06 +01003292 if (info->safi == SAFI_UNICAST)
3293 zfpm_trigger_update (rn, NULL);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00003294
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003295 if (! RIB_SYSTEM_ROUTE (rib))
3296 rib_uninstall_kernel (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00003297 }
paul718e3742002-12-13 20:15:29 +00003298}
3299
3300/* Close all RIB tables. */
3301void
paula1ac18c2005-06-28 17:17:12 +00003302rib_close (void)
paul718e3742002-12-13 20:15:29 +00003303{
Feng Lu0d0686f2015-05-22 11:40:02 +02003304 vrf_iter_t iter;
3305 struct zebra_vrf *zvrf;
3306
3307 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3308 if ((zvrf = vrf_iter2info (iter)) != NULL)
3309 {
3310 rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
3311 rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
3312 }
paul718e3742002-12-13 20:15:29 +00003313}
David Lamparter6b0655a2014-06-04 06:53:35 +02003314
paul718e3742002-12-13 20:15:29 +00003315/* Routing information base initialize. */
3316void
paula1ac18c2005-06-28 17:17:12 +00003317rib_init (void)
paul718e3742002-12-13 20:15:29 +00003318{
paul4d38fdb2005-04-28 17:35:14 +00003319 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00003320}
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003321
3322/*
3323 * vrf_id_get_next
3324 *
3325 * Get the first vrf id that is greater than the given vrf id if any.
3326 *
3327 * Returns TRUE if a vrf id was found, FALSE otherwise.
3328 */
3329static inline int
Feng Lu41f44a22015-05-22 11:39:56 +02003330vrf_id_get_next (vrf_id_t vrf_id, vrf_id_t *next_id_p)
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003331{
Feng Lu41f44a22015-05-22 11:39:56 +02003332 vrf_iter_t iter = vrf_iterator (vrf_id);
3333 struct zebra_vrf *zvrf = vrf_iter2info (iter);
3334
3335 /* The same one ? Then find out the next. */
3336 if (zvrf && (zvrf->vrf_id == vrf_id))
3337 zvrf = vrf_iter2info (vrf_next (iter));
3338
3339 if (zvrf)
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003340 {
Feng Lu41f44a22015-05-22 11:39:56 +02003341 *next_id_p = zvrf->vrf_id;
3342 return 1;
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003343 }
3344
3345 return 0;
3346}
3347
3348/*
3349 * rib_tables_iter_next
3350 *
3351 * Returns the next table in the iteration.
3352 */
3353struct route_table *
3354rib_tables_iter_next (rib_tables_iter_t *iter)
3355{
3356 struct route_table *table;
3357
3358 /*
3359 * Array that helps us go over all AFI/SAFI combinations via one
3360 * index.
3361 */
3362 static struct {
3363 afi_t afi;
3364 safi_t safi;
3365 } afi_safis[] = {
3366 { AFI_IP, SAFI_UNICAST },
3367 { AFI_IP, SAFI_MULTICAST },
3368 { AFI_IP6, SAFI_UNICAST },
3369 { AFI_IP6, SAFI_MULTICAST },
3370 };
3371
3372 table = NULL;
3373
3374 switch (iter->state)
3375 {
3376
3377 case RIB_TABLES_ITER_S_INIT:
3378 iter->vrf_id = 0;
3379 iter->afi_safi_ix = -1;
3380
3381 /* Fall through */
3382
3383 case RIB_TABLES_ITER_S_ITERATING:
3384 iter->afi_safi_ix++;
3385 while (1)
3386 {
3387
3388 while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
3389 {
Feng Lu41f44a22015-05-22 11:39:56 +02003390 table = zebra_vrf_table (afi_safis[iter->afi_safi_ix].afi,
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003391 afi_safis[iter->afi_safi_ix].safi,
3392 iter->vrf_id);
3393 if (table)
3394 break;
3395
3396 iter->afi_safi_ix++;
3397 }
3398
3399 /*
3400 * Found another table in this vrf.
3401 */
3402 if (table)
3403 break;
3404
3405 /*
3406 * Done with all tables in the current vrf, go to the next
3407 * one.
3408 */
3409 if (!vrf_id_get_next (iter->vrf_id, &iter->vrf_id))
3410 break;
3411
3412 iter->afi_safi_ix = 0;
3413 }
3414
3415 break;
3416
3417 case RIB_TABLES_ITER_S_DONE:
3418 return NULL;
3419 }
3420
3421 if (table)
3422 iter->state = RIB_TABLES_ITER_S_ITERATING;
3423 else
3424 iter->state = RIB_TABLES_ITER_S_DONE;
3425
3426 return table;
3427}
Feng Lu41f44a22015-05-22 11:39:56 +02003428
3429/*
3430 * Create a routing table for the specific AFI/SAFI in the given VRF.
3431 */
3432static void
3433zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi)
3434{
3435 rib_table_info_t *info;
3436 struct route_table *table;
3437
3438 assert (!zvrf->table[afi][safi]);
3439
3440 table = route_table_init ();
3441 zvrf->table[afi][safi] = table;
3442
3443 info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
3444 info->zvrf = zvrf;
3445 info->afi = afi;
3446 info->safi = safi;
3447 table->info = info;
3448}
3449
3450/* Allocate new zebra VRF. */
3451struct zebra_vrf *
3452zebra_vrf_alloc (vrf_id_t vrf_id)
3453{
3454 struct zebra_vrf *zvrf;
Feng Lu758fb8f2014-07-03 18:23:09 +08003455#ifdef HAVE_NETLINK
3456 char nl_name[64];
3457#endif
Feng Lu41f44a22015-05-22 11:39:56 +02003458
3459 zvrf = XCALLOC (MTYPE_ZEBRA_VRF, sizeof (struct zebra_vrf));
3460
3461 /* Allocate routing table and static table. */
3462 zebra_vrf_table_create (zvrf, AFI_IP, SAFI_UNICAST);
3463 zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_UNICAST);
3464 zvrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
3465 zvrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
3466 zebra_vrf_table_create (zvrf, AFI_IP, SAFI_MULTICAST);
3467 zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_MULTICAST);
3468 zvrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
3469 zvrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
3470
3471 /* Set VRF ID */
3472 zvrf->vrf_id = vrf_id;
3473
Feng Lu758fb8f2014-07-03 18:23:09 +08003474#ifdef HAVE_NETLINK
3475 /* Initialize netlink sockets */
3476 snprintf (nl_name, 64, "netlink-listen (vrf %u)", vrf_id);
3477 zvrf->netlink.sock = -1;
3478 zvrf->netlink.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name);
3479
3480 snprintf (nl_name, 64, "netlink-cmd (vrf %u)", vrf_id);
3481 zvrf->netlink_cmd.sock = -1;
3482 zvrf->netlink_cmd.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name);
3483#endif
3484
Feng Lu41f44a22015-05-22 11:39:56 +02003485 return zvrf;
3486}
3487
3488/* Lookup the routing table in an enabled VRF. */
3489struct route_table *
3490zebra_vrf_table (afi_t afi, safi_t safi, vrf_id_t vrf_id)
3491{
3492 struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);
3493
3494 if (!zvrf)
3495 return NULL;
3496
3497 if (afi >= AFI_MAX || safi >= SAFI_MAX)
3498 return NULL;
3499
3500 return zvrf->table[afi][safi];
3501}
3502
3503/* Lookup the static routing table in a VRF. */
3504struct route_table *
3505zebra_vrf_static_table (afi_t afi, safi_t safi, vrf_id_t vrf_id)
3506{
3507 struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);
3508
3509 if (!zvrf)
3510 return NULL;
3511
3512 if (afi >= AFI_MAX || safi >= SAFI_MAX)
3513 return NULL;
3514
3515 return zvrf->stable[afi][safi];
3516}
3517