blob: 8bd4ecc88b286b211287ea9bc0e269ebadb7afc0 [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;
364 }
paul718e3742002-12-13 20:15:29 +0000365
366 /* Make lookup prefix. */
367 memset (&p, 0, sizeof (struct prefix_ipv4));
368 p.family = AF_INET;
369 p.prefixlen = IPV4_MAX_PREFIXLEN;
370 p.prefix = nexthop->gate.ipv4;
371
372 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200373 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, rib->vrf_id);
paul718e3742002-12-13 20:15:29 +0000374 if (! table)
375 return 0;
376
377 rn = route_node_match (table, (struct prefix *) &p);
378 while (rn)
379 {
380 route_unlock_node (rn);
381
David Warda50c1072009-12-03 15:34:39 +0300382 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000383 if (rn == top)
384 return 0;
385
386 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000387 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100388 {
389 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
390 continue;
391 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
392 break;
393 }
paul718e3742002-12-13 20:15:29 +0000394
395 /* If there is no selected route or matched route is EGP, go up
396 tree. */
397 if (! match
398 || match->type == ZEBRA_ROUTE_BGP)
399 {
400 do {
401 rn = rn->parent;
402 } while (rn && rn->info == NULL);
403 if (rn)
404 route_lock_node (rn);
405 }
406 else
407 {
Christian Franke48a53dc2013-07-05 15:35:38 +0000408 /* If the longest prefix match for the nexthop yields
409 * a blackhole, mark it as inactive. */
410 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE)
411 || CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT))
412 return 0;
413
paul718e3742002-12-13 20:15:29 +0000414 if (match->type == ZEBRA_ROUTE_CONNECT)
415 {
416 /* Directly point connected route. */
417 newhop = match->nexthop;
418 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
419 nexthop->ifindex = newhop->ifindex;
420
421 return 1;
422 }
423 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
424 {
Christian Frankefa713d92013-07-05 15:35:37 +0000425 resolved = 0;
paul718e3742002-12-13 20:15:29 +0000426 for (newhop = match->nexthop; newhop; newhop = newhop->next)
427 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
428 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
429 {
430 if (set)
431 {
432 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
Christian Frankefa713d92013-07-05 15:35:37 +0000433
434 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
435 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
Christian Frankec3e6b592013-07-05 15:35:40 +0000436 /* If the resolving route specifies a gateway, use it */
437 if (newhop->type == NEXTHOP_TYPE_IPV4
438 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX
439 || newhop->type == NEXTHOP_TYPE_IPV4_IFNAME)
440 {
441 resolved_hop->type = newhop->type;
442 resolved_hop->gate.ipv4 = newhop->gate.ipv4;
Christian Frankefa713d92013-07-05 15:35:37 +0000443
Christian Frankec3e6b592013-07-05 15:35:40 +0000444 if (newhop->ifindex)
445 {
446 resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
447 resolved_hop->ifindex = newhop->ifindex;
448 }
449 }
Christian Frankefa713d92013-07-05 15:35:37 +0000450
Christian Frankec3e6b592013-07-05 15:35:40 +0000451 /* If the resolving route is an interface route,
452 * it means the gateway we are looking up is connected
453 * to that interface. (The actual network is _not_ onlink).
454 * Therefore, the resolved route should have the original
455 * gateway as nexthop as it is directly connected.
456 *
457 * On Linux, we have to set the onlink netlink flag because
458 * otherwise, the kernel won't accept the route. */
paul718e3742002-12-13 20:15:29 +0000459 if (newhop->type == NEXTHOP_TYPE_IFINDEX
Christian Frankec3e6b592013-07-05 15:35:40 +0000460 || newhop->type == NEXTHOP_TYPE_IFNAME)
461 {
462 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
463 resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
464 resolved_hop->gate.ipv4 = nexthop->gate.ipv4;
465 resolved_hop->ifindex = newhop->ifindex;
466 }
Christian Frankefa713d92013-07-05 15:35:37 +0000467
468 _nexthop_add(&nexthop->resolved, resolved_hop);
paul718e3742002-12-13 20:15:29 +0000469 }
Christian Frankefa713d92013-07-05 15:35:37 +0000470 resolved = 1;
paul718e3742002-12-13 20:15:29 +0000471 }
Christian Frankefa713d92013-07-05 15:35:37 +0000472 return resolved;
paul718e3742002-12-13 20:15:29 +0000473 }
474 else
475 {
476 return 0;
477 }
478 }
479 }
480 return 0;
481}
482
483#ifdef HAVE_IPV6
484/* If force flag is not set, do not modify falgs at all for uninstall
485 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000486static int
paul718e3742002-12-13 20:15:29 +0000487nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
488 struct route_node *top)
489{
490 struct prefix_ipv6 p;
491 struct route_table *table;
492 struct route_node *rn;
493 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000494 int resolved;
paul718e3742002-12-13 20:15:29 +0000495 struct nexthop *newhop;
Christian Frankefa713d92013-07-05 15:35:37 +0000496 struct nexthop *resolved_hop;
paul718e3742002-12-13 20:15:29 +0000497
498 if (nexthop->type == NEXTHOP_TYPE_IPV6)
499 nexthop->ifindex = 0;
500
501 if (set)
Christian Frankefa713d92013-07-05 15:35:37 +0000502 {
503 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
504 nexthops_free(nexthop->resolved);
505 nexthop->resolved = NULL;
506 }
paul718e3742002-12-13 20:15:29 +0000507
508 /* Make lookup prefix. */
509 memset (&p, 0, sizeof (struct prefix_ipv6));
510 p.family = AF_INET6;
511 p.prefixlen = IPV6_MAX_PREFIXLEN;
512 p.prefix = nexthop->gate.ipv6;
513
514 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200515 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, rib->vrf_id);
paul718e3742002-12-13 20:15:29 +0000516 if (! table)
517 return 0;
518
519 rn = route_node_match (table, (struct prefix *) &p);
520 while (rn)
521 {
522 route_unlock_node (rn);
523
David Warda50c1072009-12-03 15:34:39 +0300524 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000525 if (rn == top)
526 return 0;
527
528 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000529 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100530 {
531 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
532 continue;
533 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
534 break;
535 }
paul718e3742002-12-13 20:15:29 +0000536
537 /* If there is no selected route or matched route is EGP, go up
538 tree. */
539 if (! match
540 || match->type == ZEBRA_ROUTE_BGP)
541 {
542 do {
543 rn = rn->parent;
544 } while (rn && rn->info == NULL);
545 if (rn)
546 route_lock_node (rn);
547 }
548 else
549 {
Christian Franke48a53dc2013-07-05 15:35:38 +0000550 /* If the longest prefix match for the nexthop yields
551 * a blackhole, mark it as inactive. */
552 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE)
553 || CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT))
554 return 0;
555
paul718e3742002-12-13 20:15:29 +0000556 if (match->type == ZEBRA_ROUTE_CONNECT)
557 {
558 /* Directly point connected route. */
559 newhop = match->nexthop;
560
561 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
562 nexthop->ifindex = newhop->ifindex;
563
564 return 1;
565 }
566 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
567 {
Christian Frankefa713d92013-07-05 15:35:37 +0000568 resolved = 0;
paul718e3742002-12-13 20:15:29 +0000569 for (newhop = match->nexthop; newhop; newhop = newhop->next)
570 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
571 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
572 {
573 if (set)
574 {
575 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
Christian Frankefa713d92013-07-05 15:35:37 +0000576
577 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
578 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
Christian Frankec3e6b592013-07-05 15:35:40 +0000579 /* See nexthop_active_ipv4 for a description how the
580 * resolved nexthop is constructed. */
paul718e3742002-12-13 20:15:29 +0000581 if (newhop->type == NEXTHOP_TYPE_IPV6
582 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
583 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
Christian Frankec3e6b592013-07-05 15:35:40 +0000584 {
585 resolved_hop->type = newhop->type;
586 resolved_hop->gate.ipv6 = newhop->gate.ipv6;
587
588 if (newhop->ifindex)
589 {
590 resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
591 resolved_hop->ifindex = newhop->ifindex;
592 }
593 }
Christian Frankefa713d92013-07-05 15:35:37 +0000594
paul718e3742002-12-13 20:15:29 +0000595 if (newhop->type == NEXTHOP_TYPE_IFINDEX
Christian Frankec3e6b592013-07-05 15:35:40 +0000596 || newhop->type == NEXTHOP_TYPE_IFNAME)
597 {
598 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
599 resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
600 resolved_hop->gate.ipv6 = nexthop->gate.ipv6;
601 resolved_hop->ifindex = newhop->ifindex;
602 }
Christian Frankefa713d92013-07-05 15:35:37 +0000603
604 _nexthop_add(&nexthop->resolved, resolved_hop);
paul718e3742002-12-13 20:15:29 +0000605 }
Christian Frankefa713d92013-07-05 15:35:37 +0000606 resolved = 1;
paul718e3742002-12-13 20:15:29 +0000607 }
Christian Frankefa713d92013-07-05 15:35:37 +0000608 return resolved;
paul718e3742002-12-13 20:15:29 +0000609 }
610 else
611 {
612 return 0;
613 }
614 }
615 }
616 return 0;
617}
618#endif /* HAVE_IPV6 */
619
620struct rib *
David Lamparter24480d42015-01-22 19:09:36 +0100621rib_match_ipv4_safi (struct in_addr addr, safi_t safi, int skip_bgp,
Feng Lu0d0686f2015-05-22 11:40:02 +0200622 struct route_node **rn_out, vrf_id_t vrf_id)
Everton Marques3dea1782014-09-22 19:35:51 -0300623{
624 struct route_table *table;
625 struct route_node *rn;
626 struct rib *match;
627 struct nexthop *newhop, *tnewhop;
628 int recursing;
629
630 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200631 table = zebra_vrf_table (AFI_IP, safi, vrf_id);
Everton Marques3dea1782014-09-22 19:35:51 -0300632 if (! table)
633 return 0;
634
635 rn = route_node_match_ipv4 (table, &addr);
636
637 while (rn)
638 {
639 route_unlock_node (rn);
640
641 /* Pick up selected route. */
642 RNODE_FOREACH_RIB (rn, match)
643 {
644 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
645 continue;
646 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
647 break;
648 }
649
650 /* If there is no selected route or matched route is EGP, go up
651 tree. */
Everton Marques83d71122014-09-19 16:39:34 -0300652 if (!match || (skip_bgp && (match->type == ZEBRA_ROUTE_BGP)))
Everton Marques3dea1782014-09-22 19:35:51 -0300653 {
654 do {
655 rn = rn->parent;
656 } while (rn && rn->info == NULL);
657 if (rn)
658 route_lock_node (rn);
659 }
660 else
661 {
David Lamparter24480d42015-01-22 19:09:36 +0100662 if (match->type != ZEBRA_ROUTE_CONNECT)
Everton Marques3dea1782014-09-22 19:35:51 -0300663 {
David Lamparter24480d42015-01-22 19:09:36 +0100664 int found = 0;
Everton Marques3dea1782014-09-22 19:35:51 -0300665 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
666 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
David Lamparter24480d42015-01-22 19:09:36 +0100667 {
668 found = 1;
669 break;
670 }
671 if (!found)
672 return NULL;
Everton Marques3dea1782014-09-22 19:35:51 -0300673 }
David Lamparter24480d42015-01-22 19:09:36 +0100674
675 if (rn_out)
676 *rn_out = rn;
677 return match;
Everton Marques3dea1782014-09-22 19:35:51 -0300678 }
679 }
680 return NULL;
681}
682
683struct rib *
Feng Lu0d0686f2015-05-22 11:40:02 +0200684rib_match_ipv4_multicast (struct in_addr addr, struct route_node **rn_out,
685 vrf_id_t vrf_id)
David Lamparterbd078122015-01-06 19:53:24 +0100686{
687 struct rib *rib = NULL, *mrib = NULL, *urib = NULL;
688 struct route_node *m_rn = NULL, *u_rn = NULL;
689 int skip_bgp = 0; /* bool */
690
691 switch (ipv4_multicast_mode)
692 {
693 case MCAST_MRIB_ONLY:
Feng Lu0d0686f2015-05-22 11:40:02 +0200694 return rib_match_ipv4_safi (addr, SAFI_MULTICAST, skip_bgp, rn_out,
695 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100696 case MCAST_URIB_ONLY:
Feng Lu0d0686f2015-05-22 11:40:02 +0200697 return rib_match_ipv4_safi (addr, SAFI_UNICAST, skip_bgp, rn_out,
698 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100699 case MCAST_NO_CONFIG:
700 case MCAST_MIX_MRIB_FIRST:
Feng Lu0d0686f2015-05-22 11:40:02 +0200701 rib = mrib = rib_match_ipv4_safi (addr, SAFI_MULTICAST, skip_bgp, &m_rn,
702 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100703 if (!mrib)
Feng Lu0d0686f2015-05-22 11:40:02 +0200704 rib = urib = rib_match_ipv4_safi (addr, SAFI_UNICAST, skip_bgp, &u_rn,
705 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100706 break;
707 case MCAST_MIX_DISTANCE:
Feng Lu0d0686f2015-05-22 11:40:02 +0200708 mrib = rib_match_ipv4_safi (addr, SAFI_MULTICAST, skip_bgp, &m_rn,
709 vrf_id);
710 urib = rib_match_ipv4_safi (addr, SAFI_UNICAST, skip_bgp, &u_rn,
711 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100712 if (mrib && urib)
713 rib = urib->distance < mrib->distance ? urib : mrib;
714 else if (mrib)
715 rib = mrib;
716 else if (urib)
717 rib = urib;
718 break;
719 case MCAST_MIX_PFXLEN:
Feng Lu0d0686f2015-05-22 11:40:02 +0200720 mrib = rib_match_ipv4_safi (addr, SAFI_MULTICAST, skip_bgp, &m_rn,
721 vrf_id);
722 urib = rib_match_ipv4_safi (addr, SAFI_UNICAST, skip_bgp, &u_rn,
723 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100724 if (mrib && urib)
725 rib = u_rn->p.prefixlen > m_rn->p.prefixlen ? urib : mrib;
726 else if (mrib)
727 rib = mrib;
728 else if (urib)
729 rib = urib;
730 break;
731 }
732
733 if (rn_out)
734 *rn_out = (rib == mrib) ? m_rn : u_rn;
735
736 if (IS_ZEBRA_DEBUG_RIB)
737 {
738 char buf[BUFSIZ];
739 inet_ntop (AF_INET, &addr, buf, BUFSIZ);
740
Feng Lu0d0686f2015-05-22 11:40:02 +0200741 zlog_debug("%s: %s vrf %u: found %s, using %s",
742 __func__, buf, vrf_id,
David Lamparterbd078122015-01-06 19:53:24 +0100743 mrib ? (urib ? "MRIB+URIB" : "MRIB") :
744 urib ? "URIB" : "nothing",
745 rib == urib ? "URIB" : rib == mrib ? "MRIB" : "none");
746 }
747 return rib;
748}
749
750void
751multicast_mode_ipv4_set (enum multicast_mode mode)
752{
753 if (IS_ZEBRA_DEBUG_RIB)
754 zlog_debug("%s: multicast lookup mode set (%d)", __func__, mode);
755 ipv4_multicast_mode = mode;
756}
757
758enum multicast_mode
759multicast_mode_ipv4_get (void)
760{
761 return ipv4_multicast_mode;
762}
763
764struct rib *
Feng Lu0d0686f2015-05-22 11:40:02 +0200765rib_lookup_ipv4 (struct prefix_ipv4 *p, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000766{
767 struct route_table *table;
768 struct route_node *rn;
769 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000770 struct nexthop *nexthop, *tnexthop;
771 int recursing;
paul718e3742002-12-13 20:15:29 +0000772
773 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200774 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +0000775 if (! table)
776 return 0;
777
778 rn = route_node_lookup (table, (struct prefix *) p);
779
780 /* No route for this prefix. */
781 if (! rn)
782 return NULL;
783
784 /* Unlock node. */
785 route_unlock_node (rn);
786
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000787 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100788 {
789 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
790 continue;
791 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
792 break;
793 }
paul718e3742002-12-13 20:15:29 +0000794
795 if (! match || match->type == ZEBRA_ROUTE_BGP)
796 return NULL;
797
798 if (match->type == ZEBRA_ROUTE_CONNECT)
799 return match;
800
Christian Frankefa713d92013-07-05 15:35:37 +0000801 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +0000802 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
803 return match;
804
805 return NULL;
806}
807
Denis Ovsienkodc958242007-08-13 16:03:06 +0000808/*
809 * This clone function, unlike its original rib_lookup_ipv4(), checks
810 * if specified IPv4 route record (prefix/mask -> gate) exists in
811 * the whole RIB and has ZEBRA_FLAG_SELECTED set.
812 *
813 * Return values:
814 * -1: error
815 * 0: exact match found
816 * 1: a match was found with a different gate
817 * 2: connected route found
818 * 3: no matches found
819 */
820int
Feng Lu0d0686f2015-05-22 11:40:02 +0200821rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate,
822 vrf_id_t vrf_id)
Denis Ovsienkodc958242007-08-13 16:03:06 +0000823{
824 struct route_table *table;
825 struct route_node *rn;
826 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000827 struct nexthop *nexthop, *tnexthop;
828 int recursing;
829 int nexthops_active;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000830
831 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200832 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
Denis Ovsienkodc958242007-08-13 16:03:06 +0000833 if (! table)
834 return ZEBRA_RIB_LOOKUP_ERROR;
835
836 /* Scan the RIB table for exactly matching RIB entry. */
837 rn = route_node_lookup (table, (struct prefix *) p);
838
839 /* No route for this prefix. */
840 if (! rn)
841 return ZEBRA_RIB_NOTFOUND;
842
843 /* Unlock node. */
844 route_unlock_node (rn);
845
846 /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000847 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100848 {
849 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
850 continue;
851 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
852 break;
853 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000854
855 /* None such found :( */
856 if (!match)
857 return ZEBRA_RIB_NOTFOUND;
858
859 if (match->type == ZEBRA_ROUTE_CONNECT)
860 return ZEBRA_RIB_FOUND_CONNECTED;
861
862 /* Ok, we have a cood candidate, let's check it's nexthop list... */
Christian Frankefa713d92013-07-05 15:35:37 +0000863 nexthops_active = 0;
864 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000865 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000866 {
Christian Frankefa713d92013-07-05 15:35:37 +0000867 nexthops_active = 1;
868 if (nexthop->gate.ipv4.s_addr == sockunion2ip (qgate))
869 return ZEBRA_RIB_FOUND_EXACT;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000870 if (IS_ZEBRA_DEBUG_RIB)
Christian Frankefa713d92013-07-05 15:35:37 +0000871 {
872 char gate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
873 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
874 inet_ntop (AF_INET, &sockunion2ip(qgate), qgate_buf, INET_ADDRSTRLEN);
875 zlog_debug ("%s: qgate == %s, %s == %s", __func__,
876 qgate_buf, recursing ? "rgate" : "gate", gate_buf);
877 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000878 }
Christian Frankefa713d92013-07-05 15:35:37 +0000879
880 if (nexthops_active)
881 return ZEBRA_RIB_FOUND_NOGATE;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000882
883 return ZEBRA_RIB_NOTFOUND;
884}
885
paul718e3742002-12-13 20:15:29 +0000886#ifdef HAVE_IPV6
887struct rib *
Feng Lu0d0686f2015-05-22 11:40:02 +0200888rib_match_ipv6 (struct in6_addr *addr, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000889{
890 struct prefix_ipv6 p;
891 struct route_table *table;
892 struct route_node *rn;
893 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000894 struct nexthop *newhop, *tnewhop;
895 int recursing;
paul718e3742002-12-13 20:15:29 +0000896
897 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200898 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +0000899 if (! table)
900 return 0;
901
902 memset (&p, 0, sizeof (struct prefix_ipv6));
903 p.family = AF_INET6;
904 p.prefixlen = IPV6_MAX_PREFIXLEN;
905 IPV6_ADDR_COPY (&p.prefix, addr);
906
907 rn = route_node_match (table, (struct prefix *) &p);
908
909 while (rn)
910 {
911 route_unlock_node (rn);
912
913 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000914 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100915 {
916 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
917 continue;
918 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
919 break;
920 }
paul718e3742002-12-13 20:15:29 +0000921
922 /* If there is no selected route or matched route is EGP, go up
923 tree. */
924 if (! match
925 || match->type == ZEBRA_ROUTE_BGP)
926 {
927 do {
928 rn = rn->parent;
929 } while (rn && rn->info == NULL);
930 if (rn)
931 route_lock_node (rn);
932 }
933 else
934 {
935 if (match->type == ZEBRA_ROUTE_CONNECT)
936 /* Directly point connected route. */
937 return match;
938 else
939 {
Christian Frankefa713d92013-07-05 15:35:37 +0000940 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
paul718e3742002-12-13 20:15:29 +0000941 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
942 return match;
943 return NULL;
944 }
945 }
946 }
947 return NULL;
948}
949#endif /* HAVE_IPV6 */
950
Paul Jakma7514fb72007-05-02 16:05:35 +0000951#define RIB_SYSTEM_ROUTE(R) \
952 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
953
Denis Ovsienkodc958242007-08-13 16:03:06 +0000954/* This function verifies reachability of one given nexthop, which can be
955 * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
956 * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
957 * nexthop->ifindex will be updated appropriately as well.
958 * An existing route map can turn (otherwise active) nexthop into inactive, but
959 * not vice versa.
960 *
961 * The return value is the final value of 'ACTIVE' flag.
962 */
963
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300964static unsigned
paul718e3742002-12-13 20:15:29 +0000965nexthop_active_check (struct route_node *rn, struct rib *rib,
966 struct nexthop *nexthop, int set)
967{
Christian Frankef3a17322013-07-05 15:35:41 +0000968 rib_table_info_t *info = rn->table->info;
paul718e3742002-12-13 20:15:29 +0000969 struct interface *ifp;
Paul Jakma7514fb72007-05-02 16:05:35 +0000970 route_map_result_t ret = RMAP_MATCH;
971 extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
972 struct route_map *rmap;
973 int family;
paul718e3742002-12-13 20:15:29 +0000974
Paul Jakma7514fb72007-05-02 16:05:35 +0000975 family = 0;
paul718e3742002-12-13 20:15:29 +0000976 switch (nexthop->type)
977 {
978 case NEXTHOP_TYPE_IFINDEX:
Feng Lu0d0686f2015-05-22 11:40:02 +0200979 ifp = if_lookup_by_index_vrf (nexthop->ifindex, rib->vrf_id);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000980 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000981 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
982 else
983 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
984 break;
paul718e3742002-12-13 20:15:29 +0000985 case NEXTHOP_TYPE_IPV6_IFNAME:
Paul Jakma7514fb72007-05-02 16:05:35 +0000986 family = AFI_IP6;
987 case NEXTHOP_TYPE_IFNAME:
Feng Lu0d0686f2015-05-22 11:40:02 +0200988 ifp = if_lookup_by_name_vrf (nexthop->ifname, rib->vrf_id);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000989 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000990 {
991 if (set)
992 nexthop->ifindex = ifp->ifindex;
993 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
994 }
995 else
996 {
997 if (set)
998 nexthop->ifindex = 0;
999 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1000 }
1001 break;
1002 case NEXTHOP_TYPE_IPV4:
1003 case NEXTHOP_TYPE_IPV4_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +00001004 family = AFI_IP;
paul718e3742002-12-13 20:15:29 +00001005 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
1006 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1007 else
1008 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1009 break;
1010#ifdef HAVE_IPV6
1011 case NEXTHOP_TYPE_IPV6:
Paul Jakma7514fb72007-05-02 16:05:35 +00001012 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +00001013 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
1014 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1015 else
1016 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1017 break;
1018 case NEXTHOP_TYPE_IPV6_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +00001019 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +00001020 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
1021 {
Feng Lu0d0686f2015-05-22 11:40:02 +02001022 ifp = if_lookup_by_index_vrf (nexthop->ifindex, rib->vrf_id);
Andrew J. Schorr3f087672008-01-08 20:12:46 +00001023 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001024 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1025 else
1026 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1027 }
1028 else
1029 {
1030 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
1031 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1032 else
1033 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1034 }
1035 break;
1036#endif /* HAVE_IPV6 */
paul595db7f2003-05-25 21:35:06 +00001037 case NEXTHOP_TYPE_BLACKHOLE:
1038 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1039 break;
paul718e3742002-12-13 20:15:29 +00001040 default:
1041 break;
1042 }
Paul Jakma7514fb72007-05-02 16:05:35 +00001043 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1044 return 0;
1045
Christian Frankef3a17322013-07-05 15:35:41 +00001046 /* XXX: What exactly do those checks do? Do we support
1047 * e.g. IPv4 routes with IPv6 nexthops or vice versa? */
Paul Jakma7514fb72007-05-02 16:05:35 +00001048 if (RIB_SYSTEM_ROUTE(rib) ||
1049 (family == AFI_IP && rn->p.family != AF_INET) ||
1050 (family == AFI_IP6 && rn->p.family != AF_INET6))
1051 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1052
Christian Frankef3a17322013-07-05 15:35:41 +00001053 /* The original code didn't determine the family correctly
1054 * e.g. for NEXTHOP_TYPE_IFINDEX. Retrieve the correct afi
1055 * from the rib_table_info in those cases.
1056 * Possibly it may be better to use only the rib_table_info
1057 * in every case.
1058 */
1059 if (!family)
1060 family = info->afi;
1061
Paul Jakma7514fb72007-05-02 16:05:35 +00001062 rmap = 0;
1063 if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
1064 proto_rm[family][rib->type])
1065 rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
1066 if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
1067 rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
1068 if (rmap) {
Feng Lu1885d0a2015-05-22 11:40:04 +02001069 struct nexthop_vrfid nh_vrf = {nexthop, rib->vrf_id};
1070 ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, &nh_vrf);
Paul Jakma7514fb72007-05-02 16:05:35 +00001071 }
1072
1073 if (ret == RMAP_DENYMATCH)
1074 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
paul718e3742002-12-13 20:15:29 +00001075 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1076}
1077
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001078/* Iterate over all nexthops of the given RIB entry and refresh their
1079 * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
1080 * nexthop is found to toggle the ACTIVE flag, the whole rib structure
1081 * is flagged with ZEBRA_FLAG_CHANGED. The 4th 'set' argument is
1082 * transparently passed to nexthop_active_check().
1083 *
1084 * Return value is the new number of active nexthops.
1085 */
1086
paula1ac18c2005-06-28 17:17:12 +00001087static int
paul718e3742002-12-13 20:15:29 +00001088nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
1089{
1090 struct nexthop *nexthop;
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001091 unsigned int prev_active, prev_index, new_active;
paul718e3742002-12-13 20:15:29 +00001092
1093 rib->nexthop_active_num = 0;
1094 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1095
1096 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001097 {
1098 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001099 prev_index = nexthop->ifindex;
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001100 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
1101 rib->nexthop_active_num++;
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001102 if (prev_active != new_active ||
1103 prev_index != nexthop->ifindex)
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001104 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1105 }
paul718e3742002-12-13 20:15:29 +00001106 return rib->nexthop_active_num;
1107}
paul6baeb982003-10-28 03:47:15 +00001108
David Lamparter6b0655a2014-06-04 06:53:35 +02001109
paul718e3742002-12-13 20:15:29 +00001110
paula1ac18c2005-06-28 17:17:12 +00001111static void
paul718e3742002-12-13 20:15:29 +00001112rib_install_kernel (struct route_node *rn, struct rib *rib)
1113{
1114 int ret = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001115 struct nexthop *nexthop, *tnexthop;
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001116 rib_table_info_t *info = rn->table->info;
Christian Frankefa713d92013-07-05 15:35:37 +00001117 int recursing;
paul718e3742002-12-13 20:15:29 +00001118
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001119 if (info->safi != SAFI_UNICAST)
1120 {
1121 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1122 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1123 return;
1124 }
1125
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001126 /*
1127 * Make sure we update the FPM any time we send new information to
1128 * the kernel.
1129 */
1130 zfpm_trigger_update (rn, "installing in kernel");
paul718e3742002-12-13 20:15:29 +00001131 switch (PREFIX_FAMILY (&rn->p))
1132 {
1133 case AF_INET:
1134 ret = kernel_add_ipv4 (&rn->p, rib);
1135 break;
1136#ifdef HAVE_IPV6
1137 case AF_INET6:
1138 ret = kernel_add_ipv6 (&rn->p, rib);
1139 break;
1140#endif /* HAVE_IPV6 */
1141 }
1142
Denis Ovsienkodc958242007-08-13 16:03:06 +00001143 /* This condition is never met, if we are using rt_socket.c */
paul718e3742002-12-13 20:15:29 +00001144 if (ret < 0)
1145 {
Christian Frankefa713d92013-07-05 15:35:37 +00001146 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +00001147 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1148 }
1149}
1150
1151/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001152static int
paul718e3742002-12-13 20:15:29 +00001153rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
1154{
1155 int ret = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001156 struct nexthop *nexthop, *tnexthop;
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001157 rib_table_info_t *info = rn->table->info;
Christian Frankefa713d92013-07-05 15:35:37 +00001158 int recursing;
paul718e3742002-12-13 20:15:29 +00001159
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001160 if (info->safi != SAFI_UNICAST)
1161 {
1162 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1163 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1164 return ret;
1165 }
1166
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001167 /*
1168 * Make sure we update the FPM any time we send new information to
1169 * the kernel.
1170 */
1171 zfpm_trigger_update (rn, "uninstalling from kernel");
1172
paul718e3742002-12-13 20:15:29 +00001173 switch (PREFIX_FAMILY (&rn->p))
1174 {
1175 case AF_INET:
1176 ret = kernel_delete_ipv4 (&rn->p, rib);
1177 break;
1178#ifdef HAVE_IPV6
1179 case AF_INET6:
1180 ret = kernel_delete_ipv6 (&rn->p, rib);
1181 break;
1182#endif /* HAVE_IPV6 */
1183 }
1184
Christian Frankefa713d92013-07-05 15:35:37 +00001185 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +00001186 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1187
1188 return ret;
1189}
1190
1191/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001192static void
paul718e3742002-12-13 20:15:29 +00001193rib_uninstall (struct route_node *rn, struct rib *rib)
1194{
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001195 rib_table_info_t *info = rn->table->info;
1196
paul718e3742002-12-13 20:15:29 +00001197 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1198 {
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001199 if (info->safi == SAFI_UNICAST)
1200 zfpm_trigger_update (rn, "rib_uninstall");
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001201
paul718e3742002-12-13 20:15:29 +00001202 redistribute_delete (&rn->p, rib);
1203 if (! RIB_SYSTEM_ROUTE (rib))
1204 rib_uninstall_kernel (rn, rib);
1205 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
1206 }
1207}
1208
Paul Jakma6d691122006-07-27 21:49:00 +00001209static void rib_unlink (struct route_node *, struct rib *);
1210
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001211/*
1212 * rib_can_delete_dest
1213 *
1214 * Returns TRUE if the given dest can be deleted from the table.
1215 */
1216static int
1217rib_can_delete_dest (rib_dest_t *dest)
1218{
1219 if (dest->routes)
1220 {
1221 return 0;
1222 }
1223
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001224 /*
1225 * Don't delete the dest if we have to update the FPM about this
1226 * prefix.
1227 */
1228 if (CHECK_FLAG (dest->flags, RIB_DEST_UPDATE_FPM) ||
1229 CHECK_FLAG (dest->flags, RIB_DEST_SENT_TO_FPM))
1230 return 0;
1231
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001232 return 1;
1233}
1234
1235/*
1236 * rib_gc_dest
1237 *
1238 * Garbage collect the rib dest corresponding to the given route node
1239 * if appropriate.
1240 *
1241 * Returns TRUE if the dest was deleted, FALSE otherwise.
1242 */
1243int
1244rib_gc_dest (struct route_node *rn)
1245{
1246 rib_dest_t *dest;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001247
1248 dest = rib_dest_from_rnode (rn);
1249 if (!dest)
1250 return 0;
1251
1252 if (!rib_can_delete_dest (dest))
1253 return 0;
1254
1255 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001256 rnode_debug (rn, "removing dest from table");
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001257
1258 dest->rnode = NULL;
1259 XFREE (MTYPE_RIB_DEST, dest);
1260 rn->info = NULL;
1261
1262 /*
1263 * Release the one reference that we keep on the route node.
1264 */
1265 route_unlock_node (rn);
1266 return 1;
1267}
1268
paul718e3742002-12-13 20:15:29 +00001269/* Core function for processing routing information base. */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001270static void
1271rib_process (struct route_node *rn)
paul718e3742002-12-13 20:15:29 +00001272{
1273 struct rib *rib;
1274 struct rib *next;
1275 struct rib *fib = NULL;
1276 struct rib *select = NULL;
Paul Jakma6d691122006-07-27 21:49:00 +00001277 struct rib *del = NULL;
pauld753e9e2003-01-22 19:45:50 +00001278 int installed = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001279 struct nexthop *nexthop = NULL, *tnexthop;
1280 int recursing;
Balaji95116332014-10-23 15:25:25 +00001281 rib_table_info_t *info;
1282
paul4d38fdb2005-04-28 17:35:14 +00001283 assert (rn);
Balaji95116332014-10-23 15:25:25 +00001284
1285 info = rn->table->info;
1286
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001287 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00001288 {
paul718e3742002-12-13 20:15:29 +00001289 /* Currently installed rib. */
1290 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Paul Jakma6d691122006-07-27 21:49:00 +00001291 {
1292 assert (fib == NULL);
1293 fib = rib;
1294 }
1295
1296 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1297 * which we need to do do further work with below.
1298 */
1299 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1300 {
1301 if (rib != fib)
1302 {
1303 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001304 rnode_debug (rn, "rn %p, removing rib %p",
1305 (void *)rn, (void *)rib);
1306 rib_unlink (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001307 }
1308 else
1309 del = rib;
1310
1311 continue;
1312 }
paul4d38fdb2005-04-28 17:35:14 +00001313
paul718e3742002-12-13 20:15:29 +00001314 /* Skip unreachable nexthop. */
1315 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +00001316 continue;
paul718e3742002-12-13 20:15:29 +00001317
1318 /* Infinit distance. */
1319 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +00001320 continue;
paul718e3742002-12-13 20:15:29 +00001321
paulaf887b52006-01-18 14:52:52 +00001322 /* Newly selected rib, the common case. */
1323 if (!select)
1324 {
1325 select = rib;
1326 continue;
1327 }
1328
1329 /* filter route selection in following order:
paulaf887b52006-01-18 14:52:52 +00001330 * - connected beats other types
paula8d9c1f2006-01-25 06:31:04 +00001331 * - lower distance beats higher
paulaf887b52006-01-18 14:52:52 +00001332 * - lower metric beats higher for equal distance
1333 * - last, hence oldest, route wins tie break.
1334 */
paula1038a12006-01-30 14:08:51 +00001335
1336 /* Connected routes. Pick the last connected
1337 * route of the set of lowest metric connected routes.
1338 */
paula8d9c1f2006-01-25 06:31:04 +00001339 if (rib->type == ZEBRA_ROUTE_CONNECT)
1340 {
paula1038a12006-01-30 14:08:51 +00001341 if (select->type != ZEBRA_ROUTE_CONNECT
paula8d9c1f2006-01-25 06:31:04 +00001342 || rib->metric <= select->metric)
paula1038a12006-01-30 14:08:51 +00001343 select = rib;
1344 continue;
paula8d9c1f2006-01-25 06:31:04 +00001345 }
1346 else if (select->type == ZEBRA_ROUTE_CONNECT)
1347 continue;
1348
1349 /* higher distance loses */
1350 if (rib->distance > select->distance)
1351 continue;
1352
1353 /* lower wins */
1354 if (rib->distance < select->distance)
1355 {
paulaf887b52006-01-18 14:52:52 +00001356 select = rib;
paula8d9c1f2006-01-25 06:31:04 +00001357 continue;
1358 }
1359
1360 /* metric tie-breaks equal distance */
1361 if (rib->metric <= select->metric)
1362 select = rib;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001363 } /* RNODE_FOREACH_RIB_SAFE */
Denis Ovsienkodc958242007-08-13 16:03:06 +00001364
1365 /* After the cycle is finished, the following pointers will be set:
1366 * select --- the winner RIB entry, if any was found, otherwise NULL
1367 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1368 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1369 * rib --- NULL
1370 */
1371
1372 /* Same RIB entry is selected. Update FIB and finish. */
paul718e3742002-12-13 20:15:29 +00001373 if (select && select == fib)
1374 {
Paul Jakma6d691122006-07-27 21:49:00 +00001375 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001376 rnode_debug (rn, "Updating existing route, select %p, fib %p",
David Lampartereed3c482015-03-03 08:51:53 +01001377 (void *)select, (void *)fib);
paul718e3742002-12-13 20:15:29 +00001378 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +00001379 {
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001380 if (info->safi == SAFI_UNICAST)
1381 zfpm_trigger_update (rn, "updating existing route");
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001382
paul4d38fdb2005-04-28 17:35:14 +00001383 redistribute_delete (&rn->p, select);
1384 if (! RIB_SYSTEM_ROUTE (select))
1385 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001386
paul4d38fdb2005-04-28 17:35:14 +00001387 /* Set real nexthop. */
1388 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +00001389
paul4d38fdb2005-04-28 17:35:14 +00001390 if (! RIB_SYSTEM_ROUTE (select))
1391 rib_install_kernel (rn, select);
1392 redistribute_add (&rn->p, select);
1393 }
pauld753e9e2003-01-22 19:45:50 +00001394 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001395 {
1396 /* Housekeeping code to deal with
1397 race conditions in kernel with linux
1398 netlink reporting interface up before IPv4 or IPv6 protocol
1399 is ready to add routes.
1400 This makes sure the routes are IN the kernel.
1401 */
pauld753e9e2003-01-22 19:45:50 +00001402
Christian Frankefa713d92013-07-05 15:35:37 +00001403 for (ALL_NEXTHOPS_RO(select->nexthop, nexthop, tnexthop, recursing))
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001404 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
paul4d38fdb2005-04-28 17:35:14 +00001405 {
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001406 installed = 1;
1407 break;
paul4d38fdb2005-04-28 17:35:14 +00001408 }
1409 if (! installed)
1410 rib_install_kernel (rn, select);
1411 }
Paul Jakma6d691122006-07-27 21:49:00 +00001412 goto end;
paul718e3742002-12-13 20:15:29 +00001413 }
1414
Denis Ovsienkodc958242007-08-13 16:03:06 +00001415 /* At this point we either haven't found the best RIB entry or it is
1416 * different from what we currently intend to flag with SELECTED. In both
1417 * cases, if a RIB block is present in FIB, it should be withdrawn.
1418 */
paul718e3742002-12-13 20:15:29 +00001419 if (fib)
1420 {
Paul Jakma6d691122006-07-27 21:49:00 +00001421 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001422 rnode_debug (rn, "Removing existing route, fib %p", (void *)fib);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001423
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001424 if (info->safi == SAFI_UNICAST)
1425 zfpm_trigger_update (rn, "removing existing route");
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001426
paul718e3742002-12-13 20:15:29 +00001427 redistribute_delete (&rn->p, fib);
1428 if (! RIB_SYSTEM_ROUTE (fib))
1429 rib_uninstall_kernel (rn, fib);
1430 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1431
1432 /* Set real nexthop. */
1433 nexthop_active_update (rn, fib, 1);
1434 }
1435
Denis Ovsienkodc958242007-08-13 16:03:06 +00001436 /* Regardless of some RIB entry being SELECTED or not before, now we can
1437 * tell, that if a new winner exists, FIB is still not updated with this
1438 * data, but ready to be.
1439 */
paul718e3742002-12-13 20:15:29 +00001440 if (select)
1441 {
Paul Jakma6d691122006-07-27 21:49:00 +00001442 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001443 rnode_debug (rn, "Adding route, select %p", (void *)select);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001444
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001445 if (info->safi == SAFI_UNICAST)
1446 zfpm_trigger_update (rn, "new route selected");
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001447
paul718e3742002-12-13 20:15:29 +00001448 /* Set real nexthop. */
1449 nexthop_active_update (rn, select, 1);
1450
1451 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001452 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001453 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1454 redistribute_add (&rn->p, select);
1455 }
paul4d38fdb2005-04-28 17:35:14 +00001456
Paul Jakma6d691122006-07-27 21:49:00 +00001457 /* FIB route was removed, should be deleted */
1458 if (del)
1459 {
1460 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001461 rnode_debug (rn, "Deleting fib %p, rn %p", (void *)del, (void *)rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001462 rib_unlink (rn, del);
1463 }
paul4d38fdb2005-04-28 17:35:14 +00001464
Paul Jakma6d691122006-07-27 21:49:00 +00001465end:
1466 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lampartereed3c482015-03-03 08:51:53 +01001467 rnode_debug (rn, "rn %p dequeued", (void *)rn);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001468
1469 /*
1470 * Check if the dest can be deleted now.
1471 */
1472 rib_gc_dest (rn);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001473}
1474
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001475/* Take a list of route_node structs and return 1, if there was a record
1476 * picked from it and processed by rib_process(). Don't process more,
1477 * than one RN record; operate only in the specified sub-queue.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001478 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001479static unsigned int
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001480process_subq (struct list * subq, u_char qindex)
1481{
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001482 struct listnode *lnode = listhead (subq);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001483 struct route_node *rnode;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001484
1485 if (!lnode)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001486 return 0;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001487
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001488 rnode = listgetdata (lnode);
1489 rib_process (rnode);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001490
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001491 if (rnode->info)
1492 UNSET_FLAG (rib_dest_from_rnode (rnode)->flags, RIB_ROUTE_QUEUED (qindex));
1493
Chris Caputo67b94672009-07-18 04:02:26 +00001494#if 0
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001495 else
1496 {
1497 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1498 __func__, rnode, rnode->lock);
1499 zlog_backtrace(LOG_DEBUG);
1500 }
Chris Caputo67b94672009-07-18 04:02:26 +00001501#endif
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001502 route_unlock_node (rnode);
1503 list_delete_node (subq, lnode);
1504 return 1;
1505}
1506
1507/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1508 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1509 * is pointed to the meta queue structure.
1510 */
1511static wq_item_status
1512meta_queue_process (struct work_queue *dummy, void *data)
1513{
1514 struct meta_queue * mq = data;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001515 unsigned i;
1516
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001517 for (i = 0; i < MQ_SIZE; i++)
1518 if (process_subq (mq->subq[i], i))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001519 {
1520 mq->size--;
1521 break;
1522 }
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001523 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1524}
1525
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001526/*
1527 * Map from rib types to queue type (priority) in meta queue
1528 */
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001529static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
1530 [ZEBRA_ROUTE_SYSTEM] = 4,
1531 [ZEBRA_ROUTE_KERNEL] = 0,
1532 [ZEBRA_ROUTE_CONNECT] = 0,
1533 [ZEBRA_ROUTE_STATIC] = 1,
1534 [ZEBRA_ROUTE_RIP] = 2,
1535 [ZEBRA_ROUTE_RIPNG] = 2,
1536 [ZEBRA_ROUTE_OSPF] = 2,
1537 [ZEBRA_ROUTE_OSPF6] = 2,
1538 [ZEBRA_ROUTE_ISIS] = 2,
1539 [ZEBRA_ROUTE_BGP] = 3,
1540 [ZEBRA_ROUTE_HSLS] = 4,
Paul Jakma57345092011-12-25 17:52:09 +01001541 [ZEBRA_ROUTE_BABEL] = 2,
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001542};
1543
1544/* Look into the RN and queue it into one or more priority queues,
1545 * increasing the size for each data push done.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001546 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001547static void
1548rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001549{
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001550 struct rib *rib;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001551
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001552 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001553 {
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001554 u_char qindex = meta_queue_map[rib->type];
1555
1556 /* Invariant: at this point we always have rn->info set. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001557 if (CHECK_FLAG (rib_dest_from_rnode (rn)->flags,
1558 RIB_ROUTE_QUEUED (qindex)))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001559 {
1560 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lamparter94813742014-04-24 20:22:53 +02001561 rnode_debug (rn, "rn %p is already queued in sub-queue %u",
David Lampartereed3c482015-03-03 08:51:53 +01001562 (void *)rn, qindex);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001563 continue;
1564 }
1565
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001566 SET_FLAG (rib_dest_from_rnode (rn)->flags, RIB_ROUTE_QUEUED (qindex));
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001567 listnode_add (mq->subq[qindex], rn);
1568 route_lock_node (rn);
1569 mq->size++;
1570
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001571 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lamparter94813742014-04-24 20:22:53 +02001572 rnode_debug (rn, "queued rn %p into sub-queue %u",
David Lampartereed3c482015-03-03 08:51:53 +01001573 (void *)rn, qindex);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001574 }
paul4d38fdb2005-04-28 17:35:14 +00001575}
1576
Paul Jakma6d691122006-07-27 21:49:00 +00001577/* Add route_node to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001578static void
Paul Jakma6d691122006-07-27 21:49:00 +00001579rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
paul4d38fdb2005-04-28 17:35:14 +00001580{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001581 assert (zebra && rn);
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001582
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001583 /* Pointless to queue a route_node with no RIB entries to add or remove */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001584 if (!rnode_to_ribs (rn))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001585 {
1586 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
David Lampartereed3c482015-03-03 08:51:53 +01001587 __func__, (void *)rn, rn->lock);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001588 zlog_backtrace(LOG_DEBUG);
1589 return;
1590 }
1591
1592 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lamparter94813742014-04-24 20:22:53 +02001593 rnode_info (rn, "work queue added");
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001594
1595 assert (zebra);
1596
1597 if (zebra->ribq == NULL)
1598 {
1599 zlog_err ("%s: work_queue does not exist!", __func__);
1600 return;
Paul Jakma6d691122006-07-27 21:49:00 +00001601 }
paul4d38fdb2005-04-28 17:35:14 +00001602
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001603 /*
1604 * The RIB queue should normally be either empty or holding the only
1605 * work_queue_item element. In the latter case this element would
1606 * hold a pointer to the meta queue structure, which must be used to
1607 * actually queue the route nodes to process. So create the MQ
1608 * holder, if necessary, then push the work into it in any case.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001609 * This semantics was introduced after 0.99.9 release.
1610 */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001611 if (!zebra->ribq->items->count)
1612 work_queue_add (zebra->ribq, zebra->mq);
1613
1614 rib_meta_queue_add (zebra->mq, rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001615
1616 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lampartereed3c482015-03-03 08:51:53 +01001617 rnode_debug (rn, "rn %p queued", (void *)rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001618
1619 return;
paul4d38fdb2005-04-28 17:35:14 +00001620}
1621
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001622/* Create new meta queue.
1623 A destructor function doesn't seem to be necessary here.
1624 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001625static struct meta_queue *
1626meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001627{
1628 struct meta_queue *new;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001629 unsigned i;
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001630
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001631 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1632 assert(new);
1633
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001634 for (i = 0; i < MQ_SIZE; i++)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001635 {
1636 new->subq[i] = list_new ();
1637 assert(new->subq[i]);
1638 }
1639
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001640 return new;
1641}
1642
paul4d38fdb2005-04-28 17:35:14 +00001643/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001644static void
paul4d38fdb2005-04-28 17:35:14 +00001645rib_queue_init (struct zebra_t *zebra)
1646{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001647 assert (zebra);
1648
paul4d38fdb2005-04-28 17:35:14 +00001649 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001650 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001651 {
Paul Jakma6d691122006-07-27 21:49:00 +00001652 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001653 return;
1654 }
1655
1656 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001657 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001658 zebra->ribq->spec.errorfunc = NULL;
paul4d38fdb2005-04-28 17:35:14 +00001659 /* XXX: TODO: These should be runtime configurable via vty */
1660 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001661 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001662
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001663 if (!(zebra->mq = meta_queue_new ()))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001664 {
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001665 zlog_err ("%s: could not initialise meta queue!", __func__);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001666 return;
1667 }
1668 return;
paul718e3742002-12-13 20:15:29 +00001669}
1670
Paul Jakma6d691122006-07-27 21:49:00 +00001671/* RIB updates are processed via a queue of pointers to route_nodes.
1672 *
1673 * The queue length is bounded by the maximal size of the routing table,
1674 * as a route_node will not be requeued, if already queued.
1675 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001676 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1677 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1678 * and then submit route_node to queue for best-path selection later.
1679 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001680 *
1681 * Deleted RIBs are reaped during best-path selection.
1682 *
1683 * rib_addnode
1684 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001685 * |-------->| | best RIB, if required
1686 * | |
1687 * static_install->|->rib_addqueue...... -> rib_process
1688 * | |
1689 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001690 * |-> set RIB_ENTRY_REMOVE |
1691 * rib_delnode (RIB freed)
1692 *
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001693 * The 'info' pointer of a route_node points to a rib_dest_t
1694 * ('dest'). Queueing state for a route_node is kept on the dest. The
1695 * dest is created on-demand by rib_link() and is kept around at least
1696 * as long as there are ribs hanging off it (@see rib_gc_dest()).
Paul Jakma6d691122006-07-27 21:49:00 +00001697 *
1698 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1699 *
1700 * - route_nodes: refcounted by:
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001701 * - dest attached to route_node:
1702 * - managed by: rib_link/rib_gc_dest
Paul Jakma6d691122006-07-27 21:49:00 +00001703 * - route_node processing queue
1704 * - managed by: rib_addqueue, rib_process.
1705 *
1706 */
1707
paul718e3742002-12-13 20:15:29 +00001708/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001709static void
Paul Jakma6d691122006-07-27 21:49:00 +00001710rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001711{
1712 struct rib *head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001713 rib_dest_t *dest;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001714
paul4d38fdb2005-04-28 17:35:14 +00001715 assert (rib && rn);
1716
Paul Jakma6d691122006-07-27 21:49:00 +00001717 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001718 rnode_debug (rn, "rn %p, rib %p", (void *)rn, (void *)rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001719
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001720 dest = rib_dest_from_rnode (rn);
1721 if (!dest)
Paul Jakma6d691122006-07-27 21:49:00 +00001722 {
1723 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001724 rnode_debug (rn, "adding dest to table");
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001725
1726 dest = XCALLOC (MTYPE_RIB_DEST, sizeof (rib_dest_t));
1727 route_lock_node (rn); /* rn route table reference */
1728 rn->info = dest;
1729 dest->rnode = rn;
1730 }
1731
1732 head = dest->routes;
1733 if (head)
1734 {
Paul Jakma6d691122006-07-27 21:49:00 +00001735 head->prev = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001736 }
paul718e3742002-12-13 20:15:29 +00001737 rib->next = head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001738 dest->routes = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001739 rib_queue_add (&zebrad, rn);
1740}
1741
1742static void
1743rib_addnode (struct route_node *rn, struct rib *rib)
1744{
1745 /* RIB node has been un-removed before route-node is processed.
1746 * route_node must hence already be on the queue for processing..
1747 */
1748 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1749 {
1750 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001751 rnode_debug (rn, "rn %p, un-removed rib %p", (void *)rn, (void *)rib);
David Lamparter94813742014-04-24 20:22:53 +02001752
Paul Jakma6d691122006-07-27 21:49:00 +00001753 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1754 return;
1755 }
1756 rib_link (rn, rib);
1757}
1758
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001759/*
1760 * rib_unlink
1761 *
1762 * Detach a rib structure from a route_node.
1763 *
1764 * Note that a call to rib_unlink() should be followed by a call to
1765 * rib_gc_dest() at some point. This allows a rib_dest_t that is no
1766 * longer required to be deleted.
1767 */
Paul Jakma6d691122006-07-27 21:49:00 +00001768static void
1769rib_unlink (struct route_node *rn, struct rib *rib)
1770{
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001771 rib_dest_t *dest;
Paul Jakma6d691122006-07-27 21:49:00 +00001772
1773 assert (rn && rib);
1774
1775 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001776 rnode_debug (rn, "rn %p, rib %p", (void *)rn, (void *)rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001777
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001778 dest = rib_dest_from_rnode (rn);
1779
Paul Jakma6d691122006-07-27 21:49:00 +00001780 if (rib->next)
1781 rib->next->prev = rib->prev;
1782
1783 if (rib->prev)
1784 rib->prev->next = rib->next;
1785 else
1786 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001787 dest->routes = rib->next;
Paul Jakma6d691122006-07-27 21:49:00 +00001788 }
1789
1790 /* free RIB and nexthops */
Christian Frankefa713d92013-07-05 15:35:37 +00001791 nexthops_free(rib->nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00001792 XFREE (MTYPE_RIB, rib);
1793
paul718e3742002-12-13 20:15:29 +00001794}
1795
paula1ac18c2005-06-28 17:17:12 +00001796static void
paul718e3742002-12-13 20:15:29 +00001797rib_delnode (struct route_node *rn, struct rib *rib)
1798{
Paul Jakma6d691122006-07-27 21:49:00 +00001799 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001800 rnode_debug (rn, "rn %p, rib %p, removing", (void *)rn, (void *)rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001801 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1802 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001803}
1804
1805int
1806rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001807 struct in_addr *gate, struct in_addr *src,
Feng Lu0d0686f2015-05-22 11:40:02 +02001808 unsigned int ifindex, vrf_id_t vrf_id, int table_id,
G.Balajicddf3912011-11-26 21:59:32 +04001809 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001810{
1811 struct rib *rib;
1812 struct rib *same = NULL;
1813 struct route_table *table;
1814 struct route_node *rn;
1815 struct nexthop *nexthop;
1816
1817 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02001818 table = zebra_vrf_table (AFI_IP, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00001819 if (! table)
1820 return 0;
1821
1822 /* Make it sure prefixlen is applied to the prefix. */
1823 apply_mask_ipv4 (p);
1824
1825 /* Set default distance by route type. */
1826 if (distance == 0)
1827 {
Balaji.G837d16c2012-09-26 14:09:10 +05301828 if ((unsigned)type >= array_size(route_info))
David Lamparter7052f222009-08-27 00:28:28 +02001829 distance = 150;
1830 else
1831 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00001832
1833 /* iBGP distance is 200. */
1834 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1835 distance = 200;
1836 }
1837
1838 /* Lookup route node.*/
1839 rn = route_node_get (table, (struct prefix *) p);
1840
1841 /* If same type of route are installed, treat it as a implicit
1842 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001843 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00001844 {
Paul Jakma6d691122006-07-27 21:49:00 +00001845 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1846 continue;
1847
hassoebf1ead2005-09-21 14:58:20 +00001848 if (rib->type != type)
1849 continue;
1850 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001851 {
1852 same = rib;
1853 break;
1854 }
hassoebf1ead2005-09-21 14:58:20 +00001855 /* Duplicate connected route comes in. */
1856 else if ((nexthop = rib->nexthop) &&
1857 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001858 nexthop->ifindex == ifindex &&
1859 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001860 {
1861 rib->refcnt++;
1862 return 0 ;
1863 }
paul718e3742002-12-13 20:15:29 +00001864 }
1865
1866 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001867 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001868 rib->type = type;
1869 rib->distance = distance;
1870 rib->flags = flags;
1871 rib->metric = metric;
Feng Lu0d0686f2015-05-22 11:40:02 +02001872 rib->vrf_id = vrf_id;
1873 rib->table = table_id;
paul718e3742002-12-13 20:15:29 +00001874 rib->nexthop_num = 0;
1875 rib->uptime = time (NULL);
1876
1877 /* Nexthop settings. */
1878 if (gate)
1879 {
1880 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001881 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001882 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001883 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001884 }
1885 else
1886 nexthop_ifindex_add (rib, ifindex);
1887
1888 /* If this route is kernel route, set FIB flag to the route. */
1889 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1890 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1891 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1892
1893 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001894 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001895 zlog_debug ("%s: calling rib_addnode (%p, %p)",
1896 __func__, (void *)rn, (void *)rib);
paul718e3742002-12-13 20:15:29 +00001897 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001898
paul718e3742002-12-13 20:15:29 +00001899 /* Free implicit route.*/
1900 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001901 {
1902 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001903 zlog_debug ("%s: calling rib_delnode (%p, %p)",
1904 __func__, (void *)rn, (void *)rib);
paul4d38fdb2005-04-28 17:35:14 +00001905 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001906 }
paul4d38fdb2005-04-28 17:35:14 +00001907
1908 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001909 return 0;
1910}
1911
Denis Ovsienkodc958242007-08-13 16:03:06 +00001912/* This function dumps the contents of a given RIB entry into
1913 * standard debug log. Calling function name and IP prefix in
1914 * question are passed as 1st and 2nd arguments.
1915 */
1916
David Lamparterf7bf4152013-10-22 17:10:21 +00001917void _rib_dump (const char * func,
1918 union prefix46constptr pp, const struct rib * rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001919{
David Lamparterf7bf4152013-10-22 17:10:21 +00001920 const struct prefix *p = pp.p;
Timo Teräsbe6335d2015-05-23 11:08:41 +03001921 char straddr[PREFIX_STRLEN];
Christian Frankefa713d92013-07-05 15:35:37 +00001922 struct nexthop *nexthop, *tnexthop;
1923 int recursing;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001924
Feng Lu0d0686f2015-05-22 11:40:02 +02001925 zlog_debug ("%s: dumping RIB entry %p for %s vrf %u", func, (void *)rib,
1926 prefix2str(p, straddr, sizeof(straddr)), rib->vrf_id);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001927 zlog_debug
1928 (
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001929 "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
Denis Ovsienkodc958242007-08-13 16:03:06 +00001930 func,
1931 rib->refcnt,
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001932 (unsigned long) rib->uptime,
Denis Ovsienkodc958242007-08-13 16:03:06 +00001933 rib->type,
1934 rib->table
1935 );
1936 zlog_debug
1937 (
1938 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1939 func,
1940 rib->metric,
1941 rib->distance,
1942 rib->flags,
1943 rib->status
1944 );
1945 zlog_debug
1946 (
1947 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1948 func,
1949 rib->nexthop_num,
1950 rib->nexthop_active_num,
1951 rib->nexthop_fib_num
1952 );
Vincent Bernatfed643f2012-10-23 16:00:42 +00001953
Christian Frankefa713d92013-07-05 15:35:37 +00001954 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1955 {
Vincent Bernatfed643f2012-10-23 16:00:42 +00001956 inet_ntop (p->family, &nexthop->gate, straddr, INET6_ADDRSTRLEN);
Christian Frankefa713d92013-07-05 15:35:37 +00001957 zlog_debug
1958 (
1959 "%s: %s %s with flags %s%s%s",
1960 func,
1961 (recursing ? " NH" : "NH"),
1962 straddr,
1963 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1964 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1965 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1966 );
1967 }
Denis Ovsienkodc958242007-08-13 16:03:06 +00001968 zlog_debug ("%s: dump complete", func);
1969}
1970
1971/* This is an exported helper to rtm_read() to dump the strange
1972 * RIB entry found by rib_lookup_ipv4_route()
1973 */
1974
1975void rib_lookup_and_dump (struct prefix_ipv4 * p)
1976{
1977 struct route_table *table;
1978 struct route_node *rn;
1979 struct rib *rib;
1980 char prefix_buf[INET_ADDRSTRLEN];
1981
1982 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02001983 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001984 if (! table)
1985 {
Feng Lu41f44a22015-05-22 11:39:56 +02001986 zlog_err ("%s: zebra_vrf_table() returned NULL", __func__);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001987 return;
1988 }
1989
Denis Ovsienkodc958242007-08-13 16:03:06 +00001990 /* Scan the RIB table for exactly matching RIB entry. */
1991 rn = route_node_lookup (table, (struct prefix *) p);
1992
1993 /* No route for this prefix. */
1994 if (! rn)
1995 {
Timo Teräsbe6335d2015-05-23 11:08:41 +03001996 zlog_debug ("%s: lookup failed for %s", __func__,
1997 prefix2str((struct prefix*) p, prefix_buf, sizeof(prefix_buf)));
Denis Ovsienkodc958242007-08-13 16:03:06 +00001998 return;
1999 }
2000
2001 /* Unlock node. */
2002 route_unlock_node (rn);
2003
2004 /* let's go */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002005 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00002006 {
2007 zlog_debug
2008 (
2009 "%s: rn %p, rib %p: %s, %s",
2010 __func__,
David Lampartereed3c482015-03-03 08:51:53 +01002011 (void *)rn,
2012 (void *)rib,
Denis Ovsienkodc958242007-08-13 16:03:06 +00002013 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
2014 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
2015 );
David Lamparterf7bf4152013-10-22 17:10:21 +00002016 rib_dump (p, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002017 }
2018}
2019
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002020/* Check if requested address assignment will fail due to another
2021 * route being installed by zebra in FIB already. Take necessary
2022 * actions, if needed: remove such a route from FIB and deSELECT
2023 * corresponding RIB entry. Then put affected RN into RIBQ head.
2024 */
2025void rib_lookup_and_pushup (struct prefix_ipv4 * p)
2026{
2027 struct route_table *table;
2028 struct route_node *rn;
2029 struct rib *rib;
2030 unsigned changed = 0;
2031
Feng Lu41f44a22015-05-22 11:39:56 +02002032 if (NULL == (table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT)))
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002033 {
Feng Lu41f44a22015-05-22 11:39:56 +02002034 zlog_err ("%s: zebra_vrf_table() returned NULL", __func__);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002035 return;
2036 }
2037
2038 /* No matches would be the simplest case. */
2039 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
2040 return;
2041
2042 /* Unlock node. */
2043 route_unlock_node (rn);
2044
2045 /* Check all RIB entries. In case any changes have to be done, requeue
2046 * the RN into RIBQ head. If the routing message about the new connected
2047 * route (generated by the IP address we are going to assign very soon)
2048 * comes before the RIBQ is processed, the new RIB entry will join
2049 * RIBQ record already on head. This is necessary for proper revalidation
2050 * of the rest of the RIB.
2051 */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002052 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002053 {
2054 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
2055 ! RIB_SYSTEM_ROUTE (rib))
2056 {
2057 changed = 1;
2058 if (IS_ZEBRA_DEBUG_RIB)
2059 {
Timo Teräsbe6335d2015-05-23 11:08:41 +03002060 char buf[PREFIX_STRLEN];
2061 zlog_debug ("%s: freeing way for connected prefix %s", __func__,
2062 prefix2str(&rn->p, buf, sizeof(buf)));
David Lamparterf7bf4152013-10-22 17:10:21 +00002063 rib_dump (&rn->p, rib);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002064 }
2065 rib_uninstall (rn, rib);
2066 }
2067 }
2068 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002069 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002070}
2071
paul718e3742002-12-13 20:15:29 +00002072int
G.Balajicddf3912011-11-26 21:59:32 +04002073rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002074{
2075 struct route_table *table;
2076 struct route_node *rn;
2077 struct rib *same;
2078 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00002079
paul718e3742002-12-13 20:15:29 +00002080 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02002081 table = zebra_vrf_table (AFI_IP, safi, rib->vrf_id);
paul718e3742002-12-13 20:15:29 +00002082 if (! table)
2083 return 0;
G.Balajicddf3912011-11-26 21:59:32 +04002084
paul718e3742002-12-13 20:15:29 +00002085 /* Make it sure prefixlen is applied to the prefix. */
2086 apply_mask_ipv4 (p);
2087
2088 /* Set default distance by route type. */
2089 if (rib->distance == 0)
2090 {
2091 rib->distance = route_info[rib->type].distance;
2092
2093 /* iBGP distance is 200. */
2094 if (rib->type == ZEBRA_ROUTE_BGP
2095 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
2096 rib->distance = 200;
2097 }
2098
2099 /* Lookup route node.*/
2100 rn = route_node_get (table, (struct prefix *) p);
2101
2102 /* If same type of route are installed, treat it as a implicit
2103 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002104 RNODE_FOREACH_RIB (rn, same)
paul718e3742002-12-13 20:15:29 +00002105 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00002106 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00002107 continue;
2108
paul718e3742002-12-13 20:15:29 +00002109 if (same->type == rib->type && same->table == rib->table
2110 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00002111 break;
paul718e3742002-12-13 20:15:29 +00002112 }
paul4d38fdb2005-04-28 17:35:14 +00002113
paul718e3742002-12-13 20:15:29 +00002114 /* If this route is kernel route, set FIB flag to the route. */
2115 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
2116 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2117 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2118
2119 /* Link new rib to node.*/
2120 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002121 if (IS_ZEBRA_DEBUG_RIB)
2122 {
2123 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01002124 __func__, (void *)rn, (void *)rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00002125 rib_dump (p, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002126 }
paul718e3742002-12-13 20:15:29 +00002127
paul718e3742002-12-13 20:15:29 +00002128 /* Free implicit route.*/
2129 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00002130 {
2131 if (IS_ZEBRA_DEBUG_RIB)
2132 {
2133 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01002134 __func__, (void *)rn, (void *)same);
David Lamparterf7bf4152013-10-22 17:10:21 +00002135 rib_dump (p, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002136 }
paul4d38fdb2005-04-28 17:35:14 +00002137 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002138 }
paul4d38fdb2005-04-28 17:35:14 +00002139
2140 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002141 return 0;
2142}
2143
hassoebf1ead2005-09-21 14:58:20 +00002144/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002145int
2146rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Feng Lu0d0686f2015-05-22 11:40:02 +02002147 struct in_addr *gate, unsigned int ifindex, vrf_id_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002148{
2149 struct route_table *table;
2150 struct route_node *rn;
2151 struct rib *rib;
2152 struct rib *fib = NULL;
2153 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002154 struct nexthop *nexthop, *tnexthop;
2155 int recursing;
Timo Teräsbe6335d2015-05-23 11:08:41 +03002156 char buf1[PREFIX_STRLEN];
Stephen Hemminger81cce012009-04-28 14:28:00 -07002157 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002158
2159 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02002160 table = zebra_vrf_table (AFI_IP, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002161 if (! table)
2162 return 0;
2163
2164 /* Apply mask. */
2165 apply_mask_ipv4 (p);
2166
Christian Frankeb52aef12013-11-27 17:06:15 +00002167 if (IS_ZEBRA_DEBUG_KERNEL)
2168 {
2169 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002170 zlog_debug ("rib_delete_ipv4(): route delete %s vrf %u via %s ifindex %d",
2171 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Christian Frankeb52aef12013-11-27 17:06:15 +00002172 inet_ntoa (*gate),
2173 ifindex);
2174 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002175 zlog_debug ("rib_delete_ipv4(): route delete %s vrf %u ifindex %d",
2176 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Christian Frankeb52aef12013-11-27 17:06:15 +00002177 ifindex);
2178 }
paul5ec90d22003-06-19 01:41:37 +00002179
paul718e3742002-12-13 20:15:29 +00002180 /* Lookup route node. */
2181 rn = route_node_lookup (table, (struct prefix *) p);
2182 if (! rn)
2183 {
2184 if (IS_ZEBRA_DEBUG_KERNEL)
2185 {
2186 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002187 zlog_debug ("route %s vrf %u via %s ifindex %d doesn't exist in rib",
2188 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002189 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002190 ifindex);
2191 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002192 zlog_debug ("route %s vrf %u ifindex %d doesn't exist in rib",
2193 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002194 ifindex);
2195 }
2196 return ZEBRA_ERR_RTNOEXIST;
2197 }
2198
2199 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002200 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002201 {
Paul Jakma6d691122006-07-27 21:49:00 +00002202 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2203 continue;
2204
paul718e3742002-12-13 20:15:29 +00002205 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2206 fib = rib;
2207
hassoebf1ead2005-09-21 14:58:20 +00002208 if (rib->type != type)
2209 continue;
2210 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002211 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002212 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002213 if (nexthop->ifindex != ifindex)
2214 continue;
hassoebf1ead2005-09-21 14:58:20 +00002215 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002216 {
hassoebf1ead2005-09-21 14:58:20 +00002217 rib->refcnt--;
2218 route_unlock_node (rn);
2219 route_unlock_node (rn);
2220 return 0;
paul718e3742002-12-13 20:15:29 +00002221 }
hassoebf1ead2005-09-21 14:58:20 +00002222 same = rib;
2223 break;
paul718e3742002-12-13 20:15:29 +00002224 }
hassoebf1ead2005-09-21 14:58:20 +00002225 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002226 else
paul5ec90d22003-06-19 01:41:37 +00002227 {
Christian Frankefa713d92013-07-05 15:35:37 +00002228 if (gate == NULL)
2229 {
2230 same = rib;
2231 break;
2232 }
2233 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2234 if (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate))
2235 {
2236 same = rib;
2237 break;
2238 }
2239 if (same)
2240 break;
2241 }
paul718e3742002-12-13 20:15:29 +00002242 }
paul718e3742002-12-13 20:15:29 +00002243 /* If same type of route can't be found and this message is from
2244 kernel. */
2245 if (! same)
2246 {
2247 if (fib && type == ZEBRA_ROUTE_KERNEL)
2248 {
2249 /* Unset flags. */
2250 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2251 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2252
2253 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2254 }
2255 else
2256 {
2257 if (IS_ZEBRA_DEBUG_KERNEL)
2258 {
2259 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002260 zlog_debug ("route %s vrf %u via %s ifindex %d type %d "
2261 "doesn't exist in rib",
2262 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002263 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002264 ifindex,
2265 type);
2266 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002267 zlog_debug ("route %s vrf %u ifindex %d type %d doesn't exist in rib",
2268 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002269 ifindex,
2270 type);
2271 }
2272 route_unlock_node (rn);
2273 return ZEBRA_ERR_RTNOEXIST;
2274 }
2275 }
paul4d38fdb2005-04-28 17:35:14 +00002276
paul718e3742002-12-13 20:15:29 +00002277 if (same)
2278 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002279
paul718e3742002-12-13 20:15:29 +00002280 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002281 return 0;
2282}
David Lamparter6b0655a2014-06-04 06:53:35 +02002283
paul718e3742002-12-13 20:15:29 +00002284/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002285static void
Everton Marques33d86db2014-07-14 11:19:00 -03002286static_install_ipv4 (safi_t safi, struct prefix *p, struct static_ipv4 *si)
paul718e3742002-12-13 20:15:29 +00002287{
2288 struct rib *rib;
2289 struct route_node *rn;
2290 struct route_table *table;
2291
2292 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02002293 table = zebra_vrf_table (AFI_IP, safi, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00002294 if (! table)
2295 return;
2296
2297 /* Lookup existing route */
2298 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002299 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002300 {
2301 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2302 continue;
2303
2304 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2305 break;
2306 }
paul718e3742002-12-13 20:15:29 +00002307
2308 if (rib)
2309 {
2310 /* Same distance static route is there. Update it with new
2311 nexthop. */
paul718e3742002-12-13 20:15:29 +00002312 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002313 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002314 {
2315 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002316 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002317 break;
2318 case STATIC_IPV4_IFNAME:
2319 nexthop_ifname_add (rib, si->gate.ifname);
2320 break;
2321 case STATIC_IPV4_BLACKHOLE:
2322 nexthop_blackhole_add (rib);
2323 break;
paul4d38fdb2005-04-28 17:35:14 +00002324 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002325 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002326 }
2327 else
2328 {
2329 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002330 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2331
paul718e3742002-12-13 20:15:29 +00002332 rib->type = ZEBRA_ROUTE_STATIC;
2333 rib->distance = si->distance;
2334 rib->metric = 0;
Feng Lu0d0686f2015-05-22 11:40:02 +02002335 rib->vrf_id = VRF_DEFAULT;
Nolan Leakeb0145dd2012-09-13 17:17:31 +00002336 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002337 rib->nexthop_num = 0;
2338
2339 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002340 {
2341 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002342 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002343 break;
2344 case STATIC_IPV4_IFNAME:
2345 nexthop_ifname_add (rib, si->gate.ifname);
2346 break;
2347 case STATIC_IPV4_BLACKHOLE:
2348 nexthop_blackhole_add (rib);
2349 break;
2350 }
paul718e3742002-12-13 20:15:29 +00002351
hasso81dfcaa2003-05-25 19:21:25 +00002352 /* Save the flags of this static routes (reject, blackhole) */
2353 rib->flags = si->flags;
2354
paul718e3742002-12-13 20:15:29 +00002355 /* Link this rib to the tree. */
2356 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002357 }
2358}
2359
paula1ac18c2005-06-28 17:17:12 +00002360static int
paul718e3742002-12-13 20:15:29 +00002361static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2362{
2363 if (nexthop->type == NEXTHOP_TYPE_IPV4
2364 && si->type == STATIC_IPV4_GATEWAY
2365 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2366 return 1;
2367 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2368 && si->type == STATIC_IPV4_IFNAME
2369 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2370 return 1;
paul595db7f2003-05-25 21:35:06 +00002371 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2372 && si->type == STATIC_IPV4_BLACKHOLE)
2373 return 1;
paule8e19462006-01-19 20:16:55 +00002374 return 0;
paul718e3742002-12-13 20:15:29 +00002375}
2376
2377/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002378static void
Everton Marques33d86db2014-07-14 11:19:00 -03002379static_uninstall_ipv4 (safi_t safi, struct prefix *p, struct static_ipv4 *si)
paul718e3742002-12-13 20:15:29 +00002380{
2381 struct route_node *rn;
2382 struct rib *rib;
2383 struct nexthop *nexthop;
2384 struct route_table *table;
2385
2386 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02002387 table = zebra_vrf_table (AFI_IP, safi, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00002388 if (! table)
2389 return;
paul4d38fdb2005-04-28 17:35:14 +00002390
paul718e3742002-12-13 20:15:29 +00002391 /* Lookup existing route with type and distance. */
2392 rn = route_node_lookup (table, p);
2393 if (! rn)
2394 return;
2395
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002396 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002397 {
2398 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2399 continue;
2400
2401 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2402 break;
2403 }
paul718e3742002-12-13 20:15:29 +00002404
2405 if (! rib)
2406 {
2407 route_unlock_node (rn);
2408 return;
2409 }
2410
2411 /* Lookup nexthop. */
2412 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2413 if (static_ipv4_nexthop_same (nexthop, si))
2414 break;
2415
2416 /* Can't find nexthop. */
2417 if (! nexthop)
2418 {
2419 route_unlock_node (rn);
2420 return;
2421 }
2422
2423 /* Check nexthop. */
2424 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002425 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002426 else
2427 {
paul6baeb982003-10-28 03:47:15 +00002428 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2429 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002430 nexthop_delete (rib, nexthop);
2431 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002432 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002433 }
paul718e3742002-12-13 20:15:29 +00002434 /* Unlock node. */
2435 route_unlock_node (rn);
2436}
2437
paul718e3742002-12-13 20:15:29 +00002438int
Everton Marques33d86db2014-07-14 11:19:00 -03002439static_add_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate,
2440 const char *ifname, u_char flags, u_char distance,
Feng Lu0d0686f2015-05-22 11:40:02 +02002441 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002442{
2443 u_char type = 0;
2444 struct route_node *rn;
2445 struct static_ipv4 *si;
2446 struct static_ipv4 *pp;
2447 struct static_ipv4 *cp;
2448 struct static_ipv4 *update = NULL;
Feng Lu0d0686f2015-05-22 11:40:02 +02002449 struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
2450 struct route_table *stable = zvrf->stable[AFI_IP][safi];
paul718e3742002-12-13 20:15:29 +00002451
paul718e3742002-12-13 20:15:29 +00002452 if (! stable)
2453 return -1;
2454
2455 /* Lookup static route prefix. */
2456 rn = route_node_get (stable, p);
2457
2458 /* Make flags. */
2459 if (gate)
2460 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002461 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002462 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002463 else
2464 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002465
2466 /* Do nothing if there is a same static route. */
2467 for (si = rn->info; si; si = si->next)
2468 {
2469 if (type == si->type
2470 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2471 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2472 {
2473 if (distance == si->distance)
2474 {
2475 route_unlock_node (rn);
2476 return 0;
2477 }
2478 else
2479 update = si;
2480 }
2481 }
2482
Paul Jakma3c0755d2006-12-08 00:53:14 +00002483 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002484 if (update)
Everton Marques33d86db2014-07-14 11:19:00 -03002485 static_delete_ipv4_safi (safi, p, gate, ifname, update->distance, vrf_id);
paul718e3742002-12-13 20:15:29 +00002486
2487 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002488 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
paul718e3742002-12-13 20:15:29 +00002489
2490 si->type = type;
2491 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002492 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002493
2494 if (gate)
2495 si->gate.ipv4 = *gate;
2496 if (ifname)
2497 si->gate.ifname = XSTRDUP (0, ifname);
2498
2499 /* Add new static route information to the tree with sort by
2500 distance value and gateway address. */
2501 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2502 {
2503 if (si->distance < cp->distance)
2504 break;
2505 if (si->distance > cp->distance)
2506 continue;
2507 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2508 {
2509 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2510 break;
2511 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2512 continue;
2513 }
2514 }
2515
2516 /* Make linked list. */
2517 if (pp)
2518 pp->next = si;
2519 else
2520 rn->info = si;
2521 if (cp)
2522 cp->prev = si;
2523 si->prev = pp;
2524 si->next = cp;
2525
2526 /* Install into rib. */
Everton Marques33d86db2014-07-14 11:19:00 -03002527 static_install_ipv4 (safi, p, si);
paul718e3742002-12-13 20:15:29 +00002528
2529 return 1;
2530}
2531
paul718e3742002-12-13 20:15:29 +00002532int
Everton Marques33d86db2014-07-14 11:19:00 -03002533static_delete_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate,
Feng Lu0d0686f2015-05-22 11:40:02 +02002534 const char *ifname, u_char distance, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002535{
2536 u_char type = 0;
2537 struct route_node *rn;
2538 struct static_ipv4 *si;
2539 struct route_table *stable;
2540
2541 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02002542 stable = zebra_vrf_static_table (AFI_IP, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002543 if (! stable)
2544 return -1;
2545
2546 /* Lookup static route prefix. */
2547 rn = route_node_lookup (stable, p);
2548 if (! rn)
2549 return 0;
2550
2551 /* Make flags. */
2552 if (gate)
2553 type = STATIC_IPV4_GATEWAY;
2554 else if (ifname)
2555 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002556 else
2557 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002558
2559 /* Find same static route is the tree */
2560 for (si = rn->info; si; si = si->next)
2561 if (type == si->type
2562 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2563 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2564 break;
2565
2566 /* Can't find static route. */
2567 if (! si)
2568 {
2569 route_unlock_node (rn);
2570 return 0;
2571 }
2572
2573 /* Install into rib. */
Everton Marques33d86db2014-07-14 11:19:00 -03002574 static_uninstall_ipv4 (safi, p, si);
paul718e3742002-12-13 20:15:29 +00002575
2576 /* Unlink static route from linked list. */
2577 if (si->prev)
2578 si->prev->next = si->next;
2579 else
2580 rn->info = si->next;
2581 if (si->next)
2582 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002583 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002584
2585 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002586 if (ifname)
2587 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002588 XFREE (MTYPE_STATIC_IPV4, si);
2589
paul143a3852003-09-29 20:06:13 +00002590 route_unlock_node (rn);
2591
paul718e3742002-12-13 20:15:29 +00002592 return 1;
2593}
2594
paul718e3742002-12-13 20:15:29 +00002595#ifdef HAVE_IPV6
paul718e3742002-12-13 20:15:29 +00002596int
2597rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
Feng Lu0d0686f2015-05-22 11:40:02 +02002598 struct in6_addr *gate, unsigned int ifindex,
2599 vrf_id_t vrf_id, int table_id,
G.Balajif768f362011-11-26 22:10:39 +04002600 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002601{
2602 struct rib *rib;
2603 struct rib *same = NULL;
2604 struct route_table *table;
2605 struct route_node *rn;
2606 struct nexthop *nexthop;
2607
paul718e3742002-12-13 20:15:29 +00002608 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02002609 table = zebra_vrf_table (AFI_IP6, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002610 if (! table)
2611 return 0;
2612
2613 /* Make sure mask is applied. */
2614 apply_mask_ipv6 (p);
2615
2616 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002617 if (!distance)
2618 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002619
2620 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2621 distance = 200;
2622
paul718e3742002-12-13 20:15:29 +00002623 /* Lookup route node.*/
2624 rn = route_node_get (table, (struct prefix *) p);
2625
2626 /* If same type of route are installed, treat it as a implicit
2627 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002628 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002629 {
Paul Jakma6d691122006-07-27 21:49:00 +00002630 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2631 continue;
2632
hassoebf1ead2005-09-21 14:58:20 +00002633 if (rib->type != type)
2634 continue;
2635 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002636 {
2637 same = rib;
paul718e3742002-12-13 20:15:29 +00002638 break;
2639 }
hassoebf1ead2005-09-21 14:58:20 +00002640 else if ((nexthop = rib->nexthop) &&
2641 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2642 nexthop->ifindex == ifindex)
2643 {
2644 rib->refcnt++;
2645 return 0;
2646 }
paul718e3742002-12-13 20:15:29 +00002647 }
2648
2649 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002650 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2651
paul718e3742002-12-13 20:15:29 +00002652 rib->type = type;
2653 rib->distance = distance;
2654 rib->flags = flags;
2655 rib->metric = metric;
Feng Lu0d0686f2015-05-22 11:40:02 +02002656 rib->vrf_id = vrf_id;
2657 rib->table = table_id;
paul718e3742002-12-13 20:15:29 +00002658 rib->nexthop_num = 0;
2659 rib->uptime = time (NULL);
2660
2661 /* Nexthop settings. */
2662 if (gate)
2663 {
2664 if (ifindex)
2665 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2666 else
2667 nexthop_ipv6_add (rib, gate);
2668 }
2669 else
2670 nexthop_ifindex_add (rib, ifindex);
2671
2672 /* If this route is kernel route, set FIB flag to the route. */
2673 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2674 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2675 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2676
2677 /* Link new rib to node.*/
2678 rib_addnode (rn, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002679 if (IS_ZEBRA_DEBUG_RIB)
2680 {
2681 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01002682 __func__, (void *)rn, (void *)rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00002683 rib_dump (p, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002684 }
paul718e3742002-12-13 20:15:29 +00002685
paul718e3742002-12-13 20:15:29 +00002686 /* Free implicit route.*/
2687 if (same)
Vincent Bernatfed643f2012-10-23 16:00:42 +00002688 {
2689 if (IS_ZEBRA_DEBUG_RIB)
2690 {
2691 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01002692 __func__, (void *)rn, (void *)same);
David Lamparterf7bf4152013-10-22 17:10:21 +00002693 rib_dump (p, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002694 }
paul4d38fdb2005-04-28 17:35:14 +00002695 rib_delnode (rn, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002696 }
paul4d38fdb2005-04-28 17:35:14 +00002697
2698 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002699 return 0;
2700}
2701
hassoebf1ead2005-09-21 14:58:20 +00002702/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002703int
2704rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
Feng Lu0d0686f2015-05-22 11:40:02 +02002705 struct in6_addr *gate, unsigned int ifindex, vrf_id_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002706{
2707 struct route_table *table;
2708 struct route_node *rn;
2709 struct rib *rib;
2710 struct rib *fib = NULL;
2711 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002712 struct nexthop *nexthop, *tnexthop;
2713 int recursing;
Timo Teräsbe6335d2015-05-23 11:08:41 +03002714 char buf1[PREFIX_STRLEN];
Stephen Hemminger81cce012009-04-28 14:28:00 -07002715 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002716
2717 /* Apply mask. */
2718 apply_mask_ipv6 (p);
2719
2720 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02002721 table = zebra_vrf_table (AFI_IP6, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002722 if (! table)
2723 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002724
paul718e3742002-12-13 20:15:29 +00002725 /* Lookup route node. */
2726 rn = route_node_lookup (table, (struct prefix *) p);
2727 if (! rn)
2728 {
2729 if (IS_ZEBRA_DEBUG_KERNEL)
2730 {
2731 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002732 zlog_debug ("route %s vrf %u via %s ifindex %d doesn't exist in rib",
2733 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002734 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002735 ifindex);
2736 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002737 zlog_debug ("route %s vrf %u ifindex %d doesn't exist in rib",
2738 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002739 ifindex);
2740 }
2741 return ZEBRA_ERR_RTNOEXIST;
2742 }
2743
2744 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002745 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002746 {
Paul Jakma6d691122006-07-27 21:49:00 +00002747 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2748 continue;
2749
paul718e3742002-12-13 20:15:29 +00002750 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2751 fib = rib;
2752
hassoebf1ead2005-09-21 14:58:20 +00002753 if (rib->type != type)
2754 continue;
2755 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002756 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002757 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002758 if (nexthop->ifindex != ifindex)
2759 continue;
hassoebf1ead2005-09-21 14:58:20 +00002760 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002761 {
hassoebf1ead2005-09-21 14:58:20 +00002762 rib->refcnt--;
2763 route_unlock_node (rn);
2764 route_unlock_node (rn);
2765 return 0;
paul718e3742002-12-13 20:15:29 +00002766 }
hassoebf1ead2005-09-21 14:58:20 +00002767 same = rib;
2768 break;
paul718e3742002-12-13 20:15:29 +00002769 }
hassoebf1ead2005-09-21 14:58:20 +00002770 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002771 else
2772 {
2773 if (gate == NULL)
2774 {
2775 same = rib;
2776 break;
2777 }
2778 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2779 if (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate))
2780 {
2781 same = rib;
2782 break;
2783 }
2784 if (same)
2785 break;
2786 }
paul718e3742002-12-13 20:15:29 +00002787 }
2788
2789 /* If same type of route can't be found and this message is from
2790 kernel. */
2791 if (! same)
2792 {
2793 if (fib && type == ZEBRA_ROUTE_KERNEL)
2794 {
2795 /* Unset flags. */
2796 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2797 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2798
2799 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2800 }
2801 else
2802 {
2803 if (IS_ZEBRA_DEBUG_KERNEL)
2804 {
2805 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002806 zlog_debug ("route %s vrf %u via %s ifindex %d type %d "
2807 "doesn't exist in rib",
2808 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002809 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002810 ifindex,
2811 type);
2812 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002813 zlog_debug ("route %s vrf %u ifindex %d type %d doesn't exist in rib",
2814 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002815 ifindex,
2816 type);
2817 }
2818 route_unlock_node (rn);
2819 return ZEBRA_ERR_RTNOEXIST;
2820 }
2821 }
2822
2823 if (same)
2824 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002825
paul718e3742002-12-13 20:15:29 +00002826 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002827 return 0;
2828}
David Lamparter6b0655a2014-06-04 06:53:35 +02002829
paul718e3742002-12-13 20:15:29 +00002830/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002831static void
paul718e3742002-12-13 20:15:29 +00002832static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2833{
2834 struct rib *rib;
2835 struct route_table *table;
2836 struct route_node *rn;
2837
2838 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02002839 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00002840 if (! table)
2841 return;
2842
2843 /* Lookup existing route */
2844 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002845 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002846 {
2847 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2848 continue;
2849
2850 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2851 break;
2852 }
paul718e3742002-12-13 20:15:29 +00002853
2854 if (rib)
2855 {
2856 /* Same distance static route is there. Update it with new
2857 nexthop. */
paul718e3742002-12-13 20:15:29 +00002858 route_unlock_node (rn);
2859
2860 switch (si->type)
2861 {
2862 case STATIC_IPV6_GATEWAY:
2863 nexthop_ipv6_add (rib, &si->ipv6);
2864 break;
2865 case STATIC_IPV6_IFNAME:
2866 nexthop_ifname_add (rib, si->ifname);
2867 break;
2868 case STATIC_IPV6_GATEWAY_IFNAME:
2869 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2870 break;
2871 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002872 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002873 }
2874 else
2875 {
2876 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002877 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2878
paul718e3742002-12-13 20:15:29 +00002879 rib->type = ZEBRA_ROUTE_STATIC;
2880 rib->distance = si->distance;
2881 rib->metric = 0;
Feng Lu0d0686f2015-05-22 11:40:02 +02002882 rib->vrf_id = VRF_DEFAULT;
Dinesh G Duttd1b09912014-09-30 12:54:13 -07002883 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002884 rib->nexthop_num = 0;
2885
2886 switch (si->type)
2887 {
2888 case STATIC_IPV6_GATEWAY:
2889 nexthop_ipv6_add (rib, &si->ipv6);
2890 break;
2891 case STATIC_IPV6_IFNAME:
2892 nexthop_ifname_add (rib, si->ifname);
2893 break;
2894 case STATIC_IPV6_GATEWAY_IFNAME:
2895 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2896 break;
2897 }
2898
hasso81dfcaa2003-05-25 19:21:25 +00002899 /* Save the flags of this static routes (reject, blackhole) */
2900 rib->flags = si->flags;
2901
paul718e3742002-12-13 20:15:29 +00002902 /* Link this rib to the tree. */
2903 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002904 }
2905}
2906
paula1ac18c2005-06-28 17:17:12 +00002907static int
paul718e3742002-12-13 20:15:29 +00002908static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2909{
2910 if (nexthop->type == NEXTHOP_TYPE_IPV6
2911 && si->type == STATIC_IPV6_GATEWAY
2912 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2913 return 1;
2914 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2915 && si->type == STATIC_IPV6_IFNAME
2916 && strcmp (nexthop->ifname, si->ifname) == 0)
2917 return 1;
2918 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2919 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2920 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2921 && strcmp (nexthop->ifname, si->ifname) == 0)
2922 return 1;
paule8e19462006-01-19 20:16:55 +00002923 return 0;
paul718e3742002-12-13 20:15:29 +00002924}
2925
paula1ac18c2005-06-28 17:17:12 +00002926static void
paul718e3742002-12-13 20:15:29 +00002927static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2928{
2929 struct route_table *table;
2930 struct route_node *rn;
2931 struct rib *rib;
2932 struct nexthop *nexthop;
2933
2934 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02002935 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00002936 if (! table)
2937 return;
2938
2939 /* Lookup existing route with type and distance. */
2940 rn = route_node_lookup (table, (struct prefix *) p);
2941 if (! rn)
2942 return;
2943
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002944 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002945 {
2946 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2947 continue;
2948
2949 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2950 break;
2951 }
2952
paul718e3742002-12-13 20:15:29 +00002953 if (! rib)
2954 {
2955 route_unlock_node (rn);
2956 return;
2957 }
2958
2959 /* Lookup nexthop. */
2960 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2961 if (static_ipv6_nexthop_same (nexthop, si))
2962 break;
2963
2964 /* Can't find nexthop. */
2965 if (! nexthop)
2966 {
2967 route_unlock_node (rn);
2968 return;
2969 }
2970
2971 /* Check nexthop. */
2972 if (rib->nexthop_num == 1)
2973 {
2974 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002975 }
2976 else
2977 {
paul6baeb982003-10-28 03:47:15 +00002978 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2979 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002980 nexthop_delete (rib, nexthop);
2981 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002982 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002983 }
paul718e3742002-12-13 20:15:29 +00002984 /* Unlock node. */
2985 route_unlock_node (rn);
2986}
2987
2988/* Add static route into static route configuration. */
2989int
2990static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002991 const char *ifname, u_char flags, u_char distance,
Feng Lu0d0686f2015-05-22 11:40:02 +02002992 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002993{
2994 struct route_node *rn;
2995 struct static_ipv6 *si;
2996 struct static_ipv6 *pp;
2997 struct static_ipv6 *cp;
Feng Lu0d0686f2015-05-22 11:40:02 +02002998 struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
2999 struct route_table *stable = zvrf->stable[AFI_IP6][SAFI_UNICAST];
paul718e3742002-12-13 20:15:29 +00003000
paul718e3742002-12-13 20:15:29 +00003001 if (! stable)
3002 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00003003
3004 if (!gate &&
3005 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
3006 return -1;
3007
3008 if (!ifname &&
3009 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
3010 return -1;
paul718e3742002-12-13 20:15:29 +00003011
3012 /* Lookup static route prefix. */
3013 rn = route_node_get (stable, p);
3014
3015 /* Do nothing if there is a same static route. */
3016 for (si = rn->info; si; si = si->next)
3017 {
3018 if (distance == si->distance
3019 && type == si->type
3020 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
3021 && (! ifname || strcmp (ifname, si->ifname) == 0))
3022 {
3023 route_unlock_node (rn);
3024 return 0;
3025 }
3026 }
3027
3028 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07003029 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
paul718e3742002-12-13 20:15:29 +00003030
3031 si->type = type;
3032 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00003033 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00003034
3035 switch (type)
3036 {
3037 case STATIC_IPV6_GATEWAY:
3038 si->ipv6 = *gate;
3039 break;
3040 case STATIC_IPV6_IFNAME:
3041 si->ifname = XSTRDUP (0, ifname);
3042 break;
3043 case STATIC_IPV6_GATEWAY_IFNAME:
3044 si->ipv6 = *gate;
3045 si->ifname = XSTRDUP (0, ifname);
3046 break;
3047 }
3048
3049 /* Add new static route information to the tree with sort by
3050 distance value and gateway address. */
3051 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
3052 {
3053 if (si->distance < cp->distance)
3054 break;
3055 if (si->distance > cp->distance)
3056 continue;
3057 }
3058
3059 /* Make linked list. */
3060 if (pp)
3061 pp->next = si;
3062 else
3063 rn->info = si;
3064 if (cp)
3065 cp->prev = si;
3066 si->prev = pp;
3067 si->next = cp;
3068
3069 /* Install into rib. */
3070 static_install_ipv6 (p, si);
3071
3072 return 1;
3073}
3074
3075/* Delete static route from static route configuration. */
3076int
3077static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
Feng Lu0d0686f2015-05-22 11:40:02 +02003078 const char *ifname, u_char distance, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00003079{
3080 struct route_node *rn;
3081 struct static_ipv6 *si;
3082 struct route_table *stable;
3083
3084 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02003085 stable = zebra_vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +00003086 if (! stable)
3087 return -1;
3088
3089 /* Lookup static route prefix. */
3090 rn = route_node_lookup (stable, p);
3091 if (! rn)
3092 return 0;
3093
3094 /* Find same static route is the tree */
3095 for (si = rn->info; si; si = si->next)
3096 if (distance == si->distance
3097 && type == si->type
3098 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
3099 && (! ifname || strcmp (ifname, si->ifname) == 0))
3100 break;
3101
3102 /* Can't find static route. */
3103 if (! si)
3104 {
3105 route_unlock_node (rn);
3106 return 0;
3107 }
3108
3109 /* Install into rib. */
3110 static_uninstall_ipv6 (p, si);
3111
3112 /* Unlink static route from linked list. */
3113 if (si->prev)
3114 si->prev->next = si->next;
3115 else
3116 rn->info = si->next;
3117 if (si->next)
3118 si->next->prev = si->prev;
3119
3120 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00003121 if (ifname)
3122 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00003123 XFREE (MTYPE_STATIC_IPV6, si);
3124
3125 return 1;
3126}
3127#endif /* HAVE_IPV6 */
David Lamparter6b0655a2014-06-04 06:53:35 +02003128
paul718e3742002-12-13 20:15:29 +00003129/* RIB update function. */
3130void
Feng Lu0d0686f2015-05-22 11:40:02 +02003131rib_update (vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00003132{
3133 struct route_node *rn;
3134 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00003135
Feng Lu0d0686f2015-05-22 11:40:02 +02003136 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +00003137 if (table)
3138 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003139 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003140 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003141
Feng Lu0d0686f2015-05-22 11:40:02 +02003142 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +00003143 if (table)
3144 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003145 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003146 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003147}
3148
David Lamparter6b0655a2014-06-04 06:53:35 +02003149
paul718e3742002-12-13 20:15:29 +00003150/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00003151static void
paul718e3742002-12-13 20:15:29 +00003152rib_weed_table (struct route_table *table)
3153{
3154 struct route_node *rn;
3155 struct rib *rib;
3156 struct rib *next;
3157
3158 if (table)
3159 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003160 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003161 {
Paul Jakma6d691122006-07-27 21:49:00 +00003162 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3163 continue;
3164
paulb21b19c2003-06-15 01:28:29 +00003165 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00003166 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00003167 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003168 }
3169}
3170
3171/* Delete all routes from non main table. */
3172void
paula1ac18c2005-06-28 17:17:12 +00003173rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00003174{
Feng Lu0d0686f2015-05-22 11:40:02 +02003175 vrf_iter_t iter;
3176 struct zebra_vrf *zvrf;
3177
3178 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3179 if ((zvrf = vrf_iter2info (iter)) != NULL)
3180 {
3181 rib_weed_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
3182 rib_weed_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
3183 }
paul718e3742002-12-13 20:15:29 +00003184}
David Lamparter6b0655a2014-06-04 06:53:35 +02003185
Feng Lu0d0686f2015-05-22 11:40:02 +02003186#if 0
paul718e3742002-12-13 20:15:29 +00003187/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00003188static void
paul718e3742002-12-13 20:15:29 +00003189rib_sweep_table (struct route_table *table)
3190{
3191 struct route_node *rn;
3192 struct rib *rib;
3193 struct rib *next;
3194 int ret = 0;
3195
3196 if (table)
3197 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003198 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003199 {
Paul Jakma6d691122006-07-27 21:49:00 +00003200 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3201 continue;
3202
paul718e3742002-12-13 20:15:29 +00003203 if (rib->type == ZEBRA_ROUTE_KERNEL &&
3204 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
3205 {
3206 ret = rib_uninstall_kernel (rn, rib);
3207 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00003208 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003209 }
3210 }
3211}
Feng Lu0d0686f2015-05-22 11:40:02 +02003212#endif
paul718e3742002-12-13 20:15:29 +00003213
3214/* Sweep all RIB tables. */
3215void
paula1ac18c2005-06-28 17:17:12 +00003216rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00003217{
Feng Lu0d0686f2015-05-22 11:40:02 +02003218 vrf_iter_t iter;
3219 struct zebra_vrf *zvrf;
3220
3221 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3222 if ((zvrf = vrf_iter2info (iter)) != NULL)
3223 {
3224 rib_weed_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
3225 rib_weed_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
3226 }
paul718e3742002-12-13 20:15:29 +00003227}
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003228
3229/* Remove specific by protocol routes from 'table'. */
3230static unsigned long
3231rib_score_proto_table (u_char proto, struct route_table *table)
3232{
3233 struct route_node *rn;
3234 struct rib *rib;
3235 struct rib *next;
3236 unsigned long n = 0;
3237
3238 if (table)
3239 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003240 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003241 {
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003242 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3243 continue;
3244 if (rib->type == proto)
3245 {
3246 rib_delnode (rn, rib);
3247 n++;
3248 }
3249 }
3250
3251 return n;
3252}
3253
3254/* Remove specific by protocol routes. */
3255unsigned long
3256rib_score_proto (u_char proto)
3257{
Feng Lu0d0686f2015-05-22 11:40:02 +02003258 vrf_iter_t iter;
3259 struct zebra_vrf *zvrf;
3260 unsigned long cnt = 0;
3261
3262 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3263 if ((zvrf = vrf_iter2info (iter)) != NULL)
3264 cnt += rib_score_proto_table (proto, zvrf->table[AFI_IP][SAFI_UNICAST])
3265 +rib_score_proto_table (proto, zvrf->table[AFI_IP6][SAFI_UNICAST]);
3266
3267 return cnt;
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003268}
3269
paul718e3742002-12-13 20:15:29 +00003270/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00003271static void
paul718e3742002-12-13 20:15:29 +00003272rib_close_table (struct route_table *table)
3273{
3274 struct route_node *rn;
David Lamparter7ce9e6a2015-01-12 07:05:06 +01003275 rib_table_info_t *info = table->info;
paul718e3742002-12-13 20:15:29 +00003276 struct rib *rib;
3277
3278 if (table)
3279 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003280 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00003281 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003282 if (!CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
3283 continue;
3284
David Lamparter7ce9e6a2015-01-12 07:05:06 +01003285 if (info->safi == SAFI_UNICAST)
3286 zfpm_trigger_update (rn, NULL);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00003287
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003288 if (! RIB_SYSTEM_ROUTE (rib))
3289 rib_uninstall_kernel (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00003290 }
paul718e3742002-12-13 20:15:29 +00003291}
3292
3293/* Close all RIB tables. */
3294void
paula1ac18c2005-06-28 17:17:12 +00003295rib_close (void)
paul718e3742002-12-13 20:15:29 +00003296{
Feng Lu0d0686f2015-05-22 11:40:02 +02003297 vrf_iter_t iter;
3298 struct zebra_vrf *zvrf;
3299
3300 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3301 if ((zvrf = vrf_iter2info (iter)) != NULL)
3302 {
3303 rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
3304 rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
3305 }
paul718e3742002-12-13 20:15:29 +00003306}
David Lamparter6b0655a2014-06-04 06:53:35 +02003307
paul718e3742002-12-13 20:15:29 +00003308/* Routing information base initialize. */
3309void
paula1ac18c2005-06-28 17:17:12 +00003310rib_init (void)
paul718e3742002-12-13 20:15:29 +00003311{
paul4d38fdb2005-04-28 17:35:14 +00003312 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00003313}
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003314
3315/*
3316 * vrf_id_get_next
3317 *
3318 * Get the first vrf id that is greater than the given vrf id if any.
3319 *
3320 * Returns TRUE if a vrf id was found, FALSE otherwise.
3321 */
3322static inline int
Feng Lu41f44a22015-05-22 11:39:56 +02003323vrf_id_get_next (vrf_id_t vrf_id, vrf_id_t *next_id_p)
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003324{
Feng Lu41f44a22015-05-22 11:39:56 +02003325 vrf_iter_t iter = vrf_iterator (vrf_id);
3326 struct zebra_vrf *zvrf = vrf_iter2info (iter);
3327
3328 /* The same one ? Then find out the next. */
3329 if (zvrf && (zvrf->vrf_id == vrf_id))
3330 zvrf = vrf_iter2info (vrf_next (iter));
3331
3332 if (zvrf)
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003333 {
Feng Lu41f44a22015-05-22 11:39:56 +02003334 *next_id_p = zvrf->vrf_id;
3335 return 1;
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003336 }
3337
3338 return 0;
3339}
3340
3341/*
3342 * rib_tables_iter_next
3343 *
3344 * Returns the next table in the iteration.
3345 */
3346struct route_table *
3347rib_tables_iter_next (rib_tables_iter_t *iter)
3348{
3349 struct route_table *table;
3350
3351 /*
3352 * Array that helps us go over all AFI/SAFI combinations via one
3353 * index.
3354 */
3355 static struct {
3356 afi_t afi;
3357 safi_t safi;
3358 } afi_safis[] = {
3359 { AFI_IP, SAFI_UNICAST },
3360 { AFI_IP, SAFI_MULTICAST },
3361 { AFI_IP6, SAFI_UNICAST },
3362 { AFI_IP6, SAFI_MULTICAST },
3363 };
3364
3365 table = NULL;
3366
3367 switch (iter->state)
3368 {
3369
3370 case RIB_TABLES_ITER_S_INIT:
3371 iter->vrf_id = 0;
3372 iter->afi_safi_ix = -1;
3373
3374 /* Fall through */
3375
3376 case RIB_TABLES_ITER_S_ITERATING:
3377 iter->afi_safi_ix++;
3378 while (1)
3379 {
3380
3381 while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
3382 {
Feng Lu41f44a22015-05-22 11:39:56 +02003383 table = zebra_vrf_table (afi_safis[iter->afi_safi_ix].afi,
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003384 afi_safis[iter->afi_safi_ix].safi,
3385 iter->vrf_id);
3386 if (table)
3387 break;
3388
3389 iter->afi_safi_ix++;
3390 }
3391
3392 /*
3393 * Found another table in this vrf.
3394 */
3395 if (table)
3396 break;
3397
3398 /*
3399 * Done with all tables in the current vrf, go to the next
3400 * one.
3401 */
3402 if (!vrf_id_get_next (iter->vrf_id, &iter->vrf_id))
3403 break;
3404
3405 iter->afi_safi_ix = 0;
3406 }
3407
3408 break;
3409
3410 case RIB_TABLES_ITER_S_DONE:
3411 return NULL;
3412 }
3413
3414 if (table)
3415 iter->state = RIB_TABLES_ITER_S_ITERATING;
3416 else
3417 iter->state = RIB_TABLES_ITER_S_DONE;
3418
3419 return table;
3420}
Feng Lu41f44a22015-05-22 11:39:56 +02003421
3422/*
3423 * Create a routing table for the specific AFI/SAFI in the given VRF.
3424 */
3425static void
3426zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi)
3427{
3428 rib_table_info_t *info;
3429 struct route_table *table;
3430
3431 assert (!zvrf->table[afi][safi]);
3432
3433 table = route_table_init ();
3434 zvrf->table[afi][safi] = table;
3435
3436 info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
3437 info->zvrf = zvrf;
3438 info->afi = afi;
3439 info->safi = safi;
3440 table->info = info;
3441}
3442
3443/* Allocate new zebra VRF. */
3444struct zebra_vrf *
3445zebra_vrf_alloc (vrf_id_t vrf_id)
3446{
3447 struct zebra_vrf *zvrf;
3448
3449 zvrf = XCALLOC (MTYPE_ZEBRA_VRF, sizeof (struct zebra_vrf));
3450
3451 /* Allocate routing table and static table. */
3452 zebra_vrf_table_create (zvrf, AFI_IP, SAFI_UNICAST);
3453 zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_UNICAST);
3454 zvrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
3455 zvrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
3456 zebra_vrf_table_create (zvrf, AFI_IP, SAFI_MULTICAST);
3457 zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_MULTICAST);
3458 zvrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
3459 zvrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
3460
3461 /* Set VRF ID */
3462 zvrf->vrf_id = vrf_id;
3463
3464 return zvrf;
3465}
3466
3467/* Lookup the routing table in an enabled VRF. */
3468struct route_table *
3469zebra_vrf_table (afi_t afi, safi_t safi, vrf_id_t vrf_id)
3470{
3471 struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);
3472
3473 if (!zvrf)
3474 return NULL;
3475
3476 if (afi >= AFI_MAX || safi >= SAFI_MAX)
3477 return NULL;
3478
3479 return zvrf->table[afi][safi];
3480}
3481
3482/* Lookup the static routing table in a VRF. */
3483struct route_table *
3484zebra_vrf_static_table (afi_t afi, safi_t safi, vrf_id_t vrf_id)
3485{
3486 struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);
3487
3488 if (!zvrf)
3489 return NULL;
3490
3491 if (afi >= AFI_MAX || safi >= SAFI_MAX)
3492 return NULL;
3493
3494 return zvrf->stable[afi][safi];
3495}
3496