blob: 084af3802323c95b9f246cc2e8db57566d61e5fb [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 Lu7aaf4ea2015-05-22 11:40:06 +02002293 table = zebra_vrf_table (AFI_IP, safi, si->vrf_id);
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 Lu7aaf4ea2015-05-22 11:40:06 +02002335 rib->vrf_id = si->vrf_id;
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 Lu7aaf4ea2015-05-22 11:40:06 +02002387 table = zebra_vrf_table (AFI_IP, safi, si->vrf_id);
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;
Feng Lu7aaf4ea2015-05-22 11:40:06 +02002493 si->vrf_id = vrf_id;
paul718e3742002-12-13 20:15:29 +00002494
2495 if (gate)
2496 si->gate.ipv4 = *gate;
2497 if (ifname)
2498 si->gate.ifname = XSTRDUP (0, ifname);
2499
2500 /* Add new static route information to the tree with sort by
2501 distance value and gateway address. */
2502 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2503 {
2504 if (si->distance < cp->distance)
2505 break;
2506 if (si->distance > cp->distance)
2507 continue;
2508 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2509 {
2510 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2511 break;
2512 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2513 continue;
2514 }
2515 }
2516
2517 /* Make linked list. */
2518 if (pp)
2519 pp->next = si;
2520 else
2521 rn->info = si;
2522 if (cp)
2523 cp->prev = si;
2524 si->prev = pp;
2525 si->next = cp;
2526
2527 /* Install into rib. */
Everton Marques33d86db2014-07-14 11:19:00 -03002528 static_install_ipv4 (safi, p, si);
paul718e3742002-12-13 20:15:29 +00002529
2530 return 1;
2531}
2532
paul718e3742002-12-13 20:15:29 +00002533int
Everton Marques33d86db2014-07-14 11:19:00 -03002534static_delete_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate,
Feng Lu0d0686f2015-05-22 11:40:02 +02002535 const char *ifname, u_char distance, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002536{
2537 u_char type = 0;
2538 struct route_node *rn;
2539 struct static_ipv4 *si;
2540 struct route_table *stable;
2541
2542 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02002543 stable = zebra_vrf_static_table (AFI_IP, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002544 if (! stable)
2545 return -1;
2546
2547 /* Lookup static route prefix. */
2548 rn = route_node_lookup (stable, p);
2549 if (! rn)
2550 return 0;
2551
2552 /* Make flags. */
2553 if (gate)
2554 type = STATIC_IPV4_GATEWAY;
2555 else if (ifname)
2556 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002557 else
2558 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002559
2560 /* Find same static route is the tree */
2561 for (si = rn->info; si; si = si->next)
2562 if (type == si->type
2563 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2564 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2565 break;
2566
2567 /* Can't find static route. */
2568 if (! si)
2569 {
2570 route_unlock_node (rn);
2571 return 0;
2572 }
2573
2574 /* Install into rib. */
Everton Marques33d86db2014-07-14 11:19:00 -03002575 static_uninstall_ipv4 (safi, p, si);
paul718e3742002-12-13 20:15:29 +00002576
2577 /* Unlink static route from linked list. */
2578 if (si->prev)
2579 si->prev->next = si->next;
2580 else
2581 rn->info = si->next;
2582 if (si->next)
2583 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002584 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002585
2586 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002587 if (ifname)
2588 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002589 XFREE (MTYPE_STATIC_IPV4, si);
2590
paul143a3852003-09-29 20:06:13 +00002591 route_unlock_node (rn);
2592
paul718e3742002-12-13 20:15:29 +00002593 return 1;
2594}
2595
paul718e3742002-12-13 20:15:29 +00002596#ifdef HAVE_IPV6
paul718e3742002-12-13 20:15:29 +00002597int
2598rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
Feng Lu0d0686f2015-05-22 11:40:02 +02002599 struct in6_addr *gate, unsigned int ifindex,
2600 vrf_id_t vrf_id, int table_id,
G.Balajif768f362011-11-26 22:10:39 +04002601 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002602{
2603 struct rib *rib;
2604 struct rib *same = NULL;
2605 struct route_table *table;
2606 struct route_node *rn;
2607 struct nexthop *nexthop;
2608
paul718e3742002-12-13 20:15:29 +00002609 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02002610 table = zebra_vrf_table (AFI_IP6, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002611 if (! table)
2612 return 0;
2613
2614 /* Make sure mask is applied. */
2615 apply_mask_ipv6 (p);
2616
2617 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002618 if (!distance)
2619 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002620
2621 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2622 distance = 200;
2623
paul718e3742002-12-13 20:15:29 +00002624 /* Lookup route node.*/
2625 rn = route_node_get (table, (struct prefix *) p);
2626
2627 /* If same type of route are installed, treat it as a implicit
2628 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002629 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002630 {
Paul Jakma6d691122006-07-27 21:49:00 +00002631 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2632 continue;
2633
hassoebf1ead2005-09-21 14:58:20 +00002634 if (rib->type != type)
2635 continue;
2636 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002637 {
2638 same = rib;
paul718e3742002-12-13 20:15:29 +00002639 break;
2640 }
hassoebf1ead2005-09-21 14:58:20 +00002641 else if ((nexthop = rib->nexthop) &&
2642 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2643 nexthop->ifindex == ifindex)
2644 {
2645 rib->refcnt++;
2646 return 0;
2647 }
paul718e3742002-12-13 20:15:29 +00002648 }
2649
2650 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002651 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2652
paul718e3742002-12-13 20:15:29 +00002653 rib->type = type;
2654 rib->distance = distance;
2655 rib->flags = flags;
2656 rib->metric = metric;
Feng Lu0d0686f2015-05-22 11:40:02 +02002657 rib->vrf_id = vrf_id;
2658 rib->table = table_id;
paul718e3742002-12-13 20:15:29 +00002659 rib->nexthop_num = 0;
2660 rib->uptime = time (NULL);
2661
2662 /* Nexthop settings. */
2663 if (gate)
2664 {
2665 if (ifindex)
2666 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2667 else
2668 nexthop_ipv6_add (rib, gate);
2669 }
2670 else
2671 nexthop_ifindex_add (rib, ifindex);
2672
2673 /* If this route is kernel route, set FIB flag to the route. */
2674 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2675 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2676 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2677
2678 /* Link new rib to node.*/
2679 rib_addnode (rn, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002680 if (IS_ZEBRA_DEBUG_RIB)
2681 {
2682 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01002683 __func__, (void *)rn, (void *)rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00002684 rib_dump (p, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002685 }
paul718e3742002-12-13 20:15:29 +00002686
paul718e3742002-12-13 20:15:29 +00002687 /* Free implicit route.*/
2688 if (same)
Vincent Bernatfed643f2012-10-23 16:00:42 +00002689 {
2690 if (IS_ZEBRA_DEBUG_RIB)
2691 {
2692 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01002693 __func__, (void *)rn, (void *)same);
David Lamparterf7bf4152013-10-22 17:10:21 +00002694 rib_dump (p, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002695 }
paul4d38fdb2005-04-28 17:35:14 +00002696 rib_delnode (rn, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002697 }
paul4d38fdb2005-04-28 17:35:14 +00002698
2699 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002700 return 0;
2701}
2702
hassoebf1ead2005-09-21 14:58:20 +00002703/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002704int
2705rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
Feng Lu0d0686f2015-05-22 11:40:02 +02002706 struct in6_addr *gate, unsigned int ifindex, vrf_id_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002707{
2708 struct route_table *table;
2709 struct route_node *rn;
2710 struct rib *rib;
2711 struct rib *fib = NULL;
2712 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002713 struct nexthop *nexthop, *tnexthop;
2714 int recursing;
Timo Teräsbe6335d2015-05-23 11:08:41 +03002715 char buf1[PREFIX_STRLEN];
Stephen Hemminger81cce012009-04-28 14:28:00 -07002716 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002717
2718 /* Apply mask. */
2719 apply_mask_ipv6 (p);
2720
2721 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02002722 table = zebra_vrf_table (AFI_IP6, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002723 if (! table)
2724 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002725
paul718e3742002-12-13 20:15:29 +00002726 /* Lookup route node. */
2727 rn = route_node_lookup (table, (struct prefix *) p);
2728 if (! rn)
2729 {
2730 if (IS_ZEBRA_DEBUG_KERNEL)
2731 {
2732 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002733 zlog_debug ("route %s vrf %u via %s ifindex %d doesn't exist in rib",
2734 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002735 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002736 ifindex);
2737 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002738 zlog_debug ("route %s vrf %u ifindex %d doesn't exist in rib",
2739 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002740 ifindex);
2741 }
2742 return ZEBRA_ERR_RTNOEXIST;
2743 }
2744
2745 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002746 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002747 {
Paul Jakma6d691122006-07-27 21:49:00 +00002748 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2749 continue;
2750
paul718e3742002-12-13 20:15:29 +00002751 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2752 fib = rib;
2753
hassoebf1ead2005-09-21 14:58:20 +00002754 if (rib->type != type)
2755 continue;
2756 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002757 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002758 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002759 if (nexthop->ifindex != ifindex)
2760 continue;
hassoebf1ead2005-09-21 14:58:20 +00002761 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002762 {
hassoebf1ead2005-09-21 14:58:20 +00002763 rib->refcnt--;
2764 route_unlock_node (rn);
2765 route_unlock_node (rn);
2766 return 0;
paul718e3742002-12-13 20:15:29 +00002767 }
hassoebf1ead2005-09-21 14:58:20 +00002768 same = rib;
2769 break;
paul718e3742002-12-13 20:15:29 +00002770 }
hassoebf1ead2005-09-21 14:58:20 +00002771 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002772 else
2773 {
2774 if (gate == NULL)
2775 {
2776 same = rib;
2777 break;
2778 }
2779 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2780 if (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate))
2781 {
2782 same = rib;
2783 break;
2784 }
2785 if (same)
2786 break;
2787 }
paul718e3742002-12-13 20:15:29 +00002788 }
2789
2790 /* If same type of route can't be found and this message is from
2791 kernel. */
2792 if (! same)
2793 {
2794 if (fib && type == ZEBRA_ROUTE_KERNEL)
2795 {
2796 /* Unset flags. */
2797 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2798 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2799
2800 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2801 }
2802 else
2803 {
2804 if (IS_ZEBRA_DEBUG_KERNEL)
2805 {
2806 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002807 zlog_debug ("route %s vrf %u via %s ifindex %d type %d "
2808 "doesn't exist in rib",
2809 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002810 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002811 ifindex,
2812 type);
2813 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002814 zlog_debug ("route %s vrf %u ifindex %d type %d doesn't exist in rib",
2815 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002816 ifindex,
2817 type);
2818 }
2819 route_unlock_node (rn);
2820 return ZEBRA_ERR_RTNOEXIST;
2821 }
2822 }
2823
2824 if (same)
2825 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002826
paul718e3742002-12-13 20:15:29 +00002827 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002828 return 0;
2829}
David Lamparter6b0655a2014-06-04 06:53:35 +02002830
paul718e3742002-12-13 20:15:29 +00002831/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002832static void
paul718e3742002-12-13 20:15:29 +00002833static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2834{
2835 struct rib *rib;
2836 struct route_table *table;
2837 struct route_node *rn;
2838
2839 /* Lookup table. */
Feng Lu7aaf4ea2015-05-22 11:40:06 +02002840 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, si->vrf_id);
paul718e3742002-12-13 20:15:29 +00002841 if (! table)
2842 return;
2843
2844 /* Lookup existing route */
2845 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002846 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002847 {
2848 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2849 continue;
2850
2851 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2852 break;
2853 }
paul718e3742002-12-13 20:15:29 +00002854
2855 if (rib)
2856 {
2857 /* Same distance static route is there. Update it with new
2858 nexthop. */
paul718e3742002-12-13 20:15:29 +00002859 route_unlock_node (rn);
2860
2861 switch (si->type)
2862 {
2863 case STATIC_IPV6_GATEWAY:
2864 nexthop_ipv6_add (rib, &si->ipv6);
2865 break;
2866 case STATIC_IPV6_IFNAME:
2867 nexthop_ifname_add (rib, si->ifname);
2868 break;
2869 case STATIC_IPV6_GATEWAY_IFNAME:
2870 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2871 break;
2872 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002873 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002874 }
2875 else
2876 {
2877 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002878 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2879
paul718e3742002-12-13 20:15:29 +00002880 rib->type = ZEBRA_ROUTE_STATIC;
2881 rib->distance = si->distance;
2882 rib->metric = 0;
Feng Lu7aaf4ea2015-05-22 11:40:06 +02002883 rib->vrf_id = si->vrf_id;
Dinesh G Duttd1b09912014-09-30 12:54:13 -07002884 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002885 rib->nexthop_num = 0;
2886
2887 switch (si->type)
2888 {
2889 case STATIC_IPV6_GATEWAY:
2890 nexthop_ipv6_add (rib, &si->ipv6);
2891 break;
2892 case STATIC_IPV6_IFNAME:
2893 nexthop_ifname_add (rib, si->ifname);
2894 break;
2895 case STATIC_IPV6_GATEWAY_IFNAME:
2896 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2897 break;
2898 }
2899
hasso81dfcaa2003-05-25 19:21:25 +00002900 /* Save the flags of this static routes (reject, blackhole) */
2901 rib->flags = si->flags;
2902
paul718e3742002-12-13 20:15:29 +00002903 /* Link this rib to the tree. */
2904 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002905 }
2906}
2907
paula1ac18c2005-06-28 17:17:12 +00002908static int
paul718e3742002-12-13 20:15:29 +00002909static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2910{
2911 if (nexthop->type == NEXTHOP_TYPE_IPV6
2912 && si->type == STATIC_IPV6_GATEWAY
2913 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2914 return 1;
2915 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2916 && si->type == STATIC_IPV6_IFNAME
2917 && strcmp (nexthop->ifname, si->ifname) == 0)
2918 return 1;
2919 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2920 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2921 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2922 && strcmp (nexthop->ifname, si->ifname) == 0)
2923 return 1;
paule8e19462006-01-19 20:16:55 +00002924 return 0;
paul718e3742002-12-13 20:15:29 +00002925}
2926
paula1ac18c2005-06-28 17:17:12 +00002927static void
paul718e3742002-12-13 20:15:29 +00002928static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2929{
2930 struct route_table *table;
2931 struct route_node *rn;
2932 struct rib *rib;
2933 struct nexthop *nexthop;
2934
2935 /* Lookup table. */
Feng Lu7aaf4ea2015-05-22 11:40:06 +02002936 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, si->vrf_id);
paul718e3742002-12-13 20:15:29 +00002937 if (! table)
2938 return;
2939
2940 /* Lookup existing route with type and distance. */
2941 rn = route_node_lookup (table, (struct prefix *) p);
2942 if (! rn)
2943 return;
2944
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002945 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002946 {
2947 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2948 continue;
2949
2950 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2951 break;
2952 }
2953
paul718e3742002-12-13 20:15:29 +00002954 if (! rib)
2955 {
2956 route_unlock_node (rn);
2957 return;
2958 }
2959
2960 /* Lookup nexthop. */
2961 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2962 if (static_ipv6_nexthop_same (nexthop, si))
2963 break;
2964
2965 /* Can't find nexthop. */
2966 if (! nexthop)
2967 {
2968 route_unlock_node (rn);
2969 return;
2970 }
2971
2972 /* Check nexthop. */
2973 if (rib->nexthop_num == 1)
2974 {
2975 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002976 }
2977 else
2978 {
paul6baeb982003-10-28 03:47:15 +00002979 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2980 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002981 nexthop_delete (rib, nexthop);
2982 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002983 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002984 }
paul718e3742002-12-13 20:15:29 +00002985 /* Unlock node. */
2986 route_unlock_node (rn);
2987}
2988
2989/* Add static route into static route configuration. */
2990int
2991static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002992 const char *ifname, u_char flags, u_char distance,
Feng Lu0d0686f2015-05-22 11:40:02 +02002993 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002994{
2995 struct route_node *rn;
2996 struct static_ipv6 *si;
2997 struct static_ipv6 *pp;
2998 struct static_ipv6 *cp;
Feng Lu0d0686f2015-05-22 11:40:02 +02002999 struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
3000 struct route_table *stable = zvrf->stable[AFI_IP6][SAFI_UNICAST];
paul718e3742002-12-13 20:15:29 +00003001
paul718e3742002-12-13 20:15:29 +00003002 if (! stable)
3003 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00003004
3005 if (!gate &&
3006 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
3007 return -1;
3008
3009 if (!ifname &&
3010 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
3011 return -1;
paul718e3742002-12-13 20:15:29 +00003012
3013 /* Lookup static route prefix. */
3014 rn = route_node_get (stable, p);
3015
3016 /* Do nothing if there is a same static route. */
3017 for (si = rn->info; si; si = si->next)
3018 {
3019 if (distance == si->distance
3020 && type == si->type
3021 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
3022 && (! ifname || strcmp (ifname, si->ifname) == 0))
3023 {
3024 route_unlock_node (rn);
3025 return 0;
3026 }
3027 }
3028
3029 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07003030 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
paul718e3742002-12-13 20:15:29 +00003031
3032 si->type = type;
3033 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00003034 si->flags = flags;
Feng Lu7aaf4ea2015-05-22 11:40:06 +02003035 si->vrf_id = vrf_id;
paul718e3742002-12-13 20:15:29 +00003036
3037 switch (type)
3038 {
3039 case STATIC_IPV6_GATEWAY:
3040 si->ipv6 = *gate;
3041 break;
3042 case STATIC_IPV6_IFNAME:
3043 si->ifname = XSTRDUP (0, ifname);
3044 break;
3045 case STATIC_IPV6_GATEWAY_IFNAME:
3046 si->ipv6 = *gate;
3047 si->ifname = XSTRDUP (0, ifname);
3048 break;
3049 }
3050
3051 /* Add new static route information to the tree with sort by
3052 distance value and gateway address. */
3053 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
3054 {
3055 if (si->distance < cp->distance)
3056 break;
3057 if (si->distance > cp->distance)
3058 continue;
3059 }
3060
3061 /* Make linked list. */
3062 if (pp)
3063 pp->next = si;
3064 else
3065 rn->info = si;
3066 if (cp)
3067 cp->prev = si;
3068 si->prev = pp;
3069 si->next = cp;
3070
3071 /* Install into rib. */
3072 static_install_ipv6 (p, si);
3073
3074 return 1;
3075}
3076
3077/* Delete static route from static route configuration. */
3078int
3079static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
Feng Lu0d0686f2015-05-22 11:40:02 +02003080 const char *ifname, u_char distance, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00003081{
3082 struct route_node *rn;
3083 struct static_ipv6 *si;
3084 struct route_table *stable;
3085
3086 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02003087 stable = zebra_vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +00003088 if (! stable)
3089 return -1;
3090
3091 /* Lookup static route prefix. */
3092 rn = route_node_lookup (stable, p);
3093 if (! rn)
3094 return 0;
3095
3096 /* Find same static route is the tree */
3097 for (si = rn->info; si; si = si->next)
3098 if (distance == si->distance
3099 && type == si->type
3100 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
3101 && (! ifname || strcmp (ifname, si->ifname) == 0))
3102 break;
3103
3104 /* Can't find static route. */
3105 if (! si)
3106 {
3107 route_unlock_node (rn);
3108 return 0;
3109 }
3110
3111 /* Install into rib. */
3112 static_uninstall_ipv6 (p, si);
3113
3114 /* Unlink static route from linked list. */
3115 if (si->prev)
3116 si->prev->next = si->next;
3117 else
3118 rn->info = si->next;
3119 if (si->next)
3120 si->next->prev = si->prev;
3121
3122 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00003123 if (ifname)
3124 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00003125 XFREE (MTYPE_STATIC_IPV6, si);
3126
3127 return 1;
3128}
3129#endif /* HAVE_IPV6 */
David Lamparter6b0655a2014-06-04 06:53:35 +02003130
paul718e3742002-12-13 20:15:29 +00003131/* RIB update function. */
3132void
Feng Lu0d0686f2015-05-22 11:40:02 +02003133rib_update (vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00003134{
3135 struct route_node *rn;
3136 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00003137
Feng Lu0d0686f2015-05-22 11:40:02 +02003138 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +00003139 if (table)
3140 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003141 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003142 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003143
Feng Lu0d0686f2015-05-22 11:40:02 +02003144 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +00003145 if (table)
3146 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003147 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003148 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003149}
3150
David Lamparter6b0655a2014-06-04 06:53:35 +02003151
paul718e3742002-12-13 20:15:29 +00003152/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00003153static void
paul718e3742002-12-13 20:15:29 +00003154rib_weed_table (struct route_table *table)
3155{
3156 struct route_node *rn;
3157 struct rib *rib;
3158 struct rib *next;
3159
3160 if (table)
3161 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003162 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003163 {
Paul Jakma6d691122006-07-27 21:49:00 +00003164 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3165 continue;
3166
paulb21b19c2003-06-15 01:28:29 +00003167 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00003168 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00003169 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003170 }
3171}
3172
3173/* Delete all routes from non main table. */
3174void
paula1ac18c2005-06-28 17:17:12 +00003175rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00003176{
Feng Lu0d0686f2015-05-22 11:40:02 +02003177 vrf_iter_t iter;
3178 struct zebra_vrf *zvrf;
3179
3180 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3181 if ((zvrf = vrf_iter2info (iter)) != NULL)
3182 {
3183 rib_weed_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
3184 rib_weed_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
3185 }
paul718e3742002-12-13 20:15:29 +00003186}
David Lamparter6b0655a2014-06-04 06:53:35 +02003187
Feng Lu0d0686f2015-05-22 11:40:02 +02003188#if 0
paul718e3742002-12-13 20:15:29 +00003189/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00003190static void
paul718e3742002-12-13 20:15:29 +00003191rib_sweep_table (struct route_table *table)
3192{
3193 struct route_node *rn;
3194 struct rib *rib;
3195 struct rib *next;
3196 int ret = 0;
3197
3198 if (table)
3199 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003200 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003201 {
Paul Jakma6d691122006-07-27 21:49:00 +00003202 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3203 continue;
3204
paul718e3742002-12-13 20:15:29 +00003205 if (rib->type == ZEBRA_ROUTE_KERNEL &&
3206 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
3207 {
3208 ret = rib_uninstall_kernel (rn, rib);
3209 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00003210 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003211 }
3212 }
3213}
Feng Lu0d0686f2015-05-22 11:40:02 +02003214#endif
paul718e3742002-12-13 20:15:29 +00003215
3216/* Sweep all RIB tables. */
3217void
paula1ac18c2005-06-28 17:17:12 +00003218rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00003219{
Feng Lu0d0686f2015-05-22 11:40:02 +02003220 vrf_iter_t iter;
3221 struct zebra_vrf *zvrf;
3222
3223 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3224 if ((zvrf = vrf_iter2info (iter)) != NULL)
3225 {
3226 rib_weed_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
3227 rib_weed_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
3228 }
paul718e3742002-12-13 20:15:29 +00003229}
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003230
3231/* Remove specific by protocol routes from 'table'. */
3232static unsigned long
3233rib_score_proto_table (u_char proto, struct route_table *table)
3234{
3235 struct route_node *rn;
3236 struct rib *rib;
3237 struct rib *next;
3238 unsigned long n = 0;
3239
3240 if (table)
3241 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003242 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003243 {
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003244 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3245 continue;
3246 if (rib->type == proto)
3247 {
3248 rib_delnode (rn, rib);
3249 n++;
3250 }
3251 }
3252
3253 return n;
3254}
3255
3256/* Remove specific by protocol routes. */
3257unsigned long
3258rib_score_proto (u_char proto)
3259{
Feng Lu0d0686f2015-05-22 11:40:02 +02003260 vrf_iter_t iter;
3261 struct zebra_vrf *zvrf;
3262 unsigned long cnt = 0;
3263
3264 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3265 if ((zvrf = vrf_iter2info (iter)) != NULL)
3266 cnt += rib_score_proto_table (proto, zvrf->table[AFI_IP][SAFI_UNICAST])
3267 +rib_score_proto_table (proto, zvrf->table[AFI_IP6][SAFI_UNICAST]);
3268
3269 return cnt;
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003270}
3271
paul718e3742002-12-13 20:15:29 +00003272/* Close RIB and clean up kernel routes. */
Feng Lu267ceb22015-05-22 11:40:09 +02003273void
paul718e3742002-12-13 20:15:29 +00003274rib_close_table (struct route_table *table)
3275{
3276 struct route_node *rn;
David Lamparter7ce9e6a2015-01-12 07:05:06 +01003277 rib_table_info_t *info = table->info;
paul718e3742002-12-13 20:15:29 +00003278 struct rib *rib;
3279
3280 if (table)
3281 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003282 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00003283 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003284 if (!CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
3285 continue;
3286
David Lamparter7ce9e6a2015-01-12 07:05:06 +01003287 if (info->safi == SAFI_UNICAST)
3288 zfpm_trigger_update (rn, NULL);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00003289
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003290 if (! RIB_SYSTEM_ROUTE (rib))
3291 rib_uninstall_kernel (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00003292 }
paul718e3742002-12-13 20:15:29 +00003293}
3294
3295/* Close all RIB tables. */
3296void
paula1ac18c2005-06-28 17:17:12 +00003297rib_close (void)
paul718e3742002-12-13 20:15:29 +00003298{
Feng Lu0d0686f2015-05-22 11:40:02 +02003299 vrf_iter_t iter;
3300 struct zebra_vrf *zvrf;
3301
3302 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3303 if ((zvrf = vrf_iter2info (iter)) != NULL)
3304 {
3305 rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
3306 rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
3307 }
paul718e3742002-12-13 20:15:29 +00003308}
David Lamparter6b0655a2014-06-04 06:53:35 +02003309
paul718e3742002-12-13 20:15:29 +00003310/* Routing information base initialize. */
3311void
paula1ac18c2005-06-28 17:17:12 +00003312rib_init (void)
paul718e3742002-12-13 20:15:29 +00003313{
paul4d38fdb2005-04-28 17:35:14 +00003314 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00003315}
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003316
3317/*
3318 * vrf_id_get_next
3319 *
3320 * Get the first vrf id that is greater than the given vrf id if any.
3321 *
3322 * Returns TRUE if a vrf id was found, FALSE otherwise.
3323 */
3324static inline int
Feng Lu41f44a22015-05-22 11:39:56 +02003325vrf_id_get_next (vrf_id_t vrf_id, vrf_id_t *next_id_p)
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003326{
Feng Lu41f44a22015-05-22 11:39:56 +02003327 vrf_iter_t iter = vrf_iterator (vrf_id);
3328 struct zebra_vrf *zvrf = vrf_iter2info (iter);
3329
3330 /* The same one ? Then find out the next. */
3331 if (zvrf && (zvrf->vrf_id == vrf_id))
3332 zvrf = vrf_iter2info (vrf_next (iter));
3333
3334 if (zvrf)
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003335 {
Feng Lu41f44a22015-05-22 11:39:56 +02003336 *next_id_p = zvrf->vrf_id;
3337 return 1;
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003338 }
3339
3340 return 0;
3341}
3342
3343/*
3344 * rib_tables_iter_next
3345 *
3346 * Returns the next table in the iteration.
3347 */
3348struct route_table *
3349rib_tables_iter_next (rib_tables_iter_t *iter)
3350{
3351 struct route_table *table;
3352
3353 /*
3354 * Array that helps us go over all AFI/SAFI combinations via one
3355 * index.
3356 */
3357 static struct {
3358 afi_t afi;
3359 safi_t safi;
3360 } afi_safis[] = {
3361 { AFI_IP, SAFI_UNICAST },
3362 { AFI_IP, SAFI_MULTICAST },
3363 { AFI_IP6, SAFI_UNICAST },
3364 { AFI_IP6, SAFI_MULTICAST },
3365 };
3366
3367 table = NULL;
3368
3369 switch (iter->state)
3370 {
3371
3372 case RIB_TABLES_ITER_S_INIT:
3373 iter->vrf_id = 0;
3374 iter->afi_safi_ix = -1;
3375
3376 /* Fall through */
3377
3378 case RIB_TABLES_ITER_S_ITERATING:
3379 iter->afi_safi_ix++;
3380 while (1)
3381 {
3382
3383 while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
3384 {
Feng Lu41f44a22015-05-22 11:39:56 +02003385 table = zebra_vrf_table (afi_safis[iter->afi_safi_ix].afi,
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003386 afi_safis[iter->afi_safi_ix].safi,
3387 iter->vrf_id);
3388 if (table)
3389 break;
3390
3391 iter->afi_safi_ix++;
3392 }
3393
3394 /*
3395 * Found another table in this vrf.
3396 */
3397 if (table)
3398 break;
3399
3400 /*
3401 * Done with all tables in the current vrf, go to the next
3402 * one.
3403 */
3404 if (!vrf_id_get_next (iter->vrf_id, &iter->vrf_id))
3405 break;
3406
3407 iter->afi_safi_ix = 0;
3408 }
3409
3410 break;
3411
3412 case RIB_TABLES_ITER_S_DONE:
3413 return NULL;
3414 }
3415
3416 if (table)
3417 iter->state = RIB_TABLES_ITER_S_ITERATING;
3418 else
3419 iter->state = RIB_TABLES_ITER_S_DONE;
3420
3421 return table;
3422}
Feng Lu41f44a22015-05-22 11:39:56 +02003423
3424/*
3425 * Create a routing table for the specific AFI/SAFI in the given VRF.
3426 */
3427static void
3428zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi)
3429{
3430 rib_table_info_t *info;
3431 struct route_table *table;
3432
3433 assert (!zvrf->table[afi][safi]);
3434
3435 table = route_table_init ();
3436 zvrf->table[afi][safi] = table;
3437
3438 info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
3439 info->zvrf = zvrf;
3440 info->afi = afi;
3441 info->safi = safi;
3442 table->info = info;
3443}
3444
3445/* Allocate new zebra VRF. */
3446struct zebra_vrf *
3447zebra_vrf_alloc (vrf_id_t vrf_id)
3448{
3449 struct zebra_vrf *zvrf;
Feng Lu758fb8f2014-07-03 18:23:09 +08003450#ifdef HAVE_NETLINK
3451 char nl_name[64];
3452#endif
Feng Lu41f44a22015-05-22 11:39:56 +02003453
3454 zvrf = XCALLOC (MTYPE_ZEBRA_VRF, sizeof (struct zebra_vrf));
3455
3456 /* Allocate routing table and static table. */
3457 zebra_vrf_table_create (zvrf, AFI_IP, SAFI_UNICAST);
3458 zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_UNICAST);
3459 zvrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
3460 zvrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
3461 zebra_vrf_table_create (zvrf, AFI_IP, SAFI_MULTICAST);
3462 zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_MULTICAST);
3463 zvrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
3464 zvrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
3465
3466 /* Set VRF ID */
3467 zvrf->vrf_id = vrf_id;
3468
Feng Lu758fb8f2014-07-03 18:23:09 +08003469#ifdef HAVE_NETLINK
3470 /* Initialize netlink sockets */
3471 snprintf (nl_name, 64, "netlink-listen (vrf %u)", vrf_id);
3472 zvrf->netlink.sock = -1;
3473 zvrf->netlink.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name);
3474
3475 snprintf (nl_name, 64, "netlink-cmd (vrf %u)", vrf_id);
3476 zvrf->netlink_cmd.sock = -1;
3477 zvrf->netlink_cmd.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name);
3478#endif
3479
Feng Lu41f44a22015-05-22 11:39:56 +02003480 return zvrf;
3481}
3482
3483/* Lookup the routing table in an enabled VRF. */
3484struct route_table *
3485zebra_vrf_table (afi_t afi, safi_t safi, vrf_id_t vrf_id)
3486{
3487 struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);
3488
3489 if (!zvrf)
3490 return NULL;
3491
3492 if (afi >= AFI_MAX || safi >= SAFI_MAX)
3493 return NULL;
3494
3495 return zvrf->table[afi][safi];
3496}
3497
3498/* Lookup the static routing table in a VRF. */
3499struct route_table *
3500zebra_vrf_static_table (afi_t afi, safi_t safi, vrf_id_t vrf_id)
3501{
3502 struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);
3503
3504 if (!zvrf)
3505 return NULL;
3506
3507 if (afi >= AFI_MAX || safi >= SAFI_MAX)
3508 return NULL;
3509
3510 return zvrf->stable[afi][safi];
3511}
3512