blob: 336b56627efe9ca15190ec5f6e8ded729fa567b3 [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) {
1069 ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, nexthop);
1070 }
1071
1072 if (ret == RMAP_DENYMATCH)
1073 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
paul718e3742002-12-13 20:15:29 +00001074 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1075}
1076
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001077/* Iterate over all nexthops of the given RIB entry and refresh their
1078 * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
1079 * nexthop is found to toggle the ACTIVE flag, the whole rib structure
1080 * is flagged with ZEBRA_FLAG_CHANGED. The 4th 'set' argument is
1081 * transparently passed to nexthop_active_check().
1082 *
1083 * Return value is the new number of active nexthops.
1084 */
1085
paula1ac18c2005-06-28 17:17:12 +00001086static int
paul718e3742002-12-13 20:15:29 +00001087nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
1088{
1089 struct nexthop *nexthop;
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001090 unsigned int prev_active, prev_index, new_active;
paul718e3742002-12-13 20:15:29 +00001091
1092 rib->nexthop_active_num = 0;
1093 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1094
1095 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001096 {
1097 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001098 prev_index = nexthop->ifindex;
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001099 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
1100 rib->nexthop_active_num++;
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001101 if (prev_active != new_active ||
1102 prev_index != nexthop->ifindex)
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001103 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1104 }
paul718e3742002-12-13 20:15:29 +00001105 return rib->nexthop_active_num;
1106}
paul6baeb982003-10-28 03:47:15 +00001107
David Lamparter6b0655a2014-06-04 06:53:35 +02001108
paul718e3742002-12-13 20:15:29 +00001109
paula1ac18c2005-06-28 17:17:12 +00001110static void
paul718e3742002-12-13 20:15:29 +00001111rib_install_kernel (struct route_node *rn, struct rib *rib)
1112{
1113 int ret = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001114 struct nexthop *nexthop, *tnexthop;
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001115 rib_table_info_t *info = rn->table->info;
Christian Frankefa713d92013-07-05 15:35:37 +00001116 int recursing;
paul718e3742002-12-13 20:15:29 +00001117
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001118 if (info->safi != SAFI_UNICAST)
1119 {
1120 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1121 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1122 return;
1123 }
1124
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001125 /*
1126 * Make sure we update the FPM any time we send new information to
1127 * the kernel.
1128 */
1129 zfpm_trigger_update (rn, "installing in kernel");
paul718e3742002-12-13 20:15:29 +00001130 switch (PREFIX_FAMILY (&rn->p))
1131 {
1132 case AF_INET:
1133 ret = kernel_add_ipv4 (&rn->p, rib);
1134 break;
1135#ifdef HAVE_IPV6
1136 case AF_INET6:
1137 ret = kernel_add_ipv6 (&rn->p, rib);
1138 break;
1139#endif /* HAVE_IPV6 */
1140 }
1141
Denis Ovsienkodc958242007-08-13 16:03:06 +00001142 /* This condition is never met, if we are using rt_socket.c */
paul718e3742002-12-13 20:15:29 +00001143 if (ret < 0)
1144 {
Christian Frankefa713d92013-07-05 15:35:37 +00001145 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +00001146 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1147 }
1148}
1149
1150/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001151static int
paul718e3742002-12-13 20:15:29 +00001152rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
1153{
1154 int ret = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001155 struct nexthop *nexthop, *tnexthop;
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001156 rib_table_info_t *info = rn->table->info;
Christian Frankefa713d92013-07-05 15:35:37 +00001157 int recursing;
paul718e3742002-12-13 20:15:29 +00001158
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001159 if (info->safi != SAFI_UNICAST)
1160 {
1161 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1162 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1163 return ret;
1164 }
1165
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001166 /*
1167 * Make sure we update the FPM any time we send new information to
1168 * the kernel.
1169 */
1170 zfpm_trigger_update (rn, "uninstalling from kernel");
1171
paul718e3742002-12-13 20:15:29 +00001172 switch (PREFIX_FAMILY (&rn->p))
1173 {
1174 case AF_INET:
1175 ret = kernel_delete_ipv4 (&rn->p, rib);
1176 break;
1177#ifdef HAVE_IPV6
1178 case AF_INET6:
1179 ret = kernel_delete_ipv6 (&rn->p, rib);
1180 break;
1181#endif /* HAVE_IPV6 */
1182 }
1183
Christian Frankefa713d92013-07-05 15:35:37 +00001184 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +00001185 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1186
1187 return ret;
1188}
1189
1190/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001191static void
paul718e3742002-12-13 20:15:29 +00001192rib_uninstall (struct route_node *rn, struct rib *rib)
1193{
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001194 rib_table_info_t *info = rn->table->info;
1195
paul718e3742002-12-13 20:15:29 +00001196 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1197 {
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001198 if (info->safi == SAFI_UNICAST)
1199 zfpm_trigger_update (rn, "rib_uninstall");
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001200
paul718e3742002-12-13 20:15:29 +00001201 redistribute_delete (&rn->p, rib);
1202 if (! RIB_SYSTEM_ROUTE (rib))
1203 rib_uninstall_kernel (rn, rib);
1204 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
1205 }
1206}
1207
Paul Jakma6d691122006-07-27 21:49:00 +00001208static void rib_unlink (struct route_node *, struct rib *);
1209
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001210/*
1211 * rib_can_delete_dest
1212 *
1213 * Returns TRUE if the given dest can be deleted from the table.
1214 */
1215static int
1216rib_can_delete_dest (rib_dest_t *dest)
1217{
1218 if (dest->routes)
1219 {
1220 return 0;
1221 }
1222
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001223 /*
1224 * Don't delete the dest if we have to update the FPM about this
1225 * prefix.
1226 */
1227 if (CHECK_FLAG (dest->flags, RIB_DEST_UPDATE_FPM) ||
1228 CHECK_FLAG (dest->flags, RIB_DEST_SENT_TO_FPM))
1229 return 0;
1230
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001231 return 1;
1232}
1233
1234/*
1235 * rib_gc_dest
1236 *
1237 * Garbage collect the rib dest corresponding to the given route node
1238 * if appropriate.
1239 *
1240 * Returns TRUE if the dest was deleted, FALSE otherwise.
1241 */
1242int
1243rib_gc_dest (struct route_node *rn)
1244{
1245 rib_dest_t *dest;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001246
1247 dest = rib_dest_from_rnode (rn);
1248 if (!dest)
1249 return 0;
1250
1251 if (!rib_can_delete_dest (dest))
1252 return 0;
1253
1254 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001255 rnode_debug (rn, "removing dest from table");
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001256
1257 dest->rnode = NULL;
1258 XFREE (MTYPE_RIB_DEST, dest);
1259 rn->info = NULL;
1260
1261 /*
1262 * Release the one reference that we keep on the route node.
1263 */
1264 route_unlock_node (rn);
1265 return 1;
1266}
1267
paul718e3742002-12-13 20:15:29 +00001268/* Core function for processing routing information base. */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001269static void
1270rib_process (struct route_node *rn)
paul718e3742002-12-13 20:15:29 +00001271{
1272 struct rib *rib;
1273 struct rib *next;
1274 struct rib *fib = NULL;
1275 struct rib *select = NULL;
Paul Jakma6d691122006-07-27 21:49:00 +00001276 struct rib *del = NULL;
pauld753e9e2003-01-22 19:45:50 +00001277 int installed = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001278 struct nexthop *nexthop = NULL, *tnexthop;
1279 int recursing;
Balaji95116332014-10-23 15:25:25 +00001280 rib_table_info_t *info;
1281
paul4d38fdb2005-04-28 17:35:14 +00001282 assert (rn);
Balaji95116332014-10-23 15:25:25 +00001283
1284 info = rn->table->info;
1285
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001286 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00001287 {
paul718e3742002-12-13 20:15:29 +00001288 /* Currently installed rib. */
1289 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Paul Jakma6d691122006-07-27 21:49:00 +00001290 {
1291 assert (fib == NULL);
1292 fib = rib;
1293 }
1294
1295 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1296 * which we need to do do further work with below.
1297 */
1298 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1299 {
1300 if (rib != fib)
1301 {
1302 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001303 rnode_debug (rn, "rn %p, removing rib %p",
1304 (void *)rn, (void *)rib);
1305 rib_unlink (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001306 }
1307 else
1308 del = rib;
1309
1310 continue;
1311 }
paul4d38fdb2005-04-28 17:35:14 +00001312
paul718e3742002-12-13 20:15:29 +00001313 /* Skip unreachable nexthop. */
1314 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +00001315 continue;
paul718e3742002-12-13 20:15:29 +00001316
1317 /* Infinit distance. */
1318 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +00001319 continue;
paul718e3742002-12-13 20:15:29 +00001320
paulaf887b52006-01-18 14:52:52 +00001321 /* Newly selected rib, the common case. */
1322 if (!select)
1323 {
1324 select = rib;
1325 continue;
1326 }
1327
1328 /* filter route selection in following order:
paulaf887b52006-01-18 14:52:52 +00001329 * - connected beats other types
paula8d9c1f2006-01-25 06:31:04 +00001330 * - lower distance beats higher
paulaf887b52006-01-18 14:52:52 +00001331 * - lower metric beats higher for equal distance
1332 * - last, hence oldest, route wins tie break.
1333 */
paula1038a12006-01-30 14:08:51 +00001334
1335 /* Connected routes. Pick the last connected
1336 * route of the set of lowest metric connected routes.
1337 */
paula8d9c1f2006-01-25 06:31:04 +00001338 if (rib->type == ZEBRA_ROUTE_CONNECT)
1339 {
paula1038a12006-01-30 14:08:51 +00001340 if (select->type != ZEBRA_ROUTE_CONNECT
paula8d9c1f2006-01-25 06:31:04 +00001341 || rib->metric <= select->metric)
paula1038a12006-01-30 14:08:51 +00001342 select = rib;
1343 continue;
paula8d9c1f2006-01-25 06:31:04 +00001344 }
1345 else if (select->type == ZEBRA_ROUTE_CONNECT)
1346 continue;
1347
1348 /* higher distance loses */
1349 if (rib->distance > select->distance)
1350 continue;
1351
1352 /* lower wins */
1353 if (rib->distance < select->distance)
1354 {
paulaf887b52006-01-18 14:52:52 +00001355 select = rib;
paula8d9c1f2006-01-25 06:31:04 +00001356 continue;
1357 }
1358
1359 /* metric tie-breaks equal distance */
1360 if (rib->metric <= select->metric)
1361 select = rib;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001362 } /* RNODE_FOREACH_RIB_SAFE */
Denis Ovsienkodc958242007-08-13 16:03:06 +00001363
1364 /* After the cycle is finished, the following pointers will be set:
1365 * select --- the winner RIB entry, if any was found, otherwise NULL
1366 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1367 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1368 * rib --- NULL
1369 */
1370
1371 /* Same RIB entry is selected. Update FIB and finish. */
paul718e3742002-12-13 20:15:29 +00001372 if (select && select == fib)
1373 {
Paul Jakma6d691122006-07-27 21:49:00 +00001374 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001375 rnode_debug (rn, "Updating existing route, select %p, fib %p",
David Lampartereed3c482015-03-03 08:51:53 +01001376 (void *)select, (void *)fib);
paul718e3742002-12-13 20:15:29 +00001377 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +00001378 {
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001379 if (info->safi == SAFI_UNICAST)
1380 zfpm_trigger_update (rn, "updating existing route");
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001381
paul4d38fdb2005-04-28 17:35:14 +00001382 redistribute_delete (&rn->p, select);
1383 if (! RIB_SYSTEM_ROUTE (select))
1384 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001385
paul4d38fdb2005-04-28 17:35:14 +00001386 /* Set real nexthop. */
1387 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +00001388
paul4d38fdb2005-04-28 17:35:14 +00001389 if (! RIB_SYSTEM_ROUTE (select))
1390 rib_install_kernel (rn, select);
1391 redistribute_add (&rn->p, select);
1392 }
pauld753e9e2003-01-22 19:45:50 +00001393 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001394 {
1395 /* Housekeeping code to deal with
1396 race conditions in kernel with linux
1397 netlink reporting interface up before IPv4 or IPv6 protocol
1398 is ready to add routes.
1399 This makes sure the routes are IN the kernel.
1400 */
pauld753e9e2003-01-22 19:45:50 +00001401
Christian Frankefa713d92013-07-05 15:35:37 +00001402 for (ALL_NEXTHOPS_RO(select->nexthop, nexthop, tnexthop, recursing))
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001403 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
paul4d38fdb2005-04-28 17:35:14 +00001404 {
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001405 installed = 1;
1406 break;
paul4d38fdb2005-04-28 17:35:14 +00001407 }
1408 if (! installed)
1409 rib_install_kernel (rn, select);
1410 }
Paul Jakma6d691122006-07-27 21:49:00 +00001411 goto end;
paul718e3742002-12-13 20:15:29 +00001412 }
1413
Denis Ovsienkodc958242007-08-13 16:03:06 +00001414 /* At this point we either haven't found the best RIB entry or it is
1415 * different from what we currently intend to flag with SELECTED. In both
1416 * cases, if a RIB block is present in FIB, it should be withdrawn.
1417 */
paul718e3742002-12-13 20:15:29 +00001418 if (fib)
1419 {
Paul Jakma6d691122006-07-27 21:49:00 +00001420 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001421 rnode_debug (rn, "Removing existing route, fib %p", (void *)fib);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001422
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001423 if (info->safi == SAFI_UNICAST)
1424 zfpm_trigger_update (rn, "removing existing route");
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001425
paul718e3742002-12-13 20:15:29 +00001426 redistribute_delete (&rn->p, fib);
1427 if (! RIB_SYSTEM_ROUTE (fib))
1428 rib_uninstall_kernel (rn, fib);
1429 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1430
1431 /* Set real nexthop. */
1432 nexthop_active_update (rn, fib, 1);
1433 }
1434
Denis Ovsienkodc958242007-08-13 16:03:06 +00001435 /* Regardless of some RIB entry being SELECTED or not before, now we can
1436 * tell, that if a new winner exists, FIB is still not updated with this
1437 * data, but ready to be.
1438 */
paul718e3742002-12-13 20:15:29 +00001439 if (select)
1440 {
Paul Jakma6d691122006-07-27 21:49:00 +00001441 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001442 rnode_debug (rn, "Adding route, select %p", (void *)select);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001443
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001444 if (info->safi == SAFI_UNICAST)
1445 zfpm_trigger_update (rn, "new route selected");
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001446
paul718e3742002-12-13 20:15:29 +00001447 /* Set real nexthop. */
1448 nexthop_active_update (rn, select, 1);
1449
1450 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001451 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001452 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1453 redistribute_add (&rn->p, select);
1454 }
paul4d38fdb2005-04-28 17:35:14 +00001455
Paul Jakma6d691122006-07-27 21:49:00 +00001456 /* FIB route was removed, should be deleted */
1457 if (del)
1458 {
1459 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001460 rnode_debug (rn, "Deleting fib %p, rn %p", (void *)del, (void *)rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001461 rib_unlink (rn, del);
1462 }
paul4d38fdb2005-04-28 17:35:14 +00001463
Paul Jakma6d691122006-07-27 21:49:00 +00001464end:
1465 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lampartereed3c482015-03-03 08:51:53 +01001466 rnode_debug (rn, "rn %p dequeued", (void *)rn);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001467
1468 /*
1469 * Check if the dest can be deleted now.
1470 */
1471 rib_gc_dest (rn);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001472}
1473
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001474/* Take a list of route_node structs and return 1, if there was a record
1475 * picked from it and processed by rib_process(). Don't process more,
1476 * than one RN record; operate only in the specified sub-queue.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001477 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001478static unsigned int
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001479process_subq (struct list * subq, u_char qindex)
1480{
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001481 struct listnode *lnode = listhead (subq);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001482 struct route_node *rnode;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001483
1484 if (!lnode)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001485 return 0;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001486
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001487 rnode = listgetdata (lnode);
1488 rib_process (rnode);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001489
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001490 if (rnode->info)
1491 UNSET_FLAG (rib_dest_from_rnode (rnode)->flags, RIB_ROUTE_QUEUED (qindex));
1492
Chris Caputo67b94672009-07-18 04:02:26 +00001493#if 0
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001494 else
1495 {
1496 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1497 __func__, rnode, rnode->lock);
1498 zlog_backtrace(LOG_DEBUG);
1499 }
Chris Caputo67b94672009-07-18 04:02:26 +00001500#endif
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001501 route_unlock_node (rnode);
1502 list_delete_node (subq, lnode);
1503 return 1;
1504}
1505
1506/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1507 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1508 * is pointed to the meta queue structure.
1509 */
1510static wq_item_status
1511meta_queue_process (struct work_queue *dummy, void *data)
1512{
1513 struct meta_queue * mq = data;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001514 unsigned i;
1515
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001516 for (i = 0; i < MQ_SIZE; i++)
1517 if (process_subq (mq->subq[i], i))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001518 {
1519 mq->size--;
1520 break;
1521 }
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001522 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1523}
1524
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001525/*
1526 * Map from rib types to queue type (priority) in meta queue
1527 */
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001528static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
1529 [ZEBRA_ROUTE_SYSTEM] = 4,
1530 [ZEBRA_ROUTE_KERNEL] = 0,
1531 [ZEBRA_ROUTE_CONNECT] = 0,
1532 [ZEBRA_ROUTE_STATIC] = 1,
1533 [ZEBRA_ROUTE_RIP] = 2,
1534 [ZEBRA_ROUTE_RIPNG] = 2,
1535 [ZEBRA_ROUTE_OSPF] = 2,
1536 [ZEBRA_ROUTE_OSPF6] = 2,
1537 [ZEBRA_ROUTE_ISIS] = 2,
1538 [ZEBRA_ROUTE_BGP] = 3,
1539 [ZEBRA_ROUTE_HSLS] = 4,
Paul Jakma57345092011-12-25 17:52:09 +01001540 [ZEBRA_ROUTE_BABEL] = 2,
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001541};
1542
1543/* Look into the RN and queue it into one or more priority queues,
1544 * increasing the size for each data push done.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001545 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001546static void
1547rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001548{
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001549 struct rib *rib;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001550
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001551 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001552 {
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001553 u_char qindex = meta_queue_map[rib->type];
1554
1555 /* Invariant: at this point we always have rn->info set. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001556 if (CHECK_FLAG (rib_dest_from_rnode (rn)->flags,
1557 RIB_ROUTE_QUEUED (qindex)))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001558 {
1559 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lamparter94813742014-04-24 20:22:53 +02001560 rnode_debug (rn, "rn %p is already queued in sub-queue %u",
David Lampartereed3c482015-03-03 08:51:53 +01001561 (void *)rn, qindex);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001562 continue;
1563 }
1564
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001565 SET_FLAG (rib_dest_from_rnode (rn)->flags, RIB_ROUTE_QUEUED (qindex));
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001566 listnode_add (mq->subq[qindex], rn);
1567 route_lock_node (rn);
1568 mq->size++;
1569
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001570 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lamparter94813742014-04-24 20:22:53 +02001571 rnode_debug (rn, "queued rn %p into sub-queue %u",
David Lampartereed3c482015-03-03 08:51:53 +01001572 (void *)rn, qindex);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001573 }
paul4d38fdb2005-04-28 17:35:14 +00001574}
1575
Paul Jakma6d691122006-07-27 21:49:00 +00001576/* Add route_node to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001577static void
Paul Jakma6d691122006-07-27 21:49:00 +00001578rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
paul4d38fdb2005-04-28 17:35:14 +00001579{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001580 assert (zebra && rn);
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001581
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001582 /* Pointless to queue a route_node with no RIB entries to add or remove */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001583 if (!rnode_to_ribs (rn))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001584 {
1585 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
David Lampartereed3c482015-03-03 08:51:53 +01001586 __func__, (void *)rn, rn->lock);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001587 zlog_backtrace(LOG_DEBUG);
1588 return;
1589 }
1590
1591 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lamparter94813742014-04-24 20:22:53 +02001592 rnode_info (rn, "work queue added");
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001593
1594 assert (zebra);
1595
1596 if (zebra->ribq == NULL)
1597 {
1598 zlog_err ("%s: work_queue does not exist!", __func__);
1599 return;
Paul Jakma6d691122006-07-27 21:49:00 +00001600 }
paul4d38fdb2005-04-28 17:35:14 +00001601
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001602 /*
1603 * The RIB queue should normally be either empty or holding the only
1604 * work_queue_item element. In the latter case this element would
1605 * hold a pointer to the meta queue structure, which must be used to
1606 * actually queue the route nodes to process. So create the MQ
1607 * holder, if necessary, then push the work into it in any case.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001608 * This semantics was introduced after 0.99.9 release.
1609 */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001610 if (!zebra->ribq->items->count)
1611 work_queue_add (zebra->ribq, zebra->mq);
1612
1613 rib_meta_queue_add (zebra->mq, rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001614
1615 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lampartereed3c482015-03-03 08:51:53 +01001616 rnode_debug (rn, "rn %p queued", (void *)rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001617
1618 return;
paul4d38fdb2005-04-28 17:35:14 +00001619}
1620
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001621/* Create new meta queue.
1622 A destructor function doesn't seem to be necessary here.
1623 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001624static struct meta_queue *
1625meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001626{
1627 struct meta_queue *new;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001628 unsigned i;
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001629
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001630 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1631 assert(new);
1632
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001633 for (i = 0; i < MQ_SIZE; i++)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001634 {
1635 new->subq[i] = list_new ();
1636 assert(new->subq[i]);
1637 }
1638
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001639 return new;
1640}
1641
paul4d38fdb2005-04-28 17:35:14 +00001642/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001643static void
paul4d38fdb2005-04-28 17:35:14 +00001644rib_queue_init (struct zebra_t *zebra)
1645{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001646 assert (zebra);
1647
paul4d38fdb2005-04-28 17:35:14 +00001648 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001649 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001650 {
Paul Jakma6d691122006-07-27 21:49:00 +00001651 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001652 return;
1653 }
1654
1655 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001656 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001657 zebra->ribq->spec.errorfunc = NULL;
paul4d38fdb2005-04-28 17:35:14 +00001658 /* XXX: TODO: These should be runtime configurable via vty */
1659 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001660 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001661
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001662 if (!(zebra->mq = meta_queue_new ()))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001663 {
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001664 zlog_err ("%s: could not initialise meta queue!", __func__);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001665 return;
1666 }
1667 return;
paul718e3742002-12-13 20:15:29 +00001668}
1669
Paul Jakma6d691122006-07-27 21:49:00 +00001670/* RIB updates are processed via a queue of pointers to route_nodes.
1671 *
1672 * The queue length is bounded by the maximal size of the routing table,
1673 * as a route_node will not be requeued, if already queued.
1674 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001675 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1676 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1677 * and then submit route_node to queue for best-path selection later.
1678 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001679 *
1680 * Deleted RIBs are reaped during best-path selection.
1681 *
1682 * rib_addnode
1683 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001684 * |-------->| | best RIB, if required
1685 * | |
1686 * static_install->|->rib_addqueue...... -> rib_process
1687 * | |
1688 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001689 * |-> set RIB_ENTRY_REMOVE |
1690 * rib_delnode (RIB freed)
1691 *
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001692 * The 'info' pointer of a route_node points to a rib_dest_t
1693 * ('dest'). Queueing state for a route_node is kept on the dest. The
1694 * dest is created on-demand by rib_link() and is kept around at least
1695 * as long as there are ribs hanging off it (@see rib_gc_dest()).
Paul Jakma6d691122006-07-27 21:49:00 +00001696 *
1697 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1698 *
1699 * - route_nodes: refcounted by:
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001700 * - dest attached to route_node:
1701 * - managed by: rib_link/rib_gc_dest
Paul Jakma6d691122006-07-27 21:49:00 +00001702 * - route_node processing queue
1703 * - managed by: rib_addqueue, rib_process.
1704 *
1705 */
1706
paul718e3742002-12-13 20:15:29 +00001707/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001708static void
Paul Jakma6d691122006-07-27 21:49:00 +00001709rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001710{
1711 struct rib *head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001712 rib_dest_t *dest;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001713
paul4d38fdb2005-04-28 17:35:14 +00001714 assert (rib && rn);
1715
Paul Jakma6d691122006-07-27 21:49:00 +00001716 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001717 rnode_debug (rn, "rn %p, rib %p", (void *)rn, (void *)rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001718
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001719 dest = rib_dest_from_rnode (rn);
1720 if (!dest)
Paul Jakma6d691122006-07-27 21:49:00 +00001721 {
1722 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001723 rnode_debug (rn, "adding dest to table");
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001724
1725 dest = XCALLOC (MTYPE_RIB_DEST, sizeof (rib_dest_t));
1726 route_lock_node (rn); /* rn route table reference */
1727 rn->info = dest;
1728 dest->rnode = rn;
1729 }
1730
1731 head = dest->routes;
1732 if (head)
1733 {
Paul Jakma6d691122006-07-27 21:49:00 +00001734 head->prev = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001735 }
paul718e3742002-12-13 20:15:29 +00001736 rib->next = head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001737 dest->routes = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001738 rib_queue_add (&zebrad, rn);
1739}
1740
1741static void
1742rib_addnode (struct route_node *rn, struct rib *rib)
1743{
1744 /* RIB node has been un-removed before route-node is processed.
1745 * route_node must hence already be on the queue for processing..
1746 */
1747 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1748 {
1749 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001750 rnode_debug (rn, "rn %p, un-removed rib %p", (void *)rn, (void *)rib);
David Lamparter94813742014-04-24 20:22:53 +02001751
Paul Jakma6d691122006-07-27 21:49:00 +00001752 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1753 return;
1754 }
1755 rib_link (rn, rib);
1756}
1757
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001758/*
1759 * rib_unlink
1760 *
1761 * Detach a rib structure from a route_node.
1762 *
1763 * Note that a call to rib_unlink() should be followed by a call to
1764 * rib_gc_dest() at some point. This allows a rib_dest_t that is no
1765 * longer required to be deleted.
1766 */
Paul Jakma6d691122006-07-27 21:49:00 +00001767static void
1768rib_unlink (struct route_node *rn, struct rib *rib)
1769{
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001770 rib_dest_t *dest;
Paul Jakma6d691122006-07-27 21:49:00 +00001771
1772 assert (rn && rib);
1773
1774 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001775 rnode_debug (rn, "rn %p, rib %p", (void *)rn, (void *)rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001776
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001777 dest = rib_dest_from_rnode (rn);
1778
Paul Jakma6d691122006-07-27 21:49:00 +00001779 if (rib->next)
1780 rib->next->prev = rib->prev;
1781
1782 if (rib->prev)
1783 rib->prev->next = rib->next;
1784 else
1785 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001786 dest->routes = rib->next;
Paul Jakma6d691122006-07-27 21:49:00 +00001787 }
1788
1789 /* free RIB and nexthops */
Christian Frankefa713d92013-07-05 15:35:37 +00001790 nexthops_free(rib->nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00001791 XFREE (MTYPE_RIB, rib);
1792
paul718e3742002-12-13 20:15:29 +00001793}
1794
paula1ac18c2005-06-28 17:17:12 +00001795static void
paul718e3742002-12-13 20:15:29 +00001796rib_delnode (struct route_node *rn, struct rib *rib)
1797{
Paul Jakma6d691122006-07-27 21:49:00 +00001798 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001799 rnode_debug (rn, "rn %p, rib %p, removing", (void *)rn, (void *)rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001800 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1801 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001802}
1803
1804int
1805rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001806 struct in_addr *gate, struct in_addr *src,
Feng Lu0d0686f2015-05-22 11:40:02 +02001807 unsigned int ifindex, vrf_id_t vrf_id, int table_id,
G.Balajicddf3912011-11-26 21:59:32 +04001808 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001809{
1810 struct rib *rib;
1811 struct rib *same = NULL;
1812 struct route_table *table;
1813 struct route_node *rn;
1814 struct nexthop *nexthop;
1815
1816 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02001817 table = zebra_vrf_table (AFI_IP, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00001818 if (! table)
1819 return 0;
1820
1821 /* Make it sure prefixlen is applied to the prefix. */
1822 apply_mask_ipv4 (p);
1823
1824 /* Set default distance by route type. */
1825 if (distance == 0)
1826 {
Balaji.G837d16c2012-09-26 14:09:10 +05301827 if ((unsigned)type >= array_size(route_info))
David Lamparter7052f222009-08-27 00:28:28 +02001828 distance = 150;
1829 else
1830 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00001831
1832 /* iBGP distance is 200. */
1833 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1834 distance = 200;
1835 }
1836
1837 /* Lookup route node.*/
1838 rn = route_node_get (table, (struct prefix *) p);
1839
1840 /* If same type of route are installed, treat it as a implicit
1841 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001842 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00001843 {
Paul Jakma6d691122006-07-27 21:49:00 +00001844 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1845 continue;
1846
hassoebf1ead2005-09-21 14:58:20 +00001847 if (rib->type != type)
1848 continue;
1849 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001850 {
1851 same = rib;
1852 break;
1853 }
hassoebf1ead2005-09-21 14:58:20 +00001854 /* Duplicate connected route comes in. */
1855 else if ((nexthop = rib->nexthop) &&
1856 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001857 nexthop->ifindex == ifindex &&
1858 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001859 {
1860 rib->refcnt++;
1861 return 0 ;
1862 }
paul718e3742002-12-13 20:15:29 +00001863 }
1864
1865 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001866 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001867 rib->type = type;
1868 rib->distance = distance;
1869 rib->flags = flags;
1870 rib->metric = metric;
Feng Lu0d0686f2015-05-22 11:40:02 +02001871 rib->vrf_id = vrf_id;
1872 rib->table = table_id;
paul718e3742002-12-13 20:15:29 +00001873 rib->nexthop_num = 0;
1874 rib->uptime = time (NULL);
1875
1876 /* Nexthop settings. */
1877 if (gate)
1878 {
1879 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001880 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001881 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001882 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001883 }
1884 else
1885 nexthop_ifindex_add (rib, ifindex);
1886
1887 /* If this route is kernel route, set FIB flag to the route. */
1888 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1889 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1890 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1891
1892 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001893 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001894 zlog_debug ("%s: calling rib_addnode (%p, %p)",
1895 __func__, (void *)rn, (void *)rib);
paul718e3742002-12-13 20:15:29 +00001896 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001897
paul718e3742002-12-13 20:15:29 +00001898 /* Free implicit route.*/
1899 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001900 {
1901 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001902 zlog_debug ("%s: calling rib_delnode (%p, %p)",
1903 __func__, (void *)rn, (void *)rib);
paul4d38fdb2005-04-28 17:35:14 +00001904 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001905 }
paul4d38fdb2005-04-28 17:35:14 +00001906
1907 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001908 return 0;
1909}
1910
Denis Ovsienkodc958242007-08-13 16:03:06 +00001911/* This function dumps the contents of a given RIB entry into
1912 * standard debug log. Calling function name and IP prefix in
1913 * question are passed as 1st and 2nd arguments.
1914 */
1915
David Lamparterf7bf4152013-10-22 17:10:21 +00001916void _rib_dump (const char * func,
1917 union prefix46constptr pp, const struct rib * rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001918{
David Lamparterf7bf4152013-10-22 17:10:21 +00001919 const struct prefix *p = pp.p;
Timo Teräsbe6335d2015-05-23 11:08:41 +03001920 char straddr[PREFIX_STRLEN];
Christian Frankefa713d92013-07-05 15:35:37 +00001921 struct nexthop *nexthop, *tnexthop;
1922 int recursing;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001923
Feng Lu0d0686f2015-05-22 11:40:02 +02001924 zlog_debug ("%s: dumping RIB entry %p for %s vrf %u", func, (void *)rib,
1925 prefix2str(p, straddr, sizeof(straddr)), rib->vrf_id);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001926 zlog_debug
1927 (
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001928 "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
Denis Ovsienkodc958242007-08-13 16:03:06 +00001929 func,
1930 rib->refcnt,
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001931 (unsigned long) rib->uptime,
Denis Ovsienkodc958242007-08-13 16:03:06 +00001932 rib->type,
1933 rib->table
1934 );
1935 zlog_debug
1936 (
1937 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1938 func,
1939 rib->metric,
1940 rib->distance,
1941 rib->flags,
1942 rib->status
1943 );
1944 zlog_debug
1945 (
1946 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1947 func,
1948 rib->nexthop_num,
1949 rib->nexthop_active_num,
1950 rib->nexthop_fib_num
1951 );
Vincent Bernatfed643f2012-10-23 16:00:42 +00001952
Christian Frankefa713d92013-07-05 15:35:37 +00001953 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1954 {
Vincent Bernatfed643f2012-10-23 16:00:42 +00001955 inet_ntop (p->family, &nexthop->gate, straddr, INET6_ADDRSTRLEN);
Christian Frankefa713d92013-07-05 15:35:37 +00001956 zlog_debug
1957 (
1958 "%s: %s %s with flags %s%s%s",
1959 func,
1960 (recursing ? " NH" : "NH"),
1961 straddr,
1962 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1963 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1964 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1965 );
1966 }
Denis Ovsienkodc958242007-08-13 16:03:06 +00001967 zlog_debug ("%s: dump complete", func);
1968}
1969
1970/* This is an exported helper to rtm_read() to dump the strange
1971 * RIB entry found by rib_lookup_ipv4_route()
1972 */
1973
1974void rib_lookup_and_dump (struct prefix_ipv4 * p)
1975{
1976 struct route_table *table;
1977 struct route_node *rn;
1978 struct rib *rib;
1979 char prefix_buf[INET_ADDRSTRLEN];
1980
1981 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02001982 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001983 if (! table)
1984 {
Feng Lu41f44a22015-05-22 11:39:56 +02001985 zlog_err ("%s: zebra_vrf_table() returned NULL", __func__);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001986 return;
1987 }
1988
Denis Ovsienkodc958242007-08-13 16:03:06 +00001989 /* Scan the RIB table for exactly matching RIB entry. */
1990 rn = route_node_lookup (table, (struct prefix *) p);
1991
1992 /* No route for this prefix. */
1993 if (! rn)
1994 {
Timo Teräsbe6335d2015-05-23 11:08:41 +03001995 zlog_debug ("%s: lookup failed for %s", __func__,
1996 prefix2str((struct prefix*) p, prefix_buf, sizeof(prefix_buf)));
Denis Ovsienkodc958242007-08-13 16:03:06 +00001997 return;
1998 }
1999
2000 /* Unlock node. */
2001 route_unlock_node (rn);
2002
2003 /* let's go */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002004 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00002005 {
2006 zlog_debug
2007 (
2008 "%s: rn %p, rib %p: %s, %s",
2009 __func__,
David Lampartereed3c482015-03-03 08:51:53 +01002010 (void *)rn,
2011 (void *)rib,
Denis Ovsienkodc958242007-08-13 16:03:06 +00002012 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
2013 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
2014 );
David Lamparterf7bf4152013-10-22 17:10:21 +00002015 rib_dump (p, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002016 }
2017}
2018
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002019/* Check if requested address assignment will fail due to another
2020 * route being installed by zebra in FIB already. Take necessary
2021 * actions, if needed: remove such a route from FIB and deSELECT
2022 * corresponding RIB entry. Then put affected RN into RIBQ head.
2023 */
2024void rib_lookup_and_pushup (struct prefix_ipv4 * p)
2025{
2026 struct route_table *table;
2027 struct route_node *rn;
2028 struct rib *rib;
2029 unsigned changed = 0;
2030
Feng Lu41f44a22015-05-22 11:39:56 +02002031 if (NULL == (table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT)))
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002032 {
Feng Lu41f44a22015-05-22 11:39:56 +02002033 zlog_err ("%s: zebra_vrf_table() returned NULL", __func__);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002034 return;
2035 }
2036
2037 /* No matches would be the simplest case. */
2038 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
2039 return;
2040
2041 /* Unlock node. */
2042 route_unlock_node (rn);
2043
2044 /* Check all RIB entries. In case any changes have to be done, requeue
2045 * the RN into RIBQ head. If the routing message about the new connected
2046 * route (generated by the IP address we are going to assign very soon)
2047 * comes before the RIBQ is processed, the new RIB entry will join
2048 * RIBQ record already on head. This is necessary for proper revalidation
2049 * of the rest of the RIB.
2050 */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002051 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002052 {
2053 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
2054 ! RIB_SYSTEM_ROUTE (rib))
2055 {
2056 changed = 1;
2057 if (IS_ZEBRA_DEBUG_RIB)
2058 {
Timo Teräsbe6335d2015-05-23 11:08:41 +03002059 char buf[PREFIX_STRLEN];
2060 zlog_debug ("%s: freeing way for connected prefix %s", __func__,
2061 prefix2str(&rn->p, buf, sizeof(buf)));
David Lamparterf7bf4152013-10-22 17:10:21 +00002062 rib_dump (&rn->p, rib);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002063 }
2064 rib_uninstall (rn, rib);
2065 }
2066 }
2067 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002068 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002069}
2070
paul718e3742002-12-13 20:15:29 +00002071int
G.Balajicddf3912011-11-26 21:59:32 +04002072rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002073{
2074 struct route_table *table;
2075 struct route_node *rn;
2076 struct rib *same;
2077 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00002078
paul718e3742002-12-13 20:15:29 +00002079 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02002080 table = zebra_vrf_table (AFI_IP, safi, rib->vrf_id);
paul718e3742002-12-13 20:15:29 +00002081 if (! table)
2082 return 0;
G.Balajicddf3912011-11-26 21:59:32 +04002083
paul718e3742002-12-13 20:15:29 +00002084 /* Make it sure prefixlen is applied to the prefix. */
2085 apply_mask_ipv4 (p);
2086
2087 /* Set default distance by route type. */
2088 if (rib->distance == 0)
2089 {
2090 rib->distance = route_info[rib->type].distance;
2091
2092 /* iBGP distance is 200. */
2093 if (rib->type == ZEBRA_ROUTE_BGP
2094 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
2095 rib->distance = 200;
2096 }
2097
2098 /* Lookup route node.*/
2099 rn = route_node_get (table, (struct prefix *) p);
2100
2101 /* If same type of route are installed, treat it as a implicit
2102 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002103 RNODE_FOREACH_RIB (rn, same)
paul718e3742002-12-13 20:15:29 +00002104 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00002105 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00002106 continue;
2107
paul718e3742002-12-13 20:15:29 +00002108 if (same->type == rib->type && same->table == rib->table
2109 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00002110 break;
paul718e3742002-12-13 20:15:29 +00002111 }
paul4d38fdb2005-04-28 17:35:14 +00002112
paul718e3742002-12-13 20:15:29 +00002113 /* If this route is kernel route, set FIB flag to the route. */
2114 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
2115 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2116 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2117
2118 /* Link new rib to node.*/
2119 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002120 if (IS_ZEBRA_DEBUG_RIB)
2121 {
2122 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01002123 __func__, (void *)rn, (void *)rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00002124 rib_dump (p, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002125 }
paul718e3742002-12-13 20:15:29 +00002126
paul718e3742002-12-13 20:15:29 +00002127 /* Free implicit route.*/
2128 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00002129 {
2130 if (IS_ZEBRA_DEBUG_RIB)
2131 {
2132 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01002133 __func__, (void *)rn, (void *)same);
David Lamparterf7bf4152013-10-22 17:10:21 +00002134 rib_dump (p, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002135 }
paul4d38fdb2005-04-28 17:35:14 +00002136 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002137 }
paul4d38fdb2005-04-28 17:35:14 +00002138
2139 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002140 return 0;
2141}
2142
hassoebf1ead2005-09-21 14:58:20 +00002143/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002144int
2145rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Feng Lu0d0686f2015-05-22 11:40:02 +02002146 struct in_addr *gate, unsigned int ifindex, vrf_id_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002147{
2148 struct route_table *table;
2149 struct route_node *rn;
2150 struct rib *rib;
2151 struct rib *fib = NULL;
2152 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002153 struct nexthop *nexthop, *tnexthop;
2154 int recursing;
Timo Teräsbe6335d2015-05-23 11:08:41 +03002155 char buf1[PREFIX_STRLEN];
Stephen Hemminger81cce012009-04-28 14:28:00 -07002156 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002157
2158 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02002159 table = zebra_vrf_table (AFI_IP, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002160 if (! table)
2161 return 0;
2162
2163 /* Apply mask. */
2164 apply_mask_ipv4 (p);
2165
Christian Frankeb52aef12013-11-27 17:06:15 +00002166 if (IS_ZEBRA_DEBUG_KERNEL)
2167 {
2168 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002169 zlog_debug ("rib_delete_ipv4(): route delete %s vrf %u via %s ifindex %d",
2170 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Christian Frankeb52aef12013-11-27 17:06:15 +00002171 inet_ntoa (*gate),
2172 ifindex);
2173 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002174 zlog_debug ("rib_delete_ipv4(): route delete %s vrf %u ifindex %d",
2175 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Christian Frankeb52aef12013-11-27 17:06:15 +00002176 ifindex);
2177 }
paul5ec90d22003-06-19 01:41:37 +00002178
paul718e3742002-12-13 20:15:29 +00002179 /* Lookup route node. */
2180 rn = route_node_lookup (table, (struct prefix *) p);
2181 if (! rn)
2182 {
2183 if (IS_ZEBRA_DEBUG_KERNEL)
2184 {
2185 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002186 zlog_debug ("route %s vrf %u via %s ifindex %d doesn't exist in rib",
2187 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002188 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002189 ifindex);
2190 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002191 zlog_debug ("route %s vrf %u ifindex %d doesn't exist in rib",
2192 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002193 ifindex);
2194 }
2195 return ZEBRA_ERR_RTNOEXIST;
2196 }
2197
2198 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002199 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002200 {
Paul Jakma6d691122006-07-27 21:49:00 +00002201 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2202 continue;
2203
paul718e3742002-12-13 20:15:29 +00002204 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2205 fib = rib;
2206
hassoebf1ead2005-09-21 14:58:20 +00002207 if (rib->type != type)
2208 continue;
2209 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002210 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002211 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002212 if (nexthop->ifindex != ifindex)
2213 continue;
hassoebf1ead2005-09-21 14:58:20 +00002214 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002215 {
hassoebf1ead2005-09-21 14:58:20 +00002216 rib->refcnt--;
2217 route_unlock_node (rn);
2218 route_unlock_node (rn);
2219 return 0;
paul718e3742002-12-13 20:15:29 +00002220 }
hassoebf1ead2005-09-21 14:58:20 +00002221 same = rib;
2222 break;
paul718e3742002-12-13 20:15:29 +00002223 }
hassoebf1ead2005-09-21 14:58:20 +00002224 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002225 else
paul5ec90d22003-06-19 01:41:37 +00002226 {
Christian Frankefa713d92013-07-05 15:35:37 +00002227 if (gate == NULL)
2228 {
2229 same = rib;
2230 break;
2231 }
2232 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2233 if (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate))
2234 {
2235 same = rib;
2236 break;
2237 }
2238 if (same)
2239 break;
2240 }
paul718e3742002-12-13 20:15:29 +00002241 }
paul718e3742002-12-13 20:15:29 +00002242 /* If same type of route can't be found and this message is from
2243 kernel. */
2244 if (! same)
2245 {
2246 if (fib && type == ZEBRA_ROUTE_KERNEL)
2247 {
2248 /* Unset flags. */
2249 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2250 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2251
2252 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2253 }
2254 else
2255 {
2256 if (IS_ZEBRA_DEBUG_KERNEL)
2257 {
2258 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002259 zlog_debug ("route %s vrf %u via %s ifindex %d type %d "
2260 "doesn't exist in rib",
2261 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002262 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002263 ifindex,
2264 type);
2265 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002266 zlog_debug ("route %s vrf %u ifindex %d type %d doesn't exist in rib",
2267 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002268 ifindex,
2269 type);
2270 }
2271 route_unlock_node (rn);
2272 return ZEBRA_ERR_RTNOEXIST;
2273 }
2274 }
paul4d38fdb2005-04-28 17:35:14 +00002275
paul718e3742002-12-13 20:15:29 +00002276 if (same)
2277 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002278
paul718e3742002-12-13 20:15:29 +00002279 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002280 return 0;
2281}
David Lamparter6b0655a2014-06-04 06:53:35 +02002282
paul718e3742002-12-13 20:15:29 +00002283/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002284static void
Everton Marques33d86db2014-07-14 11:19:00 -03002285static_install_ipv4 (safi_t safi, struct prefix *p, struct static_ipv4 *si)
paul718e3742002-12-13 20:15:29 +00002286{
2287 struct rib *rib;
2288 struct route_node *rn;
2289 struct route_table *table;
2290
2291 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02002292 table = zebra_vrf_table (AFI_IP, safi, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00002293 if (! table)
2294 return;
2295
2296 /* Lookup existing route */
2297 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002298 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002299 {
2300 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2301 continue;
2302
2303 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2304 break;
2305 }
paul718e3742002-12-13 20:15:29 +00002306
2307 if (rib)
2308 {
2309 /* Same distance static route is there. Update it with new
2310 nexthop. */
paul718e3742002-12-13 20:15:29 +00002311 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002312 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002313 {
2314 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002315 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002316 break;
2317 case STATIC_IPV4_IFNAME:
2318 nexthop_ifname_add (rib, si->gate.ifname);
2319 break;
2320 case STATIC_IPV4_BLACKHOLE:
2321 nexthop_blackhole_add (rib);
2322 break;
paul4d38fdb2005-04-28 17:35:14 +00002323 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002324 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002325 }
2326 else
2327 {
2328 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002329 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2330
paul718e3742002-12-13 20:15:29 +00002331 rib->type = ZEBRA_ROUTE_STATIC;
2332 rib->distance = si->distance;
2333 rib->metric = 0;
Feng Lu0d0686f2015-05-22 11:40:02 +02002334 rib->vrf_id = VRF_DEFAULT;
Nolan Leakeb0145dd2012-09-13 17:17:31 +00002335 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002336 rib->nexthop_num = 0;
2337
2338 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002339 {
2340 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002341 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002342 break;
2343 case STATIC_IPV4_IFNAME:
2344 nexthop_ifname_add (rib, si->gate.ifname);
2345 break;
2346 case STATIC_IPV4_BLACKHOLE:
2347 nexthop_blackhole_add (rib);
2348 break;
2349 }
paul718e3742002-12-13 20:15:29 +00002350
hasso81dfcaa2003-05-25 19:21:25 +00002351 /* Save the flags of this static routes (reject, blackhole) */
2352 rib->flags = si->flags;
2353
paul718e3742002-12-13 20:15:29 +00002354 /* Link this rib to the tree. */
2355 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002356 }
2357}
2358
paula1ac18c2005-06-28 17:17:12 +00002359static int
paul718e3742002-12-13 20:15:29 +00002360static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2361{
2362 if (nexthop->type == NEXTHOP_TYPE_IPV4
2363 && si->type == STATIC_IPV4_GATEWAY
2364 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2365 return 1;
2366 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2367 && si->type == STATIC_IPV4_IFNAME
2368 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2369 return 1;
paul595db7f2003-05-25 21:35:06 +00002370 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2371 && si->type == STATIC_IPV4_BLACKHOLE)
2372 return 1;
paule8e19462006-01-19 20:16:55 +00002373 return 0;
paul718e3742002-12-13 20:15:29 +00002374}
2375
2376/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002377static void
Everton Marques33d86db2014-07-14 11:19:00 -03002378static_uninstall_ipv4 (safi_t safi, struct prefix *p, struct static_ipv4 *si)
paul718e3742002-12-13 20:15:29 +00002379{
2380 struct route_node *rn;
2381 struct rib *rib;
2382 struct nexthop *nexthop;
2383 struct route_table *table;
2384
2385 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02002386 table = zebra_vrf_table (AFI_IP, safi, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00002387 if (! table)
2388 return;
paul4d38fdb2005-04-28 17:35:14 +00002389
paul718e3742002-12-13 20:15:29 +00002390 /* Lookup existing route with type and distance. */
2391 rn = route_node_lookup (table, p);
2392 if (! rn)
2393 return;
2394
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002395 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002396 {
2397 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2398 continue;
2399
2400 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2401 break;
2402 }
paul718e3742002-12-13 20:15:29 +00002403
2404 if (! rib)
2405 {
2406 route_unlock_node (rn);
2407 return;
2408 }
2409
2410 /* Lookup nexthop. */
2411 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2412 if (static_ipv4_nexthop_same (nexthop, si))
2413 break;
2414
2415 /* Can't find nexthop. */
2416 if (! nexthop)
2417 {
2418 route_unlock_node (rn);
2419 return;
2420 }
2421
2422 /* Check nexthop. */
2423 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002424 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002425 else
2426 {
paul6baeb982003-10-28 03:47:15 +00002427 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2428 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002429 nexthop_delete (rib, nexthop);
2430 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002431 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002432 }
paul718e3742002-12-13 20:15:29 +00002433 /* Unlock node. */
2434 route_unlock_node (rn);
2435}
2436
paul718e3742002-12-13 20:15:29 +00002437int
Everton Marques33d86db2014-07-14 11:19:00 -03002438static_add_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate,
2439 const char *ifname, u_char flags, u_char distance,
Feng Lu0d0686f2015-05-22 11:40:02 +02002440 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002441{
2442 u_char type = 0;
2443 struct route_node *rn;
2444 struct static_ipv4 *si;
2445 struct static_ipv4 *pp;
2446 struct static_ipv4 *cp;
2447 struct static_ipv4 *update = NULL;
Feng Lu0d0686f2015-05-22 11:40:02 +02002448 struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
2449 struct route_table *stable = zvrf->stable[AFI_IP][safi];
paul718e3742002-12-13 20:15:29 +00002450
paul718e3742002-12-13 20:15:29 +00002451 if (! stable)
2452 return -1;
2453
2454 /* Lookup static route prefix. */
2455 rn = route_node_get (stable, p);
2456
2457 /* Make flags. */
2458 if (gate)
2459 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002460 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002461 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002462 else
2463 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002464
2465 /* Do nothing if there is a same static route. */
2466 for (si = rn->info; si; si = si->next)
2467 {
2468 if (type == si->type
2469 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2470 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2471 {
2472 if (distance == si->distance)
2473 {
2474 route_unlock_node (rn);
2475 return 0;
2476 }
2477 else
2478 update = si;
2479 }
2480 }
2481
Paul Jakma3c0755d2006-12-08 00:53:14 +00002482 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002483 if (update)
Everton Marques33d86db2014-07-14 11:19:00 -03002484 static_delete_ipv4_safi (safi, p, gate, ifname, update->distance, vrf_id);
paul718e3742002-12-13 20:15:29 +00002485
2486 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002487 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
paul718e3742002-12-13 20:15:29 +00002488
2489 si->type = type;
2490 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002491 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002492
2493 if (gate)
2494 si->gate.ipv4 = *gate;
2495 if (ifname)
2496 si->gate.ifname = XSTRDUP (0, ifname);
2497
2498 /* Add new static route information to the tree with sort by
2499 distance value and gateway address. */
2500 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2501 {
2502 if (si->distance < cp->distance)
2503 break;
2504 if (si->distance > cp->distance)
2505 continue;
2506 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2507 {
2508 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2509 break;
2510 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2511 continue;
2512 }
2513 }
2514
2515 /* Make linked list. */
2516 if (pp)
2517 pp->next = si;
2518 else
2519 rn->info = si;
2520 if (cp)
2521 cp->prev = si;
2522 si->prev = pp;
2523 si->next = cp;
2524
2525 /* Install into rib. */
Everton Marques33d86db2014-07-14 11:19:00 -03002526 static_install_ipv4 (safi, p, si);
paul718e3742002-12-13 20:15:29 +00002527
2528 return 1;
2529}
2530
paul718e3742002-12-13 20:15:29 +00002531int
Everton Marques33d86db2014-07-14 11:19:00 -03002532static_delete_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate,
Feng Lu0d0686f2015-05-22 11:40:02 +02002533 const char *ifname, u_char distance, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002534{
2535 u_char type = 0;
2536 struct route_node *rn;
2537 struct static_ipv4 *si;
2538 struct route_table *stable;
2539
2540 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02002541 stable = zebra_vrf_static_table (AFI_IP, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002542 if (! stable)
2543 return -1;
2544
2545 /* Lookup static route prefix. */
2546 rn = route_node_lookup (stable, p);
2547 if (! rn)
2548 return 0;
2549
2550 /* Make flags. */
2551 if (gate)
2552 type = STATIC_IPV4_GATEWAY;
2553 else if (ifname)
2554 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002555 else
2556 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002557
2558 /* Find same static route is the tree */
2559 for (si = rn->info; si; si = si->next)
2560 if (type == si->type
2561 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2562 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2563 break;
2564
2565 /* Can't find static route. */
2566 if (! si)
2567 {
2568 route_unlock_node (rn);
2569 return 0;
2570 }
2571
2572 /* Install into rib. */
Everton Marques33d86db2014-07-14 11:19:00 -03002573 static_uninstall_ipv4 (safi, p, si);
paul718e3742002-12-13 20:15:29 +00002574
2575 /* Unlink static route from linked list. */
2576 if (si->prev)
2577 si->prev->next = si->next;
2578 else
2579 rn->info = si->next;
2580 if (si->next)
2581 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002582 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002583
2584 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002585 if (ifname)
2586 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002587 XFREE (MTYPE_STATIC_IPV4, si);
2588
paul143a3852003-09-29 20:06:13 +00002589 route_unlock_node (rn);
2590
paul718e3742002-12-13 20:15:29 +00002591 return 1;
2592}
2593
paul718e3742002-12-13 20:15:29 +00002594#ifdef HAVE_IPV6
paul718e3742002-12-13 20:15:29 +00002595int
2596rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
Feng Lu0d0686f2015-05-22 11:40:02 +02002597 struct in6_addr *gate, unsigned int ifindex,
2598 vrf_id_t vrf_id, int table_id,
G.Balajif768f362011-11-26 22:10:39 +04002599 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002600{
2601 struct rib *rib;
2602 struct rib *same = NULL;
2603 struct route_table *table;
2604 struct route_node *rn;
2605 struct nexthop *nexthop;
2606
paul718e3742002-12-13 20:15:29 +00002607 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02002608 table = zebra_vrf_table (AFI_IP6, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002609 if (! table)
2610 return 0;
2611
2612 /* Make sure mask is applied. */
2613 apply_mask_ipv6 (p);
2614
2615 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002616 if (!distance)
2617 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002618
2619 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2620 distance = 200;
2621
paul718e3742002-12-13 20:15:29 +00002622 /* Lookup route node.*/
2623 rn = route_node_get (table, (struct prefix *) p);
2624
2625 /* If same type of route are installed, treat it as a implicit
2626 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002627 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002628 {
Paul Jakma6d691122006-07-27 21:49:00 +00002629 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2630 continue;
2631
hassoebf1ead2005-09-21 14:58:20 +00002632 if (rib->type != type)
2633 continue;
2634 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002635 {
2636 same = rib;
paul718e3742002-12-13 20:15:29 +00002637 break;
2638 }
hassoebf1ead2005-09-21 14:58:20 +00002639 else if ((nexthop = rib->nexthop) &&
2640 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2641 nexthop->ifindex == ifindex)
2642 {
2643 rib->refcnt++;
2644 return 0;
2645 }
paul718e3742002-12-13 20:15:29 +00002646 }
2647
2648 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002649 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2650
paul718e3742002-12-13 20:15:29 +00002651 rib->type = type;
2652 rib->distance = distance;
2653 rib->flags = flags;
2654 rib->metric = metric;
Feng Lu0d0686f2015-05-22 11:40:02 +02002655 rib->vrf_id = vrf_id;
2656 rib->table = table_id;
paul718e3742002-12-13 20:15:29 +00002657 rib->nexthop_num = 0;
2658 rib->uptime = time (NULL);
2659
2660 /* Nexthop settings. */
2661 if (gate)
2662 {
2663 if (ifindex)
2664 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2665 else
2666 nexthop_ipv6_add (rib, gate);
2667 }
2668 else
2669 nexthop_ifindex_add (rib, ifindex);
2670
2671 /* If this route is kernel route, set FIB flag to the route. */
2672 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2673 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2674 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2675
2676 /* Link new rib to node.*/
2677 rib_addnode (rn, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002678 if (IS_ZEBRA_DEBUG_RIB)
2679 {
2680 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01002681 __func__, (void *)rn, (void *)rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00002682 rib_dump (p, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002683 }
paul718e3742002-12-13 20:15:29 +00002684
paul718e3742002-12-13 20:15:29 +00002685 /* Free implicit route.*/
2686 if (same)
Vincent Bernatfed643f2012-10-23 16:00:42 +00002687 {
2688 if (IS_ZEBRA_DEBUG_RIB)
2689 {
2690 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01002691 __func__, (void *)rn, (void *)same);
David Lamparterf7bf4152013-10-22 17:10:21 +00002692 rib_dump (p, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002693 }
paul4d38fdb2005-04-28 17:35:14 +00002694 rib_delnode (rn, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002695 }
paul4d38fdb2005-04-28 17:35:14 +00002696
2697 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002698 return 0;
2699}
2700
hassoebf1ead2005-09-21 14:58:20 +00002701/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002702int
2703rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
Feng Lu0d0686f2015-05-22 11:40:02 +02002704 struct in6_addr *gate, unsigned int ifindex, vrf_id_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002705{
2706 struct route_table *table;
2707 struct route_node *rn;
2708 struct rib *rib;
2709 struct rib *fib = NULL;
2710 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002711 struct nexthop *nexthop, *tnexthop;
2712 int recursing;
Timo Teräsbe6335d2015-05-23 11:08:41 +03002713 char buf1[PREFIX_STRLEN];
Stephen Hemminger81cce012009-04-28 14:28:00 -07002714 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002715
2716 /* Apply mask. */
2717 apply_mask_ipv6 (p);
2718
2719 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02002720 table = zebra_vrf_table (AFI_IP6, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002721 if (! table)
2722 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002723
paul718e3742002-12-13 20:15:29 +00002724 /* Lookup route node. */
2725 rn = route_node_lookup (table, (struct prefix *) p);
2726 if (! rn)
2727 {
2728 if (IS_ZEBRA_DEBUG_KERNEL)
2729 {
2730 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002731 zlog_debug ("route %s vrf %u via %s ifindex %d doesn't exist in rib",
2732 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002733 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002734 ifindex);
2735 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002736 zlog_debug ("route %s vrf %u ifindex %d doesn't exist in rib",
2737 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002738 ifindex);
2739 }
2740 return ZEBRA_ERR_RTNOEXIST;
2741 }
2742
2743 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002744 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002745 {
Paul Jakma6d691122006-07-27 21:49:00 +00002746 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2747 continue;
2748
paul718e3742002-12-13 20:15:29 +00002749 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2750 fib = rib;
2751
hassoebf1ead2005-09-21 14:58:20 +00002752 if (rib->type != type)
2753 continue;
2754 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002755 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002756 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002757 if (nexthop->ifindex != ifindex)
2758 continue;
hassoebf1ead2005-09-21 14:58:20 +00002759 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002760 {
hassoebf1ead2005-09-21 14:58:20 +00002761 rib->refcnt--;
2762 route_unlock_node (rn);
2763 route_unlock_node (rn);
2764 return 0;
paul718e3742002-12-13 20:15:29 +00002765 }
hassoebf1ead2005-09-21 14:58:20 +00002766 same = rib;
2767 break;
paul718e3742002-12-13 20:15:29 +00002768 }
hassoebf1ead2005-09-21 14:58:20 +00002769 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002770 else
2771 {
2772 if (gate == NULL)
2773 {
2774 same = rib;
2775 break;
2776 }
2777 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2778 if (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate))
2779 {
2780 same = rib;
2781 break;
2782 }
2783 if (same)
2784 break;
2785 }
paul718e3742002-12-13 20:15:29 +00002786 }
2787
2788 /* If same type of route can't be found and this message is from
2789 kernel. */
2790 if (! same)
2791 {
2792 if (fib && type == ZEBRA_ROUTE_KERNEL)
2793 {
2794 /* Unset flags. */
2795 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2796 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2797
2798 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2799 }
2800 else
2801 {
2802 if (IS_ZEBRA_DEBUG_KERNEL)
2803 {
2804 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002805 zlog_debug ("route %s vrf %u via %s ifindex %d type %d "
2806 "doesn't exist in rib",
2807 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002808 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002809 ifindex,
2810 type);
2811 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002812 zlog_debug ("route %s vrf %u ifindex %d type %d doesn't exist in rib",
2813 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002814 ifindex,
2815 type);
2816 }
2817 route_unlock_node (rn);
2818 return ZEBRA_ERR_RTNOEXIST;
2819 }
2820 }
2821
2822 if (same)
2823 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002824
paul718e3742002-12-13 20:15:29 +00002825 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002826 return 0;
2827}
David Lamparter6b0655a2014-06-04 06:53:35 +02002828
paul718e3742002-12-13 20:15:29 +00002829/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002830static void
paul718e3742002-12-13 20:15:29 +00002831static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2832{
2833 struct rib *rib;
2834 struct route_table *table;
2835 struct route_node *rn;
2836
2837 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02002838 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00002839 if (! table)
2840 return;
2841
2842 /* Lookup existing route */
2843 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002844 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002845 {
2846 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2847 continue;
2848
2849 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2850 break;
2851 }
paul718e3742002-12-13 20:15:29 +00002852
2853 if (rib)
2854 {
2855 /* Same distance static route is there. Update it with new
2856 nexthop. */
paul718e3742002-12-13 20:15:29 +00002857 route_unlock_node (rn);
2858
2859 switch (si->type)
2860 {
2861 case STATIC_IPV6_GATEWAY:
2862 nexthop_ipv6_add (rib, &si->ipv6);
2863 break;
2864 case STATIC_IPV6_IFNAME:
2865 nexthop_ifname_add (rib, si->ifname);
2866 break;
2867 case STATIC_IPV6_GATEWAY_IFNAME:
2868 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2869 break;
2870 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002871 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002872 }
2873 else
2874 {
2875 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002876 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2877
paul718e3742002-12-13 20:15:29 +00002878 rib->type = ZEBRA_ROUTE_STATIC;
2879 rib->distance = si->distance;
2880 rib->metric = 0;
Feng Lu0d0686f2015-05-22 11:40:02 +02002881 rib->vrf_id = VRF_DEFAULT;
Dinesh G Duttd1b09912014-09-30 12:54:13 -07002882 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002883 rib->nexthop_num = 0;
2884
2885 switch (si->type)
2886 {
2887 case STATIC_IPV6_GATEWAY:
2888 nexthop_ipv6_add (rib, &si->ipv6);
2889 break;
2890 case STATIC_IPV6_IFNAME:
2891 nexthop_ifname_add (rib, si->ifname);
2892 break;
2893 case STATIC_IPV6_GATEWAY_IFNAME:
2894 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2895 break;
2896 }
2897
hasso81dfcaa2003-05-25 19:21:25 +00002898 /* Save the flags of this static routes (reject, blackhole) */
2899 rib->flags = si->flags;
2900
paul718e3742002-12-13 20:15:29 +00002901 /* Link this rib to the tree. */
2902 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002903 }
2904}
2905
paula1ac18c2005-06-28 17:17:12 +00002906static int
paul718e3742002-12-13 20:15:29 +00002907static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2908{
2909 if (nexthop->type == NEXTHOP_TYPE_IPV6
2910 && si->type == STATIC_IPV6_GATEWAY
2911 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2912 return 1;
2913 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2914 && si->type == STATIC_IPV6_IFNAME
2915 && strcmp (nexthop->ifname, si->ifname) == 0)
2916 return 1;
2917 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2918 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2919 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2920 && strcmp (nexthop->ifname, si->ifname) == 0)
2921 return 1;
paule8e19462006-01-19 20:16:55 +00002922 return 0;
paul718e3742002-12-13 20:15:29 +00002923}
2924
paula1ac18c2005-06-28 17:17:12 +00002925static void
paul718e3742002-12-13 20:15:29 +00002926static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2927{
2928 struct route_table *table;
2929 struct route_node *rn;
2930 struct rib *rib;
2931 struct nexthop *nexthop;
2932
2933 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02002934 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00002935 if (! table)
2936 return;
2937
2938 /* Lookup existing route with type and distance. */
2939 rn = route_node_lookup (table, (struct prefix *) p);
2940 if (! rn)
2941 return;
2942
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002943 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002944 {
2945 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2946 continue;
2947
2948 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2949 break;
2950 }
2951
paul718e3742002-12-13 20:15:29 +00002952 if (! rib)
2953 {
2954 route_unlock_node (rn);
2955 return;
2956 }
2957
2958 /* Lookup nexthop. */
2959 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2960 if (static_ipv6_nexthop_same (nexthop, si))
2961 break;
2962
2963 /* Can't find nexthop. */
2964 if (! nexthop)
2965 {
2966 route_unlock_node (rn);
2967 return;
2968 }
2969
2970 /* Check nexthop. */
2971 if (rib->nexthop_num == 1)
2972 {
2973 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002974 }
2975 else
2976 {
paul6baeb982003-10-28 03:47:15 +00002977 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2978 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002979 nexthop_delete (rib, nexthop);
2980 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002981 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002982 }
paul718e3742002-12-13 20:15:29 +00002983 /* Unlock node. */
2984 route_unlock_node (rn);
2985}
2986
2987/* Add static route into static route configuration. */
2988int
2989static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002990 const char *ifname, u_char flags, u_char distance,
Feng Lu0d0686f2015-05-22 11:40:02 +02002991 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002992{
2993 struct route_node *rn;
2994 struct static_ipv6 *si;
2995 struct static_ipv6 *pp;
2996 struct static_ipv6 *cp;
Feng Lu0d0686f2015-05-22 11:40:02 +02002997 struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
2998 struct route_table *stable = zvrf->stable[AFI_IP6][SAFI_UNICAST];
paul718e3742002-12-13 20:15:29 +00002999
paul718e3742002-12-13 20:15:29 +00003000 if (! stable)
3001 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00003002
3003 if (!gate &&
3004 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
3005 return -1;
3006
3007 if (!ifname &&
3008 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
3009 return -1;
paul718e3742002-12-13 20:15:29 +00003010
3011 /* Lookup static route prefix. */
3012 rn = route_node_get (stable, p);
3013
3014 /* Do nothing if there is a same static route. */
3015 for (si = rn->info; si; si = si->next)
3016 {
3017 if (distance == si->distance
3018 && type == si->type
3019 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
3020 && (! ifname || strcmp (ifname, si->ifname) == 0))
3021 {
3022 route_unlock_node (rn);
3023 return 0;
3024 }
3025 }
3026
3027 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07003028 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
paul718e3742002-12-13 20:15:29 +00003029
3030 si->type = type;
3031 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00003032 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00003033
3034 switch (type)
3035 {
3036 case STATIC_IPV6_GATEWAY:
3037 si->ipv6 = *gate;
3038 break;
3039 case STATIC_IPV6_IFNAME:
3040 si->ifname = XSTRDUP (0, ifname);
3041 break;
3042 case STATIC_IPV6_GATEWAY_IFNAME:
3043 si->ipv6 = *gate;
3044 si->ifname = XSTRDUP (0, ifname);
3045 break;
3046 }
3047
3048 /* Add new static route information to the tree with sort by
3049 distance value and gateway address. */
3050 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
3051 {
3052 if (si->distance < cp->distance)
3053 break;
3054 if (si->distance > cp->distance)
3055 continue;
3056 }
3057
3058 /* Make linked list. */
3059 if (pp)
3060 pp->next = si;
3061 else
3062 rn->info = si;
3063 if (cp)
3064 cp->prev = si;
3065 si->prev = pp;
3066 si->next = cp;
3067
3068 /* Install into rib. */
3069 static_install_ipv6 (p, si);
3070
3071 return 1;
3072}
3073
3074/* Delete static route from static route configuration. */
3075int
3076static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
Feng Lu0d0686f2015-05-22 11:40:02 +02003077 const char *ifname, u_char distance, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00003078{
3079 struct route_node *rn;
3080 struct static_ipv6 *si;
3081 struct route_table *stable;
3082
3083 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02003084 stable = zebra_vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +00003085 if (! stable)
3086 return -1;
3087
3088 /* Lookup static route prefix. */
3089 rn = route_node_lookup (stable, p);
3090 if (! rn)
3091 return 0;
3092
3093 /* Find same static route is the tree */
3094 for (si = rn->info; si; si = si->next)
3095 if (distance == si->distance
3096 && type == si->type
3097 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
3098 && (! ifname || strcmp (ifname, si->ifname) == 0))
3099 break;
3100
3101 /* Can't find static route. */
3102 if (! si)
3103 {
3104 route_unlock_node (rn);
3105 return 0;
3106 }
3107
3108 /* Install into rib. */
3109 static_uninstall_ipv6 (p, si);
3110
3111 /* Unlink static route from linked list. */
3112 if (si->prev)
3113 si->prev->next = si->next;
3114 else
3115 rn->info = si->next;
3116 if (si->next)
3117 si->next->prev = si->prev;
3118
3119 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00003120 if (ifname)
3121 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00003122 XFREE (MTYPE_STATIC_IPV6, si);
3123
3124 return 1;
3125}
3126#endif /* HAVE_IPV6 */
David Lamparter6b0655a2014-06-04 06:53:35 +02003127
paul718e3742002-12-13 20:15:29 +00003128/* RIB update function. */
3129void
Feng Lu0d0686f2015-05-22 11:40:02 +02003130rib_update (vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00003131{
3132 struct route_node *rn;
3133 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00003134
Feng Lu0d0686f2015-05-22 11:40:02 +02003135 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +00003136 if (table)
3137 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003138 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003139 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003140
Feng Lu0d0686f2015-05-22 11:40:02 +02003141 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +00003142 if (table)
3143 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003144 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003145 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003146}
3147
David Lamparter6b0655a2014-06-04 06:53:35 +02003148
paul718e3742002-12-13 20:15:29 +00003149/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00003150static void
paul718e3742002-12-13 20:15:29 +00003151rib_weed_table (struct route_table *table)
3152{
3153 struct route_node *rn;
3154 struct rib *rib;
3155 struct rib *next;
3156
3157 if (table)
3158 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003159 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003160 {
Paul Jakma6d691122006-07-27 21:49:00 +00003161 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3162 continue;
3163
paulb21b19c2003-06-15 01:28:29 +00003164 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00003165 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00003166 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003167 }
3168}
3169
3170/* Delete all routes from non main table. */
3171void
paula1ac18c2005-06-28 17:17:12 +00003172rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00003173{
Feng Lu0d0686f2015-05-22 11:40:02 +02003174 vrf_iter_t iter;
3175 struct zebra_vrf *zvrf;
3176
3177 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3178 if ((zvrf = vrf_iter2info (iter)) != NULL)
3179 {
3180 rib_weed_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
3181 rib_weed_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
3182 }
paul718e3742002-12-13 20:15:29 +00003183}
David Lamparter6b0655a2014-06-04 06:53:35 +02003184
Feng Lu0d0686f2015-05-22 11:40:02 +02003185#if 0
paul718e3742002-12-13 20:15:29 +00003186/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00003187static void
paul718e3742002-12-13 20:15:29 +00003188rib_sweep_table (struct route_table *table)
3189{
3190 struct route_node *rn;
3191 struct rib *rib;
3192 struct rib *next;
3193 int ret = 0;
3194
3195 if (table)
3196 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003197 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003198 {
Paul Jakma6d691122006-07-27 21:49:00 +00003199 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3200 continue;
3201
paul718e3742002-12-13 20:15:29 +00003202 if (rib->type == ZEBRA_ROUTE_KERNEL &&
3203 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
3204 {
3205 ret = rib_uninstall_kernel (rn, rib);
3206 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00003207 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003208 }
3209 }
3210}
Feng Lu0d0686f2015-05-22 11:40:02 +02003211#endif
paul718e3742002-12-13 20:15:29 +00003212
3213/* Sweep all RIB tables. */
3214void
paula1ac18c2005-06-28 17:17:12 +00003215rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00003216{
Feng Lu0d0686f2015-05-22 11:40:02 +02003217 vrf_iter_t iter;
3218 struct zebra_vrf *zvrf;
3219
3220 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3221 if ((zvrf = vrf_iter2info (iter)) != NULL)
3222 {
3223 rib_weed_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
3224 rib_weed_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
3225 }
paul718e3742002-12-13 20:15:29 +00003226}
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003227
3228/* Remove specific by protocol routes from 'table'. */
3229static unsigned long
3230rib_score_proto_table (u_char proto, struct route_table *table)
3231{
3232 struct route_node *rn;
3233 struct rib *rib;
3234 struct rib *next;
3235 unsigned long n = 0;
3236
3237 if (table)
3238 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003239 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003240 {
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003241 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3242 continue;
3243 if (rib->type == proto)
3244 {
3245 rib_delnode (rn, rib);
3246 n++;
3247 }
3248 }
3249
3250 return n;
3251}
3252
3253/* Remove specific by protocol routes. */
3254unsigned long
3255rib_score_proto (u_char proto)
3256{
Feng Lu0d0686f2015-05-22 11:40:02 +02003257 vrf_iter_t iter;
3258 struct zebra_vrf *zvrf;
3259 unsigned long cnt = 0;
3260
3261 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3262 if ((zvrf = vrf_iter2info (iter)) != NULL)
3263 cnt += rib_score_proto_table (proto, zvrf->table[AFI_IP][SAFI_UNICAST])
3264 +rib_score_proto_table (proto, zvrf->table[AFI_IP6][SAFI_UNICAST]);
3265
3266 return cnt;
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003267}
3268
paul718e3742002-12-13 20:15:29 +00003269/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00003270static void
paul718e3742002-12-13 20:15:29 +00003271rib_close_table (struct route_table *table)
3272{
3273 struct route_node *rn;
David Lamparter7ce9e6a2015-01-12 07:05:06 +01003274 rib_table_info_t *info = table->info;
paul718e3742002-12-13 20:15:29 +00003275 struct rib *rib;
3276
3277 if (table)
3278 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003279 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00003280 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003281 if (!CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
3282 continue;
3283
David Lamparter7ce9e6a2015-01-12 07:05:06 +01003284 if (info->safi == SAFI_UNICAST)
3285 zfpm_trigger_update (rn, NULL);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00003286
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003287 if (! RIB_SYSTEM_ROUTE (rib))
3288 rib_uninstall_kernel (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00003289 }
paul718e3742002-12-13 20:15:29 +00003290}
3291
3292/* Close all RIB tables. */
3293void
paula1ac18c2005-06-28 17:17:12 +00003294rib_close (void)
paul718e3742002-12-13 20:15:29 +00003295{
Feng Lu0d0686f2015-05-22 11:40:02 +02003296 vrf_iter_t iter;
3297 struct zebra_vrf *zvrf;
3298
3299 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3300 if ((zvrf = vrf_iter2info (iter)) != NULL)
3301 {
3302 rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
3303 rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
3304 }
paul718e3742002-12-13 20:15:29 +00003305}
David Lamparter6b0655a2014-06-04 06:53:35 +02003306
paul718e3742002-12-13 20:15:29 +00003307/* Routing information base initialize. */
3308void
paula1ac18c2005-06-28 17:17:12 +00003309rib_init (void)
paul718e3742002-12-13 20:15:29 +00003310{
paul4d38fdb2005-04-28 17:35:14 +00003311 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00003312}
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003313
3314/*
3315 * vrf_id_get_next
3316 *
3317 * Get the first vrf id that is greater than the given vrf id if any.
3318 *
3319 * Returns TRUE if a vrf id was found, FALSE otherwise.
3320 */
3321static inline int
Feng Lu41f44a22015-05-22 11:39:56 +02003322vrf_id_get_next (vrf_id_t vrf_id, vrf_id_t *next_id_p)
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003323{
Feng Lu41f44a22015-05-22 11:39:56 +02003324 vrf_iter_t iter = vrf_iterator (vrf_id);
3325 struct zebra_vrf *zvrf = vrf_iter2info (iter);
3326
3327 /* The same one ? Then find out the next. */
3328 if (zvrf && (zvrf->vrf_id == vrf_id))
3329 zvrf = vrf_iter2info (vrf_next (iter));
3330
3331 if (zvrf)
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003332 {
Feng Lu41f44a22015-05-22 11:39:56 +02003333 *next_id_p = zvrf->vrf_id;
3334 return 1;
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003335 }
3336
3337 return 0;
3338}
3339
3340/*
3341 * rib_tables_iter_next
3342 *
3343 * Returns the next table in the iteration.
3344 */
3345struct route_table *
3346rib_tables_iter_next (rib_tables_iter_t *iter)
3347{
3348 struct route_table *table;
3349
3350 /*
3351 * Array that helps us go over all AFI/SAFI combinations via one
3352 * index.
3353 */
3354 static struct {
3355 afi_t afi;
3356 safi_t safi;
3357 } afi_safis[] = {
3358 { AFI_IP, SAFI_UNICAST },
3359 { AFI_IP, SAFI_MULTICAST },
3360 { AFI_IP6, SAFI_UNICAST },
3361 { AFI_IP6, SAFI_MULTICAST },
3362 };
3363
3364 table = NULL;
3365
3366 switch (iter->state)
3367 {
3368
3369 case RIB_TABLES_ITER_S_INIT:
3370 iter->vrf_id = 0;
3371 iter->afi_safi_ix = -1;
3372
3373 /* Fall through */
3374
3375 case RIB_TABLES_ITER_S_ITERATING:
3376 iter->afi_safi_ix++;
3377 while (1)
3378 {
3379
3380 while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
3381 {
Feng Lu41f44a22015-05-22 11:39:56 +02003382 table = zebra_vrf_table (afi_safis[iter->afi_safi_ix].afi,
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003383 afi_safis[iter->afi_safi_ix].safi,
3384 iter->vrf_id);
3385 if (table)
3386 break;
3387
3388 iter->afi_safi_ix++;
3389 }
3390
3391 /*
3392 * Found another table in this vrf.
3393 */
3394 if (table)
3395 break;
3396
3397 /*
3398 * Done with all tables in the current vrf, go to the next
3399 * one.
3400 */
3401 if (!vrf_id_get_next (iter->vrf_id, &iter->vrf_id))
3402 break;
3403
3404 iter->afi_safi_ix = 0;
3405 }
3406
3407 break;
3408
3409 case RIB_TABLES_ITER_S_DONE:
3410 return NULL;
3411 }
3412
3413 if (table)
3414 iter->state = RIB_TABLES_ITER_S_ITERATING;
3415 else
3416 iter->state = RIB_TABLES_ITER_S_DONE;
3417
3418 return table;
3419}
Feng Lu41f44a22015-05-22 11:39:56 +02003420
3421/*
3422 * Create a routing table for the specific AFI/SAFI in the given VRF.
3423 */
3424static void
3425zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi)
3426{
3427 rib_table_info_t *info;
3428 struct route_table *table;
3429
3430 assert (!zvrf->table[afi][safi]);
3431
3432 table = route_table_init ();
3433 zvrf->table[afi][safi] = table;
3434
3435 info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
3436 info->zvrf = zvrf;
3437 info->afi = afi;
3438 info->safi = safi;
3439 table->info = info;
3440}
3441
3442/* Allocate new zebra VRF. */
3443struct zebra_vrf *
3444zebra_vrf_alloc (vrf_id_t vrf_id)
3445{
3446 struct zebra_vrf *zvrf;
3447
3448 zvrf = XCALLOC (MTYPE_ZEBRA_VRF, sizeof (struct zebra_vrf));
3449
3450 /* Allocate routing table and static table. */
3451 zebra_vrf_table_create (zvrf, AFI_IP, SAFI_UNICAST);
3452 zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_UNICAST);
3453 zvrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
3454 zvrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
3455 zebra_vrf_table_create (zvrf, AFI_IP, SAFI_MULTICAST);
3456 zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_MULTICAST);
3457 zvrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
3458 zvrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
3459
3460 /* Set VRF ID */
3461 zvrf->vrf_id = vrf_id;
3462
3463 return zvrf;
3464}
3465
3466/* Lookup the routing table in an enabled VRF. */
3467struct route_table *
3468zebra_vrf_table (afi_t afi, safi_t safi, vrf_id_t vrf_id)
3469{
3470 struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);
3471
3472 if (!zvrf)
3473 return NULL;
3474
3475 if (afi >= AFI_MAX || safi >= SAFI_MAX)
3476 return NULL;
3477
3478 return zvrf->table[afi][safi];
3479}
3480
3481/* Lookup the static routing table in a VRF. */
3482struct route_table *
3483zebra_vrf_static_table (afi_t afi, safi_t safi, vrf_id_t vrf_id)
3484{
3485 struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);
3486
3487 if (!zvrf)
3488 return NULL;
3489
3490 if (afi >= AFI_MAX || safi >= SAFI_MAX)
3491 return NULL;
3492
3493 return zvrf->stable[afi][safi];
3494}
3495