blob: 6a54f11bee0c08b72ad1ac51bf8bde64cbc6da16 [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
paul718e3742002-12-13 20:15:29 +0000262struct nexthop *
263nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
264{
265 struct nexthop *nexthop;
266
Stephen Hemminger393deb92008-08-18 14:13:29 -0700267 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000268 nexthop->type = NEXTHOP_TYPE_IPV6;
269 nexthop->gate.ipv6 = *ipv6;
270
271 nexthop_add (rib, nexthop);
272
273 return nexthop;
274}
275
paula1ac18c2005-06-28 17:17:12 +0000276static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000277nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
278 char *ifname)
279{
280 struct nexthop *nexthop;
281
Stephen Hemminger393deb92008-08-18 14:13:29 -0700282 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000283 nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
284 nexthop->gate.ipv6 = *ipv6;
285 nexthop->ifname = XSTRDUP (0, ifname);
286
287 nexthop_add (rib, nexthop);
288
289 return nexthop;
290}
291
paula1ac18c2005-06-28 17:17:12 +0000292static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000293nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
294 unsigned int ifindex)
295{
296 struct nexthop *nexthop;
297
Stephen Hemminger393deb92008-08-18 14:13:29 -0700298 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000299 nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
300 nexthop->gate.ipv6 = *ipv6;
301 nexthop->ifindex = ifindex;
302
303 nexthop_add (rib, nexthop);
304
305 return nexthop;
306}
paul718e3742002-12-13 20:15:29 +0000307
paul595db7f2003-05-25 21:35:06 +0000308struct nexthop *
309nexthop_blackhole_add (struct rib *rib)
310{
311 struct nexthop *nexthop;
312
Stephen Hemminger393deb92008-08-18 14:13:29 -0700313 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul595db7f2003-05-25 21:35:06 +0000314 nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
315 SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
316
317 nexthop_add (rib, nexthop);
318
319 return nexthop;
320}
321
Christian Frankefa713d92013-07-05 15:35:37 +0000322/* This method checks whether a recursive nexthop has at
323 * least one resolved nexthop in the fib.
324 */
325int
326nexthop_has_fib_child(struct nexthop *nexthop)
327{
328 struct nexthop *nh;
329
330 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
331 return 0;
332
333 for (nh = nexthop->resolved; nh; nh = nh->next)
334 if (CHECK_FLAG (nh->flags, NEXTHOP_FLAG_FIB))
335 return 1;
336
337 return 0;
338}
339
paul718e3742002-12-13 20:15:29 +0000340/* If force flag is not set, do not modify falgs at all for uninstall
341 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000342static int
paul718e3742002-12-13 20:15:29 +0000343nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
344 struct route_node *top)
345{
346 struct prefix_ipv4 p;
347 struct route_table *table;
348 struct route_node *rn;
349 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000350 int resolved;
paul718e3742002-12-13 20:15:29 +0000351 struct nexthop *newhop;
Christian Frankefa713d92013-07-05 15:35:37 +0000352 struct nexthop *resolved_hop;
paul718e3742002-12-13 20:15:29 +0000353
354 if (nexthop->type == NEXTHOP_TYPE_IPV4)
355 nexthop->ifindex = 0;
356
357 if (set)
Christian Frankefa713d92013-07-05 15:35:37 +0000358 {
359 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
360 nexthops_free(nexthop->resolved);
361 nexthop->resolved = NULL;
Timo Teräsb11f3b52015-11-02 16:50:07 +0200362 rib->nexthop_mtu = 0;
Christian Frankefa713d92013-07-05 15:35:37 +0000363 }
paul718e3742002-12-13 20:15:29 +0000364
365 /* Make lookup prefix. */
366 memset (&p, 0, sizeof (struct prefix_ipv4));
367 p.family = AF_INET;
368 p.prefixlen = IPV4_MAX_PREFIXLEN;
369 p.prefix = nexthop->gate.ipv4;
370
371 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200372 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, rib->vrf_id);
paul718e3742002-12-13 20:15:29 +0000373 if (! table)
374 return 0;
375
376 rn = route_node_match (table, (struct prefix *) &p);
377 while (rn)
378 {
379 route_unlock_node (rn);
380
David Warda50c1072009-12-03 15:34:39 +0300381 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000382 if (rn == top)
383 return 0;
384
385 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000386 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100387 {
388 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
389 continue;
390 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
391 break;
392 }
paul718e3742002-12-13 20:15:29 +0000393
394 /* If there is no selected route or matched route is EGP, go up
395 tree. */
396 if (! match
397 || match->type == ZEBRA_ROUTE_BGP)
398 {
399 do {
400 rn = rn->parent;
401 } while (rn && rn->info == NULL);
402 if (rn)
403 route_lock_node (rn);
404 }
405 else
406 {
Christian Franke48a53dc2013-07-05 15:35:38 +0000407 /* If the longest prefix match for the nexthop yields
408 * a blackhole, mark it as inactive. */
409 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE)
410 || CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT))
411 return 0;
412
paul718e3742002-12-13 20:15:29 +0000413 if (match->type == ZEBRA_ROUTE_CONNECT)
414 {
415 /* Directly point connected route. */
416 newhop = match->nexthop;
417 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
418 nexthop->ifindex = newhop->ifindex;
419
420 return 1;
421 }
422 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
423 {
Christian Frankefa713d92013-07-05 15:35:37 +0000424 resolved = 0;
paul718e3742002-12-13 20:15:29 +0000425 for (newhop = match->nexthop; newhop; newhop = newhop->next)
426 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
427 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
428 {
429 if (set)
430 {
431 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
Christian Frankefa713d92013-07-05 15:35:37 +0000432
433 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
434 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
Christian Frankec3e6b592013-07-05 15:35:40 +0000435 /* If the resolving route specifies a gateway, use it */
436 if (newhop->type == NEXTHOP_TYPE_IPV4
437 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX
438 || newhop->type == NEXTHOP_TYPE_IPV4_IFNAME)
439 {
440 resolved_hop->type = newhop->type;
441 resolved_hop->gate.ipv4 = newhop->gate.ipv4;
Christian Frankefa713d92013-07-05 15:35:37 +0000442
Christian Frankec3e6b592013-07-05 15:35:40 +0000443 if (newhop->ifindex)
444 {
445 resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
446 resolved_hop->ifindex = newhop->ifindex;
447 }
448 }
Christian Frankefa713d92013-07-05 15:35:37 +0000449
Christian Frankec3e6b592013-07-05 15:35:40 +0000450 /* If the resolving route is an interface route,
451 * it means the gateway we are looking up is connected
452 * to that interface. (The actual network is _not_ onlink).
453 * Therefore, the resolved route should have the original
454 * gateway as nexthop as it is directly connected.
455 *
456 * On Linux, we have to set the onlink netlink flag because
457 * otherwise, the kernel won't accept the route. */
paul718e3742002-12-13 20:15:29 +0000458 if (newhop->type == NEXTHOP_TYPE_IFINDEX
Christian Frankec3e6b592013-07-05 15:35:40 +0000459 || newhop->type == NEXTHOP_TYPE_IFNAME)
460 {
461 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
462 resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
463 resolved_hop->gate.ipv4 = nexthop->gate.ipv4;
464 resolved_hop->ifindex = newhop->ifindex;
465 }
Christian Frankefa713d92013-07-05 15:35:37 +0000466
467 _nexthop_add(&nexthop->resolved, resolved_hop);
paul718e3742002-12-13 20:15:29 +0000468 }
Christian Frankefa713d92013-07-05 15:35:37 +0000469 resolved = 1;
paul718e3742002-12-13 20:15:29 +0000470 }
Timo Teräsb11f3b52015-11-02 16:50:07 +0200471 if (resolved && set)
472 rib->nexthop_mtu = match->mtu;
Christian Frankefa713d92013-07-05 15:35:37 +0000473 return resolved;
paul718e3742002-12-13 20:15:29 +0000474 }
475 else
476 {
477 return 0;
478 }
479 }
480 }
481 return 0;
482}
483
paul718e3742002-12-13 20:15:29 +0000484/* 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}
paul718e3742002-12-13 20:15:29 +0000618
619struct rib *
David Lamparter24480d42015-01-22 19:09:36 +0100620rib_match_ipv4_safi (struct in_addr addr, safi_t safi, int skip_bgp,
Feng Lu0d0686f2015-05-22 11:40:02 +0200621 struct route_node **rn_out, vrf_id_t vrf_id)
Everton Marques3dea1782014-09-22 19:35:51 -0300622{
623 struct route_table *table;
624 struct route_node *rn;
625 struct rib *match;
626 struct nexthop *newhop, *tnewhop;
627 int recursing;
628
629 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200630 table = zebra_vrf_table (AFI_IP, safi, vrf_id);
Everton Marques3dea1782014-09-22 19:35:51 -0300631 if (! table)
632 return 0;
633
634 rn = route_node_match_ipv4 (table, &addr);
635
636 while (rn)
637 {
638 route_unlock_node (rn);
639
640 /* Pick up selected route. */
641 RNODE_FOREACH_RIB (rn, match)
642 {
643 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
644 continue;
645 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
646 break;
647 }
648
649 /* If there is no selected route or matched route is EGP, go up
650 tree. */
Everton Marques83d71122014-09-19 16:39:34 -0300651 if (!match || (skip_bgp && (match->type == ZEBRA_ROUTE_BGP)))
Everton Marques3dea1782014-09-22 19:35:51 -0300652 {
653 do {
654 rn = rn->parent;
655 } while (rn && rn->info == NULL);
656 if (rn)
657 route_lock_node (rn);
658 }
659 else
660 {
David Lamparter24480d42015-01-22 19:09:36 +0100661 if (match->type != ZEBRA_ROUTE_CONNECT)
Everton Marques3dea1782014-09-22 19:35:51 -0300662 {
David Lamparter24480d42015-01-22 19:09:36 +0100663 int found = 0;
Everton Marques3dea1782014-09-22 19:35:51 -0300664 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
665 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
David Lamparter24480d42015-01-22 19:09:36 +0100666 {
667 found = 1;
668 break;
669 }
670 if (!found)
671 return NULL;
Everton Marques3dea1782014-09-22 19:35:51 -0300672 }
David Lamparter24480d42015-01-22 19:09:36 +0100673
674 if (rn_out)
675 *rn_out = rn;
676 return match;
Everton Marques3dea1782014-09-22 19:35:51 -0300677 }
678 }
679 return NULL;
680}
681
682struct rib *
Feng Lu0d0686f2015-05-22 11:40:02 +0200683rib_match_ipv4_multicast (struct in_addr addr, struct route_node **rn_out,
684 vrf_id_t vrf_id)
David Lamparterbd078122015-01-06 19:53:24 +0100685{
686 struct rib *rib = NULL, *mrib = NULL, *urib = NULL;
687 struct route_node *m_rn = NULL, *u_rn = NULL;
688 int skip_bgp = 0; /* bool */
689
690 switch (ipv4_multicast_mode)
691 {
692 case MCAST_MRIB_ONLY:
Feng Lu0d0686f2015-05-22 11:40:02 +0200693 return rib_match_ipv4_safi (addr, SAFI_MULTICAST, skip_bgp, rn_out,
694 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100695 case MCAST_URIB_ONLY:
Feng Lu0d0686f2015-05-22 11:40:02 +0200696 return rib_match_ipv4_safi (addr, SAFI_UNICAST, skip_bgp, rn_out,
697 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100698 case MCAST_NO_CONFIG:
699 case MCAST_MIX_MRIB_FIRST:
Feng Lu0d0686f2015-05-22 11:40:02 +0200700 rib = mrib = rib_match_ipv4_safi (addr, SAFI_MULTICAST, skip_bgp, &m_rn,
701 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100702 if (!mrib)
Feng Lu0d0686f2015-05-22 11:40:02 +0200703 rib = urib = rib_match_ipv4_safi (addr, SAFI_UNICAST, skip_bgp, &u_rn,
704 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100705 break;
706 case MCAST_MIX_DISTANCE:
Feng Lu0d0686f2015-05-22 11:40:02 +0200707 mrib = rib_match_ipv4_safi (addr, SAFI_MULTICAST, skip_bgp, &m_rn,
708 vrf_id);
709 urib = rib_match_ipv4_safi (addr, SAFI_UNICAST, skip_bgp, &u_rn,
710 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100711 if (mrib && urib)
712 rib = urib->distance < mrib->distance ? urib : mrib;
713 else if (mrib)
714 rib = mrib;
715 else if (urib)
716 rib = urib;
717 break;
718 case MCAST_MIX_PFXLEN:
Feng Lu0d0686f2015-05-22 11:40:02 +0200719 mrib = rib_match_ipv4_safi (addr, SAFI_MULTICAST, skip_bgp, &m_rn,
720 vrf_id);
721 urib = rib_match_ipv4_safi (addr, SAFI_UNICAST, skip_bgp, &u_rn,
722 vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +0100723 if (mrib && urib)
724 rib = u_rn->p.prefixlen > m_rn->p.prefixlen ? urib : mrib;
725 else if (mrib)
726 rib = mrib;
727 else if (urib)
728 rib = urib;
729 break;
730 }
731
732 if (rn_out)
733 *rn_out = (rib == mrib) ? m_rn : u_rn;
734
735 if (IS_ZEBRA_DEBUG_RIB)
736 {
737 char buf[BUFSIZ];
738 inet_ntop (AF_INET, &addr, buf, BUFSIZ);
739
Feng Lu0d0686f2015-05-22 11:40:02 +0200740 zlog_debug("%s: %s vrf %u: found %s, using %s",
741 __func__, buf, vrf_id,
David Lamparterbd078122015-01-06 19:53:24 +0100742 mrib ? (urib ? "MRIB+URIB" : "MRIB") :
743 urib ? "URIB" : "nothing",
744 rib == urib ? "URIB" : rib == mrib ? "MRIB" : "none");
745 }
746 return rib;
747}
748
749void
750multicast_mode_ipv4_set (enum multicast_mode mode)
751{
752 if (IS_ZEBRA_DEBUG_RIB)
753 zlog_debug("%s: multicast lookup mode set (%d)", __func__, mode);
754 ipv4_multicast_mode = mode;
755}
756
757enum multicast_mode
758multicast_mode_ipv4_get (void)
759{
760 return ipv4_multicast_mode;
761}
762
763struct rib *
Feng Lu0d0686f2015-05-22 11:40:02 +0200764rib_lookup_ipv4 (struct prefix_ipv4 *p, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000765{
766 struct route_table *table;
767 struct route_node *rn;
768 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000769 struct nexthop *nexthop, *tnexthop;
770 int recursing;
paul718e3742002-12-13 20:15:29 +0000771
772 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200773 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +0000774 if (! table)
775 return 0;
776
777 rn = route_node_lookup (table, (struct prefix *) p);
778
779 /* No route for this prefix. */
780 if (! rn)
781 return NULL;
782
783 /* Unlock node. */
784 route_unlock_node (rn);
785
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000786 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100787 {
788 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
789 continue;
790 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
791 break;
792 }
paul718e3742002-12-13 20:15:29 +0000793
794 if (! match || match->type == ZEBRA_ROUTE_BGP)
795 return NULL;
796
797 if (match->type == ZEBRA_ROUTE_CONNECT)
798 return match;
799
Christian Frankefa713d92013-07-05 15:35:37 +0000800 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +0000801 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
802 return match;
803
804 return NULL;
805}
806
Denis Ovsienkodc958242007-08-13 16:03:06 +0000807/*
808 * This clone function, unlike its original rib_lookup_ipv4(), checks
809 * if specified IPv4 route record (prefix/mask -> gate) exists in
810 * the whole RIB and has ZEBRA_FLAG_SELECTED set.
811 *
812 * Return values:
813 * -1: error
814 * 0: exact match found
815 * 1: a match was found with a different gate
816 * 2: connected route found
817 * 3: no matches found
818 */
819int
Feng Lu0d0686f2015-05-22 11:40:02 +0200820rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate,
821 vrf_id_t vrf_id)
Denis Ovsienkodc958242007-08-13 16:03:06 +0000822{
823 struct route_table *table;
824 struct route_node *rn;
825 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000826 struct nexthop *nexthop, *tnexthop;
827 int recursing;
828 int nexthops_active;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000829
830 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200831 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
Denis Ovsienkodc958242007-08-13 16:03:06 +0000832 if (! table)
833 return ZEBRA_RIB_LOOKUP_ERROR;
834
835 /* Scan the RIB table for exactly matching RIB entry. */
836 rn = route_node_lookup (table, (struct prefix *) p);
837
838 /* No route for this prefix. */
839 if (! rn)
840 return ZEBRA_RIB_NOTFOUND;
841
842 /* Unlock node. */
843 route_unlock_node (rn);
844
845 /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000846 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100847 {
848 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
849 continue;
850 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
851 break;
852 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000853
854 /* None such found :( */
855 if (!match)
856 return ZEBRA_RIB_NOTFOUND;
857
858 if (match->type == ZEBRA_ROUTE_CONNECT)
859 return ZEBRA_RIB_FOUND_CONNECTED;
860
861 /* Ok, we have a cood candidate, let's check it's nexthop list... */
Christian Frankefa713d92013-07-05 15:35:37 +0000862 nexthops_active = 0;
863 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000864 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000865 {
Christian Frankefa713d92013-07-05 15:35:37 +0000866 nexthops_active = 1;
867 if (nexthop->gate.ipv4.s_addr == sockunion2ip (qgate))
868 return ZEBRA_RIB_FOUND_EXACT;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000869 if (IS_ZEBRA_DEBUG_RIB)
Christian Frankefa713d92013-07-05 15:35:37 +0000870 {
871 char gate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
872 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
873 inet_ntop (AF_INET, &sockunion2ip(qgate), qgate_buf, INET_ADDRSTRLEN);
874 zlog_debug ("%s: qgate == %s, %s == %s", __func__,
875 qgate_buf, recursing ? "rgate" : "gate", gate_buf);
876 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000877 }
Christian Frankefa713d92013-07-05 15:35:37 +0000878
879 if (nexthops_active)
880 return ZEBRA_RIB_FOUND_NOGATE;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000881
882 return ZEBRA_RIB_NOTFOUND;
883}
884
paul718e3742002-12-13 20:15:29 +0000885struct rib *
Feng Lu0d0686f2015-05-22 11:40:02 +0200886rib_match_ipv6 (struct in6_addr *addr, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000887{
888 struct prefix_ipv6 p;
889 struct route_table *table;
890 struct route_node *rn;
891 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000892 struct nexthop *newhop, *tnewhop;
893 int recursing;
paul718e3742002-12-13 20:15:29 +0000894
895 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200896 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +0000897 if (! table)
898 return 0;
899
900 memset (&p, 0, sizeof (struct prefix_ipv6));
901 p.family = AF_INET6;
902 p.prefixlen = IPV6_MAX_PREFIXLEN;
903 IPV6_ADDR_COPY (&p.prefix, addr);
904
905 rn = route_node_match (table, (struct prefix *) &p);
906
907 while (rn)
908 {
909 route_unlock_node (rn);
910
911 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000912 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100913 {
914 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
915 continue;
916 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
917 break;
918 }
paul718e3742002-12-13 20:15:29 +0000919
920 /* If there is no selected route or matched route is EGP, go up
921 tree. */
922 if (! match
923 || match->type == ZEBRA_ROUTE_BGP)
924 {
925 do {
926 rn = rn->parent;
927 } while (rn && rn->info == NULL);
928 if (rn)
929 route_lock_node (rn);
930 }
931 else
932 {
933 if (match->type == ZEBRA_ROUTE_CONNECT)
934 /* Directly point connected route. */
935 return match;
936 else
937 {
Christian Frankefa713d92013-07-05 15:35:37 +0000938 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
paul718e3742002-12-13 20:15:29 +0000939 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
940 return match;
941 return NULL;
942 }
943 }
944 }
945 return NULL;
946}
paul718e3742002-12-13 20:15:29 +0000947
Paul Jakma7514fb72007-05-02 16:05:35 +0000948#define RIB_SYSTEM_ROUTE(R) \
949 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
950
Denis Ovsienkodc958242007-08-13 16:03:06 +0000951/* This function verifies reachability of one given nexthop, which can be
952 * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
953 * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
954 * nexthop->ifindex will be updated appropriately as well.
955 * An existing route map can turn (otherwise active) nexthop into inactive, but
956 * not vice versa.
957 *
958 * The return value is the final value of 'ACTIVE' flag.
959 */
960
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300961static unsigned
paul718e3742002-12-13 20:15:29 +0000962nexthop_active_check (struct route_node *rn, struct rib *rib,
963 struct nexthop *nexthop, int set)
964{
Christian Frankef3a17322013-07-05 15:35:41 +0000965 rib_table_info_t *info = rn->table->info;
paul718e3742002-12-13 20:15:29 +0000966 struct interface *ifp;
Paul Jakma7514fb72007-05-02 16:05:35 +0000967 route_map_result_t ret = RMAP_MATCH;
968 extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
969 struct route_map *rmap;
970 int family;
paul718e3742002-12-13 20:15:29 +0000971
Paul Jakma7514fb72007-05-02 16:05:35 +0000972 family = 0;
paul718e3742002-12-13 20:15:29 +0000973 switch (nexthop->type)
974 {
975 case NEXTHOP_TYPE_IFINDEX:
Feng Lu0d0686f2015-05-22 11:40:02 +0200976 ifp = if_lookup_by_index_vrf (nexthop->ifindex, rib->vrf_id);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000977 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000978 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
979 else
980 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
981 break;
paul718e3742002-12-13 20:15:29 +0000982 case NEXTHOP_TYPE_IPV6_IFNAME:
Paul Jakma7514fb72007-05-02 16:05:35 +0000983 family = AFI_IP6;
984 case NEXTHOP_TYPE_IFNAME:
Feng Lu0d0686f2015-05-22 11:40:02 +0200985 ifp = if_lookup_by_name_vrf (nexthop->ifname, rib->vrf_id);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000986 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000987 {
988 if (set)
989 nexthop->ifindex = ifp->ifindex;
990 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
991 }
992 else
993 {
994 if (set)
995 nexthop->ifindex = 0;
996 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
997 }
998 break;
999 case NEXTHOP_TYPE_IPV4:
1000 case NEXTHOP_TYPE_IPV4_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +00001001 family = AFI_IP;
paul718e3742002-12-13 20:15:29 +00001002 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
1003 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1004 else
1005 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1006 break;
paul718e3742002-12-13 20:15:29 +00001007 case NEXTHOP_TYPE_IPV6:
Paul Jakma7514fb72007-05-02 16:05:35 +00001008 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +00001009 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
1010 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1011 else
1012 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1013 break;
1014 case NEXTHOP_TYPE_IPV6_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +00001015 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +00001016 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
1017 {
Feng Lu0d0686f2015-05-22 11:40:02 +02001018 ifp = if_lookup_by_index_vrf (nexthop->ifindex, rib->vrf_id);
Andrew J. Schorr3f087672008-01-08 20:12:46 +00001019 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001020 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1021 else
1022 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1023 }
1024 else
1025 {
1026 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
1027 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1028 else
1029 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1030 }
1031 break;
paul595db7f2003-05-25 21:35:06 +00001032 case NEXTHOP_TYPE_BLACKHOLE:
1033 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1034 break;
paul718e3742002-12-13 20:15:29 +00001035 default:
1036 break;
1037 }
Paul Jakma7514fb72007-05-02 16:05:35 +00001038 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1039 return 0;
1040
Christian Frankef3a17322013-07-05 15:35:41 +00001041 /* XXX: What exactly do those checks do? Do we support
1042 * e.g. IPv4 routes with IPv6 nexthops or vice versa? */
Paul Jakma7514fb72007-05-02 16:05:35 +00001043 if (RIB_SYSTEM_ROUTE(rib) ||
1044 (family == AFI_IP && rn->p.family != AF_INET) ||
1045 (family == AFI_IP6 && rn->p.family != AF_INET6))
1046 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1047
Christian Frankef3a17322013-07-05 15:35:41 +00001048 /* The original code didn't determine the family correctly
1049 * e.g. for NEXTHOP_TYPE_IFINDEX. Retrieve the correct afi
1050 * from the rib_table_info in those cases.
1051 * Possibly it may be better to use only the rib_table_info
1052 * in every case.
1053 */
1054 if (!family)
1055 family = info->afi;
1056
Paul Jakma7514fb72007-05-02 16:05:35 +00001057 rmap = 0;
1058 if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
1059 proto_rm[family][rib->type])
1060 rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
1061 if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
1062 rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
1063 if (rmap) {
Feng Lu1885d0a2015-05-22 11:40:04 +02001064 struct nexthop_vrfid nh_vrf = {nexthop, rib->vrf_id};
1065 ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, &nh_vrf);
Paul Jakma7514fb72007-05-02 16:05:35 +00001066 }
1067
1068 if (ret == RMAP_DENYMATCH)
1069 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
paul718e3742002-12-13 20:15:29 +00001070 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1071}
1072
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001073/* Iterate over all nexthops of the given RIB entry and refresh their
1074 * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
1075 * nexthop is found to toggle the ACTIVE flag, the whole rib structure
Timo Teräs7eb61362015-11-02 16:50:05 +02001076 * is flagged with RIB_ENTRY_CHANGED. The 4th 'set' argument is
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001077 * transparently passed to nexthop_active_check().
1078 *
1079 * Return value is the new number of active nexthops.
1080 */
1081
paula1ac18c2005-06-28 17:17:12 +00001082static int
paul718e3742002-12-13 20:15:29 +00001083nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
1084{
1085 struct nexthop *nexthop;
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001086 unsigned int prev_active, prev_index, new_active;
paul718e3742002-12-13 20:15:29 +00001087
1088 rib->nexthop_active_num = 0;
Timo Teräs7eb61362015-11-02 16:50:05 +02001089 UNSET_FLAG (rib->status, RIB_ENTRY_CHANGED);
paul718e3742002-12-13 20:15:29 +00001090
1091 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001092 {
1093 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001094 prev_index = nexthop->ifindex;
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001095 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
1096 rib->nexthop_active_num++;
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001097 if (prev_active != new_active ||
1098 prev_index != nexthop->ifindex)
Timo Teräs7eb61362015-11-02 16:50:05 +02001099 SET_FLAG (rib->status, RIB_ENTRY_CHANGED);
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001100 }
paul718e3742002-12-13 20:15:29 +00001101 return rib->nexthop_active_num;
1102}
paul6baeb982003-10-28 03:47:15 +00001103
David Lamparter6b0655a2014-06-04 06:53:35 +02001104
paul718e3742002-12-13 20:15:29 +00001105
paula1ac18c2005-06-28 17:17:12 +00001106static void
paul718e3742002-12-13 20:15:29 +00001107rib_install_kernel (struct route_node *rn, struct rib *rib)
1108{
1109 int ret = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001110 struct nexthop *nexthop, *tnexthop;
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001111 rib_table_info_t *info = rn->table->info;
Christian Frankefa713d92013-07-05 15:35:37 +00001112 int recursing;
paul718e3742002-12-13 20:15:29 +00001113
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001114 if (info->safi != SAFI_UNICAST)
1115 {
1116 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1117 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1118 return;
1119 }
1120
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001121 /*
1122 * Make sure we update the FPM any time we send new information to
1123 * the kernel.
1124 */
1125 zfpm_trigger_update (rn, "installing in kernel");
paul718e3742002-12-13 20:15:29 +00001126 switch (PREFIX_FAMILY (&rn->p))
1127 {
1128 case AF_INET:
1129 ret = kernel_add_ipv4 (&rn->p, rib);
1130 break;
1131#ifdef HAVE_IPV6
1132 case AF_INET6:
1133 ret = kernel_add_ipv6 (&rn->p, rib);
1134 break;
1135#endif /* HAVE_IPV6 */
1136 }
1137
Denis Ovsienkodc958242007-08-13 16:03:06 +00001138 /* This condition is never met, if we are using rt_socket.c */
paul718e3742002-12-13 20:15:29 +00001139 if (ret < 0)
1140 {
Christian Frankefa713d92013-07-05 15:35:37 +00001141 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +00001142 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1143 }
1144}
1145
1146/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001147static int
paul718e3742002-12-13 20:15:29 +00001148rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
1149{
1150 int ret = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001151 struct nexthop *nexthop, *tnexthop;
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001152 rib_table_info_t *info = rn->table->info;
Christian Frankefa713d92013-07-05 15:35:37 +00001153 int recursing;
paul718e3742002-12-13 20:15:29 +00001154
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001155 if (info->safi != SAFI_UNICAST)
1156 {
1157 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1158 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1159 return ret;
1160 }
1161
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001162 /*
1163 * Make sure we update the FPM any time we send new information to
1164 * the kernel.
1165 */
1166 zfpm_trigger_update (rn, "uninstalling from kernel");
1167
paul718e3742002-12-13 20:15:29 +00001168 switch (PREFIX_FAMILY (&rn->p))
1169 {
1170 case AF_INET:
1171 ret = kernel_delete_ipv4 (&rn->p, rib);
1172 break;
1173#ifdef HAVE_IPV6
1174 case AF_INET6:
1175 ret = kernel_delete_ipv6 (&rn->p, rib);
1176 break;
1177#endif /* HAVE_IPV6 */
1178 }
1179
Christian Frankefa713d92013-07-05 15:35:37 +00001180 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +00001181 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1182
1183 return ret;
1184}
1185
1186/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001187static void
paul718e3742002-12-13 20:15:29 +00001188rib_uninstall (struct route_node *rn, struct rib *rib)
1189{
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001190 rib_table_info_t *info = rn->table->info;
1191
paul718e3742002-12-13 20:15:29 +00001192 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1193 {
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001194 if (info->safi == SAFI_UNICAST)
1195 zfpm_trigger_update (rn, "rib_uninstall");
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001196
paul718e3742002-12-13 20:15:29 +00001197 redistribute_delete (&rn->p, rib);
1198 if (! RIB_SYSTEM_ROUTE (rib))
1199 rib_uninstall_kernel (rn, rib);
1200 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
1201 }
1202}
1203
Paul Jakma6d691122006-07-27 21:49:00 +00001204static void rib_unlink (struct route_node *, struct rib *);
1205
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001206/*
1207 * rib_can_delete_dest
1208 *
1209 * Returns TRUE if the given dest can be deleted from the table.
1210 */
1211static int
1212rib_can_delete_dest (rib_dest_t *dest)
1213{
1214 if (dest->routes)
1215 {
1216 return 0;
1217 }
1218
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001219 /*
1220 * Don't delete the dest if we have to update the FPM about this
1221 * prefix.
1222 */
1223 if (CHECK_FLAG (dest->flags, RIB_DEST_UPDATE_FPM) ||
1224 CHECK_FLAG (dest->flags, RIB_DEST_SENT_TO_FPM))
1225 return 0;
1226
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001227 return 1;
1228}
1229
1230/*
1231 * rib_gc_dest
1232 *
1233 * Garbage collect the rib dest corresponding to the given route node
1234 * if appropriate.
1235 *
1236 * Returns TRUE if the dest was deleted, FALSE otherwise.
1237 */
1238int
1239rib_gc_dest (struct route_node *rn)
1240{
1241 rib_dest_t *dest;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001242
1243 dest = rib_dest_from_rnode (rn);
1244 if (!dest)
1245 return 0;
1246
1247 if (!rib_can_delete_dest (dest))
1248 return 0;
1249
1250 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001251 rnode_debug (rn, "removing dest from table");
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001252
1253 dest->rnode = NULL;
1254 XFREE (MTYPE_RIB_DEST, dest);
1255 rn->info = NULL;
1256
1257 /*
1258 * Release the one reference that we keep on the route node.
1259 */
1260 route_unlock_node (rn);
1261 return 1;
1262}
1263
paul718e3742002-12-13 20:15:29 +00001264/* Core function for processing routing information base. */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001265static void
1266rib_process (struct route_node *rn)
paul718e3742002-12-13 20:15:29 +00001267{
1268 struct rib *rib;
1269 struct rib *next;
1270 struct rib *fib = NULL;
1271 struct rib *select = NULL;
Paul Jakma6d691122006-07-27 21:49:00 +00001272 struct rib *del = NULL;
pauld753e9e2003-01-22 19:45:50 +00001273 int installed = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001274 struct nexthop *nexthop = NULL, *tnexthop;
1275 int recursing;
Balaji95116332014-10-23 15:25:25 +00001276 rib_table_info_t *info;
1277
paul4d38fdb2005-04-28 17:35:14 +00001278 assert (rn);
Balaji95116332014-10-23 15:25:25 +00001279
1280 info = rn->table->info;
1281
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001282 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00001283 {
paul718e3742002-12-13 20:15:29 +00001284 /* Currently installed rib. */
1285 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Paul Jakma6d691122006-07-27 21:49:00 +00001286 {
1287 assert (fib == NULL);
1288 fib = rib;
1289 }
1290
1291 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1292 * which we need to do do further work with below.
1293 */
1294 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1295 {
1296 if (rib != fib)
1297 {
1298 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001299 rnode_debug (rn, "rn %p, removing rib %p",
1300 (void *)rn, (void *)rib);
1301 rib_unlink (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001302 }
1303 else
1304 del = rib;
1305
1306 continue;
1307 }
paul4d38fdb2005-04-28 17:35:14 +00001308
paul718e3742002-12-13 20:15:29 +00001309 /* Skip unreachable nexthop. */
1310 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +00001311 continue;
paul718e3742002-12-13 20:15:29 +00001312
1313 /* Infinit distance. */
1314 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +00001315 continue;
paul718e3742002-12-13 20:15:29 +00001316
paulaf887b52006-01-18 14:52:52 +00001317 /* Newly selected rib, the common case. */
1318 if (!select)
1319 {
1320 select = rib;
1321 continue;
1322 }
1323
1324 /* filter route selection in following order:
paulaf887b52006-01-18 14:52:52 +00001325 * - connected beats other types
paula8d9c1f2006-01-25 06:31:04 +00001326 * - lower distance beats higher
paulaf887b52006-01-18 14:52:52 +00001327 * - lower metric beats higher for equal distance
1328 * - last, hence oldest, route wins tie break.
1329 */
paula1038a12006-01-30 14:08:51 +00001330
1331 /* Connected routes. Pick the last connected
1332 * route of the set of lowest metric connected routes.
1333 */
paula8d9c1f2006-01-25 06:31:04 +00001334 if (rib->type == ZEBRA_ROUTE_CONNECT)
1335 {
paula1038a12006-01-30 14:08:51 +00001336 if (select->type != ZEBRA_ROUTE_CONNECT
paula8d9c1f2006-01-25 06:31:04 +00001337 || rib->metric <= select->metric)
paula1038a12006-01-30 14:08:51 +00001338 select = rib;
1339 continue;
paula8d9c1f2006-01-25 06:31:04 +00001340 }
1341 else if (select->type == ZEBRA_ROUTE_CONNECT)
1342 continue;
1343
1344 /* higher distance loses */
1345 if (rib->distance > select->distance)
1346 continue;
1347
1348 /* lower wins */
1349 if (rib->distance < select->distance)
1350 {
paulaf887b52006-01-18 14:52:52 +00001351 select = rib;
paula8d9c1f2006-01-25 06:31:04 +00001352 continue;
1353 }
1354
1355 /* metric tie-breaks equal distance */
1356 if (rib->metric <= select->metric)
1357 select = rib;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001358 } /* RNODE_FOREACH_RIB_SAFE */
Denis Ovsienkodc958242007-08-13 16:03:06 +00001359
1360 /* After the cycle is finished, the following pointers will be set:
1361 * select --- the winner RIB entry, if any was found, otherwise NULL
1362 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1363 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1364 * rib --- NULL
1365 */
1366
1367 /* Same RIB entry is selected. Update FIB and finish. */
paul718e3742002-12-13 20:15:29 +00001368 if (select && select == fib)
1369 {
Paul Jakma6d691122006-07-27 21:49:00 +00001370 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001371 rnode_debug (rn, "Updating existing route, select %p, fib %p",
David Lampartereed3c482015-03-03 08:51:53 +01001372 (void *)select, (void *)fib);
Timo Teräs7eb61362015-11-02 16:50:05 +02001373 if (CHECK_FLAG (select->status, RIB_ENTRY_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +00001374 {
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001375 if (info->safi == SAFI_UNICAST)
1376 zfpm_trigger_update (rn, "updating existing route");
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001377
paul4d38fdb2005-04-28 17:35:14 +00001378 redistribute_delete (&rn->p, select);
1379 if (! RIB_SYSTEM_ROUTE (select))
1380 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001381
paul4d38fdb2005-04-28 17:35:14 +00001382 /* Set real nexthop. */
1383 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +00001384
paul4d38fdb2005-04-28 17:35:14 +00001385 if (! RIB_SYSTEM_ROUTE (select))
1386 rib_install_kernel (rn, select);
1387 redistribute_add (&rn->p, select);
1388 }
pauld753e9e2003-01-22 19:45:50 +00001389 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001390 {
1391 /* Housekeeping code to deal with
1392 race conditions in kernel with linux
1393 netlink reporting interface up before IPv4 or IPv6 protocol
1394 is ready to add routes.
1395 This makes sure the routes are IN the kernel.
1396 */
pauld753e9e2003-01-22 19:45:50 +00001397
Christian Frankefa713d92013-07-05 15:35:37 +00001398 for (ALL_NEXTHOPS_RO(select->nexthop, nexthop, tnexthop, recursing))
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001399 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
paul4d38fdb2005-04-28 17:35:14 +00001400 {
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001401 installed = 1;
1402 break;
paul4d38fdb2005-04-28 17:35:14 +00001403 }
1404 if (! installed)
1405 rib_install_kernel (rn, select);
1406 }
Paul Jakma6d691122006-07-27 21:49:00 +00001407 goto end;
paul718e3742002-12-13 20:15:29 +00001408 }
1409
Denis Ovsienkodc958242007-08-13 16:03:06 +00001410 /* At this point we either haven't found the best RIB entry or it is
1411 * different from what we currently intend to flag with SELECTED. In both
1412 * cases, if a RIB block is present in FIB, it should be withdrawn.
1413 */
paul718e3742002-12-13 20:15:29 +00001414 if (fib)
1415 {
Paul Jakma6d691122006-07-27 21:49:00 +00001416 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001417 rnode_debug (rn, "Removing existing route, fib %p", (void *)fib);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001418
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001419 if (info->safi == SAFI_UNICAST)
1420 zfpm_trigger_update (rn, "removing existing route");
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001421
paul718e3742002-12-13 20:15:29 +00001422 redistribute_delete (&rn->p, fib);
1423 if (! RIB_SYSTEM_ROUTE (fib))
1424 rib_uninstall_kernel (rn, fib);
1425 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1426
1427 /* Set real nexthop. */
1428 nexthop_active_update (rn, fib, 1);
1429 }
1430
Denis Ovsienkodc958242007-08-13 16:03:06 +00001431 /* Regardless of some RIB entry being SELECTED or not before, now we can
1432 * tell, that if a new winner exists, FIB is still not updated with this
1433 * data, but ready to be.
1434 */
paul718e3742002-12-13 20:15:29 +00001435 if (select)
1436 {
Paul Jakma6d691122006-07-27 21:49:00 +00001437 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001438 rnode_debug (rn, "Adding route, select %p", (void *)select);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001439
David Lamparter7ce9e6a2015-01-12 07:05:06 +01001440 if (info->safi == SAFI_UNICAST)
1441 zfpm_trigger_update (rn, "new route selected");
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001442
paul718e3742002-12-13 20:15:29 +00001443 /* Set real nexthop. */
1444 nexthop_active_update (rn, select, 1);
1445
1446 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001447 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001448 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1449 redistribute_add (&rn->p, select);
1450 }
paul4d38fdb2005-04-28 17:35:14 +00001451
Paul Jakma6d691122006-07-27 21:49:00 +00001452 /* FIB route was removed, should be deleted */
1453 if (del)
1454 {
1455 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001456 rnode_debug (rn, "Deleting fib %p, rn %p", (void *)del, (void *)rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001457 rib_unlink (rn, del);
1458 }
paul4d38fdb2005-04-28 17:35:14 +00001459
Paul Jakma6d691122006-07-27 21:49:00 +00001460end:
1461 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lampartereed3c482015-03-03 08:51:53 +01001462 rnode_debug (rn, "rn %p dequeued", (void *)rn);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001463
1464 /*
1465 * Check if the dest can be deleted now.
1466 */
1467 rib_gc_dest (rn);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001468}
1469
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001470/* Take a list of route_node structs and return 1, if there was a record
1471 * picked from it and processed by rib_process(). Don't process more,
1472 * than one RN record; operate only in the specified sub-queue.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001473 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001474static unsigned int
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001475process_subq (struct list * subq, u_char qindex)
1476{
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001477 struct listnode *lnode = listhead (subq);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001478 struct route_node *rnode;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001479
1480 if (!lnode)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001481 return 0;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001482
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001483 rnode = listgetdata (lnode);
1484 rib_process (rnode);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001485
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001486 if (rnode->info)
1487 UNSET_FLAG (rib_dest_from_rnode (rnode)->flags, RIB_ROUTE_QUEUED (qindex));
1488
Chris Caputo67b94672009-07-18 04:02:26 +00001489#if 0
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001490 else
1491 {
1492 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1493 __func__, rnode, rnode->lock);
1494 zlog_backtrace(LOG_DEBUG);
1495 }
Chris Caputo67b94672009-07-18 04:02:26 +00001496#endif
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001497 route_unlock_node (rnode);
1498 list_delete_node (subq, lnode);
1499 return 1;
1500}
1501
1502/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1503 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1504 * is pointed to the meta queue structure.
1505 */
1506static wq_item_status
1507meta_queue_process (struct work_queue *dummy, void *data)
1508{
1509 struct meta_queue * mq = data;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001510 unsigned i;
1511
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001512 for (i = 0; i < MQ_SIZE; i++)
1513 if (process_subq (mq->subq[i], i))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001514 {
1515 mq->size--;
1516 break;
1517 }
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001518 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1519}
1520
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001521/*
1522 * Map from rib types to queue type (priority) in meta queue
1523 */
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001524static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
1525 [ZEBRA_ROUTE_SYSTEM] = 4,
1526 [ZEBRA_ROUTE_KERNEL] = 0,
1527 [ZEBRA_ROUTE_CONNECT] = 0,
1528 [ZEBRA_ROUTE_STATIC] = 1,
1529 [ZEBRA_ROUTE_RIP] = 2,
1530 [ZEBRA_ROUTE_RIPNG] = 2,
1531 [ZEBRA_ROUTE_OSPF] = 2,
1532 [ZEBRA_ROUTE_OSPF6] = 2,
1533 [ZEBRA_ROUTE_ISIS] = 2,
1534 [ZEBRA_ROUTE_BGP] = 3,
1535 [ZEBRA_ROUTE_HSLS] = 4,
Paul Jakma57345092011-12-25 17:52:09 +01001536 [ZEBRA_ROUTE_BABEL] = 2,
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001537};
1538
1539/* Look into the RN and queue it into one or more priority queues,
1540 * increasing the size for each data push done.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001541 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001542static void
1543rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001544{
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001545 struct rib *rib;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001546
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001547 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001548 {
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001549 u_char qindex = meta_queue_map[rib->type];
1550
1551 /* Invariant: at this point we always have rn->info set. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001552 if (CHECK_FLAG (rib_dest_from_rnode (rn)->flags,
1553 RIB_ROUTE_QUEUED (qindex)))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001554 {
1555 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lamparter94813742014-04-24 20:22:53 +02001556 rnode_debug (rn, "rn %p is already queued in sub-queue %u",
David Lampartereed3c482015-03-03 08:51:53 +01001557 (void *)rn, qindex);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001558 continue;
1559 }
1560
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001561 SET_FLAG (rib_dest_from_rnode (rn)->flags, RIB_ROUTE_QUEUED (qindex));
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001562 listnode_add (mq->subq[qindex], rn);
1563 route_lock_node (rn);
1564 mq->size++;
1565
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001566 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lamparter94813742014-04-24 20:22:53 +02001567 rnode_debug (rn, "queued rn %p into sub-queue %u",
David Lampartereed3c482015-03-03 08:51:53 +01001568 (void *)rn, qindex);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001569 }
paul4d38fdb2005-04-28 17:35:14 +00001570}
1571
Paul Jakma6d691122006-07-27 21:49:00 +00001572/* Add route_node to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001573static void
Paul Jakma6d691122006-07-27 21:49:00 +00001574rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
paul4d38fdb2005-04-28 17:35:14 +00001575{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001576 assert (zebra && rn);
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001577
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001578 /* Pointless to queue a route_node with no RIB entries to add or remove */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001579 if (!rnode_to_ribs (rn))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001580 {
1581 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
David Lampartereed3c482015-03-03 08:51:53 +01001582 __func__, (void *)rn, rn->lock);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001583 zlog_backtrace(LOG_DEBUG);
1584 return;
1585 }
1586
1587 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lamparter94813742014-04-24 20:22:53 +02001588 rnode_info (rn, "work queue added");
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001589
1590 assert (zebra);
1591
1592 if (zebra->ribq == NULL)
1593 {
1594 zlog_err ("%s: work_queue does not exist!", __func__);
1595 return;
Paul Jakma6d691122006-07-27 21:49:00 +00001596 }
paul4d38fdb2005-04-28 17:35:14 +00001597
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001598 /*
1599 * The RIB queue should normally be either empty or holding the only
1600 * work_queue_item element. In the latter case this element would
1601 * hold a pointer to the meta queue structure, which must be used to
1602 * actually queue the route nodes to process. So create the MQ
1603 * holder, if necessary, then push the work into it in any case.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001604 * This semantics was introduced after 0.99.9 release.
1605 */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001606 if (!zebra->ribq->items->count)
1607 work_queue_add (zebra->ribq, zebra->mq);
1608
1609 rib_meta_queue_add (zebra->mq, rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001610
1611 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lampartereed3c482015-03-03 08:51:53 +01001612 rnode_debug (rn, "rn %p queued", (void *)rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001613
1614 return;
paul4d38fdb2005-04-28 17:35:14 +00001615}
1616
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001617/* Create new meta queue.
1618 A destructor function doesn't seem to be necessary here.
1619 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001620static struct meta_queue *
1621meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001622{
1623 struct meta_queue *new;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001624 unsigned i;
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001625
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001626 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1627 assert(new);
1628
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001629 for (i = 0; i < MQ_SIZE; i++)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001630 {
1631 new->subq[i] = list_new ();
1632 assert(new->subq[i]);
1633 }
1634
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001635 return new;
1636}
1637
paul4d38fdb2005-04-28 17:35:14 +00001638/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001639static void
paul4d38fdb2005-04-28 17:35:14 +00001640rib_queue_init (struct zebra_t *zebra)
1641{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001642 assert (zebra);
1643
paul4d38fdb2005-04-28 17:35:14 +00001644 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001645 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001646 {
Paul Jakma6d691122006-07-27 21:49:00 +00001647 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001648 return;
1649 }
1650
1651 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001652 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001653 zebra->ribq->spec.errorfunc = NULL;
paul4d38fdb2005-04-28 17:35:14 +00001654 /* XXX: TODO: These should be runtime configurable via vty */
1655 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001656 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001657
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001658 if (!(zebra->mq = meta_queue_new ()))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001659 {
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001660 zlog_err ("%s: could not initialise meta queue!", __func__);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001661 return;
1662 }
1663 return;
paul718e3742002-12-13 20:15:29 +00001664}
1665
Paul Jakma6d691122006-07-27 21:49:00 +00001666/* RIB updates are processed via a queue of pointers to route_nodes.
1667 *
1668 * The queue length is bounded by the maximal size of the routing table,
1669 * as a route_node will not be requeued, if already queued.
1670 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001671 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05001672 * state, or static_install_route (when an existing RIB is updated)
Paul Jakma3c0755d2006-12-08 00:53:14 +00001673 * and then submit route_node to queue for best-path selection later.
1674 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001675 *
1676 * Deleted RIBs are reaped during best-path selection.
1677 *
1678 * rib_addnode
1679 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001680 * |-------->| | best RIB, if required
1681 * | |
1682 * static_install->|->rib_addqueue...... -> rib_process
1683 * | |
1684 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001685 * |-> set RIB_ENTRY_REMOVE |
1686 * rib_delnode (RIB freed)
1687 *
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001688 * The 'info' pointer of a route_node points to a rib_dest_t
1689 * ('dest'). Queueing state for a route_node is kept on the dest. The
1690 * dest is created on-demand by rib_link() and is kept around at least
1691 * as long as there are ribs hanging off it (@see rib_gc_dest()).
Paul Jakma6d691122006-07-27 21:49:00 +00001692 *
1693 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1694 *
1695 * - route_nodes: refcounted by:
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001696 * - dest attached to route_node:
1697 * - managed by: rib_link/rib_gc_dest
Paul Jakma6d691122006-07-27 21:49:00 +00001698 * - route_node processing queue
1699 * - managed by: rib_addqueue, rib_process.
1700 *
1701 */
1702
paul718e3742002-12-13 20:15:29 +00001703/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001704static void
Paul Jakma6d691122006-07-27 21:49:00 +00001705rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001706{
1707 struct rib *head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001708 rib_dest_t *dest;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001709
paul4d38fdb2005-04-28 17:35:14 +00001710 assert (rib && rn);
1711
Paul Jakma6d691122006-07-27 21:49:00 +00001712 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001713 rnode_debug (rn, "rn %p, rib %p", (void *)rn, (void *)rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001714
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001715 dest = rib_dest_from_rnode (rn);
1716 if (!dest)
Paul Jakma6d691122006-07-27 21:49:00 +00001717 {
1718 if (IS_ZEBRA_DEBUG_RIB)
David Lamparter94813742014-04-24 20:22:53 +02001719 rnode_debug (rn, "adding dest to table");
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001720
1721 dest = XCALLOC (MTYPE_RIB_DEST, sizeof (rib_dest_t));
1722 route_lock_node (rn); /* rn route table reference */
1723 rn->info = dest;
1724 dest->rnode = rn;
1725 }
1726
1727 head = dest->routes;
1728 if (head)
1729 {
Paul Jakma6d691122006-07-27 21:49:00 +00001730 head->prev = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001731 }
paul718e3742002-12-13 20:15:29 +00001732 rib->next = head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001733 dest->routes = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001734 rib_queue_add (&zebrad, rn);
1735}
1736
1737static void
1738rib_addnode (struct route_node *rn, struct rib *rib)
1739{
1740 /* RIB node has been un-removed before route-node is processed.
1741 * route_node must hence already be on the queue for processing..
1742 */
1743 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1744 {
1745 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001746 rnode_debug (rn, "rn %p, un-removed rib %p", (void *)rn, (void *)rib);
David Lamparter94813742014-04-24 20:22:53 +02001747
Paul Jakma6d691122006-07-27 21:49:00 +00001748 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1749 return;
1750 }
1751 rib_link (rn, rib);
1752}
1753
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001754/*
1755 * rib_unlink
1756 *
1757 * Detach a rib structure from a route_node.
1758 *
1759 * Note that a call to rib_unlink() should be followed by a call to
1760 * rib_gc_dest() at some point. This allows a rib_dest_t that is no
1761 * longer required to be deleted.
1762 */
Paul Jakma6d691122006-07-27 21:49:00 +00001763static void
1764rib_unlink (struct route_node *rn, struct rib *rib)
1765{
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001766 rib_dest_t *dest;
Paul Jakma6d691122006-07-27 21:49:00 +00001767
1768 assert (rn && rib);
1769
1770 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001771 rnode_debug (rn, "rn %p, rib %p", (void *)rn, (void *)rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001772
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001773 dest = rib_dest_from_rnode (rn);
1774
Paul Jakma6d691122006-07-27 21:49:00 +00001775 if (rib->next)
1776 rib->next->prev = rib->prev;
1777
1778 if (rib->prev)
1779 rib->prev->next = rib->next;
1780 else
1781 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001782 dest->routes = rib->next;
Paul Jakma6d691122006-07-27 21:49:00 +00001783 }
1784
1785 /* free RIB and nexthops */
Christian Frankefa713d92013-07-05 15:35:37 +00001786 nexthops_free(rib->nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00001787 XFREE (MTYPE_RIB, rib);
1788
paul718e3742002-12-13 20:15:29 +00001789}
1790
paula1ac18c2005-06-28 17:17:12 +00001791static void
paul718e3742002-12-13 20:15:29 +00001792rib_delnode (struct route_node *rn, struct rib *rib)
1793{
Paul Jakma6d691122006-07-27 21:49:00 +00001794 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001795 rnode_debug (rn, "rn %p, rib %p, removing", (void *)rn, (void *)rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001796 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1797 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001798}
1799
1800int
1801rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001802 struct in_addr *gate, struct in_addr *src,
Feng Lu0d0686f2015-05-22 11:40:02 +02001803 unsigned int ifindex, vrf_id_t vrf_id, int table_id,
Timo Teräsb11f3b52015-11-02 16:50:07 +02001804 u_int32_t metric, u_int32_t mtu, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001805{
1806 struct rib *rib;
1807 struct rib *same = NULL;
1808 struct route_table *table;
1809 struct route_node *rn;
1810 struct nexthop *nexthop;
1811
1812 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02001813 table = zebra_vrf_table (AFI_IP, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00001814 if (! table)
1815 return 0;
1816
1817 /* Make it sure prefixlen is applied to the prefix. */
1818 apply_mask_ipv4 (p);
1819
1820 /* Set default distance by route type. */
1821 if (distance == 0)
1822 {
Balaji.G837d16c2012-09-26 14:09:10 +05301823 if ((unsigned)type >= array_size(route_info))
David Lamparter7052f222009-08-27 00:28:28 +02001824 distance = 150;
1825 else
1826 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00001827
1828 /* iBGP distance is 200. */
1829 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1830 distance = 200;
1831 }
1832
1833 /* Lookup route node.*/
1834 rn = route_node_get (table, (struct prefix *) p);
1835
1836 /* If same type of route are installed, treat it as a implicit
1837 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001838 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00001839 {
Paul Jakma6d691122006-07-27 21:49:00 +00001840 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1841 continue;
1842
hassoebf1ead2005-09-21 14:58:20 +00001843 if (rib->type != type)
1844 continue;
1845 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001846 {
1847 same = rib;
1848 break;
1849 }
hassoebf1ead2005-09-21 14:58:20 +00001850 /* Duplicate connected route comes in. */
1851 else if ((nexthop = rib->nexthop) &&
1852 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001853 nexthop->ifindex == ifindex &&
1854 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001855 {
1856 rib->refcnt++;
1857 return 0 ;
1858 }
paul718e3742002-12-13 20:15:29 +00001859 }
1860
1861 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001862 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001863 rib->type = type;
1864 rib->distance = distance;
1865 rib->flags = flags;
1866 rib->metric = metric;
Timo Teräsb11f3b52015-11-02 16:50:07 +02001867 rib->mtu = mtu;
Feng Lu0d0686f2015-05-22 11:40:02 +02001868 rib->vrf_id = vrf_id;
1869 rib->table = table_id;
paul718e3742002-12-13 20:15:29 +00001870 rib->nexthop_num = 0;
1871 rib->uptime = time (NULL);
1872
1873 /* Nexthop settings. */
1874 if (gate)
1875 {
1876 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001877 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001878 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001879 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001880 }
1881 else
1882 nexthop_ifindex_add (rib, ifindex);
1883
1884 /* If this route is kernel route, set FIB flag to the route. */
1885 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1886 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1887 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1888
1889 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001890 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001891 zlog_debug ("%s: calling rib_addnode (%p, %p)",
1892 __func__, (void *)rn, (void *)rib);
paul718e3742002-12-13 20:15:29 +00001893 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001894
paul718e3742002-12-13 20:15:29 +00001895 /* Free implicit route.*/
1896 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001897 {
1898 if (IS_ZEBRA_DEBUG_RIB)
David Lampartereed3c482015-03-03 08:51:53 +01001899 zlog_debug ("%s: calling rib_delnode (%p, %p)",
1900 __func__, (void *)rn, (void *)rib);
paul4d38fdb2005-04-28 17:35:14 +00001901 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001902 }
paul4d38fdb2005-04-28 17:35:14 +00001903
1904 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001905 return 0;
1906}
1907
Denis Ovsienkodc958242007-08-13 16:03:06 +00001908/* This function dumps the contents of a given RIB entry into
1909 * standard debug log. Calling function name and IP prefix in
1910 * question are passed as 1st and 2nd arguments.
1911 */
1912
David Lamparterf7bf4152013-10-22 17:10:21 +00001913void _rib_dump (const char * func,
1914 union prefix46constptr pp, const struct rib * rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001915{
David Lamparterf7bf4152013-10-22 17:10:21 +00001916 const struct prefix *p = pp.p;
Timo Teräsbe6335d2015-05-23 11:08:41 +03001917 char straddr[PREFIX_STRLEN];
Christian Frankefa713d92013-07-05 15:35:37 +00001918 struct nexthop *nexthop, *tnexthop;
1919 int recursing;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001920
Feng Lu0d0686f2015-05-22 11:40:02 +02001921 zlog_debug ("%s: dumping RIB entry %p for %s vrf %u", func, (void *)rib,
1922 prefix2str(p, straddr, sizeof(straddr)), rib->vrf_id);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001923 zlog_debug
1924 (
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001925 "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
Denis Ovsienkodc958242007-08-13 16:03:06 +00001926 func,
1927 rib->refcnt,
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001928 (unsigned long) rib->uptime,
Denis Ovsienkodc958242007-08-13 16:03:06 +00001929 rib->type,
1930 rib->table
1931 );
1932 zlog_debug
1933 (
1934 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1935 func,
1936 rib->metric,
1937 rib->distance,
1938 rib->flags,
1939 rib->status
1940 );
1941 zlog_debug
1942 (
1943 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1944 func,
1945 rib->nexthop_num,
1946 rib->nexthop_active_num,
1947 rib->nexthop_fib_num
1948 );
Vincent Bernatfed643f2012-10-23 16:00:42 +00001949
Christian Frankefa713d92013-07-05 15:35:37 +00001950 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1951 {
Vincent Bernatfed643f2012-10-23 16:00:42 +00001952 inet_ntop (p->family, &nexthop->gate, straddr, INET6_ADDRSTRLEN);
Christian Frankefa713d92013-07-05 15:35:37 +00001953 zlog_debug
1954 (
1955 "%s: %s %s with flags %s%s%s",
1956 func,
1957 (recursing ? " NH" : "NH"),
1958 straddr,
1959 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1960 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1961 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1962 );
1963 }
Denis Ovsienkodc958242007-08-13 16:03:06 +00001964 zlog_debug ("%s: dump complete", func);
1965}
1966
1967/* This is an exported helper to rtm_read() to dump the strange
1968 * RIB entry found by rib_lookup_ipv4_route()
1969 */
1970
1971void rib_lookup_and_dump (struct prefix_ipv4 * p)
1972{
1973 struct route_table *table;
1974 struct route_node *rn;
1975 struct rib *rib;
1976 char prefix_buf[INET_ADDRSTRLEN];
1977
1978 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02001979 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001980 if (! table)
1981 {
Feng Lu41f44a22015-05-22 11:39:56 +02001982 zlog_err ("%s: zebra_vrf_table() returned NULL", __func__);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001983 return;
1984 }
1985
Denis Ovsienkodc958242007-08-13 16:03:06 +00001986 /* Scan the RIB table for exactly matching RIB entry. */
1987 rn = route_node_lookup (table, (struct prefix *) p);
1988
1989 /* No route for this prefix. */
1990 if (! rn)
1991 {
Timo Teräsbe6335d2015-05-23 11:08:41 +03001992 zlog_debug ("%s: lookup failed for %s", __func__,
1993 prefix2str((struct prefix*) p, prefix_buf, sizeof(prefix_buf)));
Denis Ovsienkodc958242007-08-13 16:03:06 +00001994 return;
1995 }
1996
1997 /* Unlock node. */
1998 route_unlock_node (rn);
1999
2000 /* let's go */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002001 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00002002 {
2003 zlog_debug
2004 (
2005 "%s: rn %p, rib %p: %s, %s",
2006 __func__,
David Lampartereed3c482015-03-03 08:51:53 +01002007 (void *)rn,
2008 (void *)rib,
Denis Ovsienkodc958242007-08-13 16:03:06 +00002009 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
2010 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
2011 );
David Lamparterf7bf4152013-10-22 17:10:21 +00002012 rib_dump (p, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002013 }
2014}
2015
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002016/* Check if requested address assignment will fail due to another
2017 * route being installed by zebra in FIB already. Take necessary
2018 * actions, if needed: remove such a route from FIB and deSELECT
2019 * corresponding RIB entry. Then put affected RN into RIBQ head.
2020 */
2021void rib_lookup_and_pushup (struct prefix_ipv4 * p)
2022{
2023 struct route_table *table;
2024 struct route_node *rn;
2025 struct rib *rib;
2026 unsigned changed = 0;
2027
Feng Lu41f44a22015-05-22 11:39:56 +02002028 if (NULL == (table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT)))
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002029 {
Feng Lu41f44a22015-05-22 11:39:56 +02002030 zlog_err ("%s: zebra_vrf_table() returned NULL", __func__);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002031 return;
2032 }
2033
2034 /* No matches would be the simplest case. */
2035 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
2036 return;
2037
2038 /* Unlock node. */
2039 route_unlock_node (rn);
2040
2041 /* Check all RIB entries. In case any changes have to be done, requeue
2042 * the RN into RIBQ head. If the routing message about the new connected
2043 * route (generated by the IP address we are going to assign very soon)
2044 * comes before the RIBQ is processed, the new RIB entry will join
2045 * RIBQ record already on head. This is necessary for proper revalidation
2046 * of the rest of the RIB.
2047 */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002048 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002049 {
2050 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
2051 ! RIB_SYSTEM_ROUTE (rib))
2052 {
2053 changed = 1;
2054 if (IS_ZEBRA_DEBUG_RIB)
2055 {
Timo Teräsbe6335d2015-05-23 11:08:41 +03002056 char buf[PREFIX_STRLEN];
2057 zlog_debug ("%s: freeing way for connected prefix %s", __func__,
2058 prefix2str(&rn->p, buf, sizeof(buf)));
David Lamparterf7bf4152013-10-22 17:10:21 +00002059 rib_dump (&rn->p, rib);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002060 }
2061 rib_uninstall (rn, rib);
2062 }
2063 }
2064 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002065 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002066}
2067
paul718e3742002-12-13 20:15:29 +00002068int
G.Balajicddf3912011-11-26 21:59:32 +04002069rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002070{
2071 struct route_table *table;
2072 struct route_node *rn;
2073 struct rib *same;
2074 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00002075
paul718e3742002-12-13 20:15:29 +00002076 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02002077 table = zebra_vrf_table (AFI_IP, safi, rib->vrf_id);
paul718e3742002-12-13 20:15:29 +00002078 if (! table)
2079 return 0;
G.Balajicddf3912011-11-26 21:59:32 +04002080
paul718e3742002-12-13 20:15:29 +00002081 /* Make it sure prefixlen is applied to the prefix. */
2082 apply_mask_ipv4 (p);
2083
2084 /* Set default distance by route type. */
2085 if (rib->distance == 0)
2086 {
2087 rib->distance = route_info[rib->type].distance;
2088
2089 /* iBGP distance is 200. */
2090 if (rib->type == ZEBRA_ROUTE_BGP
2091 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
2092 rib->distance = 200;
2093 }
2094
2095 /* Lookup route node.*/
2096 rn = route_node_get (table, (struct prefix *) p);
2097
2098 /* If same type of route are installed, treat it as a implicit
2099 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002100 RNODE_FOREACH_RIB (rn, same)
paul718e3742002-12-13 20:15:29 +00002101 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00002102 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00002103 continue;
2104
paul718e3742002-12-13 20:15:29 +00002105 if (same->type == rib->type && same->table == rib->table
2106 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00002107 break;
paul718e3742002-12-13 20:15:29 +00002108 }
paul4d38fdb2005-04-28 17:35:14 +00002109
paul718e3742002-12-13 20:15:29 +00002110 /* If this route is kernel route, set FIB flag to the route. */
2111 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
2112 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2113 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2114
2115 /* Link new rib to node.*/
2116 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002117 if (IS_ZEBRA_DEBUG_RIB)
2118 {
2119 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01002120 __func__, (void *)rn, (void *)rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00002121 rib_dump (p, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002122 }
paul718e3742002-12-13 20:15:29 +00002123
paul718e3742002-12-13 20:15:29 +00002124 /* Free implicit route.*/
2125 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00002126 {
2127 if (IS_ZEBRA_DEBUG_RIB)
2128 {
2129 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01002130 __func__, (void *)rn, (void *)same);
David Lamparterf7bf4152013-10-22 17:10:21 +00002131 rib_dump (p, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002132 }
paul4d38fdb2005-04-28 17:35:14 +00002133 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002134 }
paul4d38fdb2005-04-28 17:35:14 +00002135
2136 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002137 return 0;
2138}
2139
hassoebf1ead2005-09-21 14:58:20 +00002140/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002141int
2142rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Feng Lu0d0686f2015-05-22 11:40:02 +02002143 struct in_addr *gate, unsigned int ifindex, vrf_id_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002144{
2145 struct route_table *table;
2146 struct route_node *rn;
2147 struct rib *rib;
2148 struct rib *fib = NULL;
2149 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002150 struct nexthop *nexthop, *tnexthop;
2151 int recursing;
Timo Teräsbe6335d2015-05-23 11:08:41 +03002152 char buf1[PREFIX_STRLEN];
Stephen Hemminger81cce012009-04-28 14:28:00 -07002153 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002154
2155 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02002156 table = zebra_vrf_table (AFI_IP, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002157 if (! table)
2158 return 0;
2159
2160 /* Apply mask. */
2161 apply_mask_ipv4 (p);
2162
Christian Frankeb52aef12013-11-27 17:06:15 +00002163 if (IS_ZEBRA_DEBUG_KERNEL)
2164 {
2165 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002166 zlog_debug ("rib_delete_ipv4(): route delete %s vrf %u via %s ifindex %d",
2167 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Christian Frankeb52aef12013-11-27 17:06:15 +00002168 inet_ntoa (*gate),
2169 ifindex);
2170 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002171 zlog_debug ("rib_delete_ipv4(): route delete %s vrf %u ifindex %d",
2172 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Christian Frankeb52aef12013-11-27 17:06:15 +00002173 ifindex);
2174 }
paul5ec90d22003-06-19 01:41:37 +00002175
paul718e3742002-12-13 20:15:29 +00002176 /* Lookup route node. */
2177 rn = route_node_lookup (table, (struct prefix *) p);
2178 if (! rn)
2179 {
2180 if (IS_ZEBRA_DEBUG_KERNEL)
2181 {
2182 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002183 zlog_debug ("route %s vrf %u via %s ifindex %d doesn't exist in rib",
2184 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002185 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002186 ifindex);
2187 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002188 zlog_debug ("route %s vrf %u ifindex %d doesn't exist in rib",
2189 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002190 ifindex);
2191 }
2192 return ZEBRA_ERR_RTNOEXIST;
2193 }
2194
2195 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002196 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002197 {
Paul Jakma6d691122006-07-27 21:49:00 +00002198 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2199 continue;
2200
paul718e3742002-12-13 20:15:29 +00002201 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2202 fib = rib;
2203
hassoebf1ead2005-09-21 14:58:20 +00002204 if (rib->type != type)
2205 continue;
2206 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002207 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002208 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002209 if (nexthop->ifindex != ifindex)
2210 continue;
hassoebf1ead2005-09-21 14:58:20 +00002211 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002212 {
hassoebf1ead2005-09-21 14:58:20 +00002213 rib->refcnt--;
2214 route_unlock_node (rn);
2215 route_unlock_node (rn);
2216 return 0;
paul718e3742002-12-13 20:15:29 +00002217 }
hassoebf1ead2005-09-21 14:58:20 +00002218 same = rib;
2219 break;
paul718e3742002-12-13 20:15:29 +00002220 }
hassoebf1ead2005-09-21 14:58:20 +00002221 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002222 else
paul5ec90d22003-06-19 01:41:37 +00002223 {
Christian Frankefa713d92013-07-05 15:35:37 +00002224 if (gate == NULL)
2225 {
2226 same = rib;
2227 break;
2228 }
2229 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2230 if (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate))
2231 {
2232 same = rib;
2233 break;
2234 }
2235 if (same)
2236 break;
2237 }
paul718e3742002-12-13 20:15:29 +00002238 }
paul718e3742002-12-13 20:15:29 +00002239 /* If same type of route can't be found and this message is from
2240 kernel. */
2241 if (! same)
2242 {
2243 if (fib && type == ZEBRA_ROUTE_KERNEL)
2244 {
2245 /* Unset flags. */
2246 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2247 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2248
2249 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2250 }
2251 else
2252 {
2253 if (IS_ZEBRA_DEBUG_KERNEL)
2254 {
2255 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002256 zlog_debug ("route %s vrf %u via %s ifindex %d type %d "
2257 "doesn't exist in rib",
2258 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002259 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002260 ifindex,
2261 type);
2262 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002263 zlog_debug ("route %s vrf %u ifindex %d type %d doesn't exist in rib",
2264 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002265 ifindex,
2266 type);
2267 }
2268 route_unlock_node (rn);
2269 return ZEBRA_ERR_RTNOEXIST;
2270 }
2271 }
paul4d38fdb2005-04-28 17:35:14 +00002272
paul718e3742002-12-13 20:15:29 +00002273 if (same)
2274 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002275
paul718e3742002-12-13 20:15:29 +00002276 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002277 return 0;
2278}
David Lamparter6b0655a2014-06-04 06:53:35 +02002279
paul718e3742002-12-13 20:15:29 +00002280/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002281static void
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002282static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si)
paul718e3742002-12-13 20:15:29 +00002283{
2284 struct rib *rib;
2285 struct route_node *rn;
2286 struct route_table *table;
2287
2288 /* Lookup table. */
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002289 table = zebra_vrf_table (afi, safi, si->vrf_id);
paul718e3742002-12-13 20:15:29 +00002290 if (! table)
2291 return;
2292
2293 /* Lookup existing route */
2294 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002295 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002296 {
2297 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2298 continue;
2299
2300 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2301 break;
2302 }
paul718e3742002-12-13 20:15:29 +00002303
2304 if (rib)
2305 {
2306 /* Same distance static route is there. Update it with new
2307 nexthop. */
paul718e3742002-12-13 20:15:29 +00002308 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002309 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002310 {
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002311 case STATIC_IPV4_GATEWAY:
2312 nexthop_ipv4_add (rib, &si->addr.ipv4, NULL);
2313 break;
2314 case STATIC_IPV4_IFNAME:
2315 nexthop_ifname_add (rib, si->ifname);
2316 break;
2317 case STATIC_IPV4_BLACKHOLE:
2318 nexthop_blackhole_add (rib);
2319 break;
2320 case STATIC_IPV6_GATEWAY:
2321 nexthop_ipv6_add (rib, &si->addr.ipv6);
2322 break;
2323 case STATIC_IPV6_IFNAME:
2324 nexthop_ifname_add (rib, si->ifname);
2325 break;
2326 case STATIC_IPV6_GATEWAY_IFNAME:
2327 nexthop_ipv6_ifname_add (rib, &si->addr.ipv6, si->ifname);
2328 break;
paul4d38fdb2005-04-28 17:35:14 +00002329 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002330 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002331 }
2332 else
2333 {
2334 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002335 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2336
paul718e3742002-12-13 20:15:29 +00002337 rib->type = ZEBRA_ROUTE_STATIC;
2338 rib->distance = si->distance;
2339 rib->metric = 0;
Feng Lu7aaf4ea2015-05-22 11:40:06 +02002340 rib->vrf_id = si->vrf_id;
Nolan Leakeb0145dd2012-09-13 17:17:31 +00002341 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002342 rib->nexthop_num = 0;
2343
2344 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002345 {
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002346 case STATIC_IPV4_GATEWAY:
2347 nexthop_ipv4_add (rib, &si->addr.ipv4, NULL);
2348 break;
2349 case STATIC_IPV4_IFNAME:
2350 nexthop_ifname_add (rib, si->ifname);
2351 break;
2352 case STATIC_IPV4_BLACKHOLE:
2353 nexthop_blackhole_add (rib);
2354 break;
2355 case STATIC_IPV6_GATEWAY:
2356 nexthop_ipv6_add (rib, &si->addr.ipv6);
2357 break;
2358 case STATIC_IPV6_IFNAME:
2359 nexthop_ifname_add (rib, si->ifname);
2360 break;
2361 case STATIC_IPV6_GATEWAY_IFNAME:
2362 nexthop_ipv6_ifname_add (rib, &si->addr.ipv6, si->ifname);
2363 break;
paul7021c422003-07-15 12:52:22 +00002364 }
paul718e3742002-12-13 20:15:29 +00002365
hasso81dfcaa2003-05-25 19:21:25 +00002366 /* Save the flags of this static routes (reject, blackhole) */
2367 rib->flags = si->flags;
2368
paul718e3742002-12-13 20:15:29 +00002369 /* Link this rib to the tree. */
2370 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002371 }
2372}
2373
paula1ac18c2005-06-28 17:17:12 +00002374static int
Donald Sharpa979ab72015-11-04 13:26:38 -05002375static_nexthop_same (struct nexthop *nexthop, struct static_route *si)
paul718e3742002-12-13 20:15:29 +00002376{
2377 if (nexthop->type == NEXTHOP_TYPE_IPV4
2378 && si->type == STATIC_IPV4_GATEWAY
Donald Sharpd4c27d62015-11-04 13:26:35 -05002379 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->addr.ipv4))
paul718e3742002-12-13 20:15:29 +00002380 return 1;
2381 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2382 && si->type == STATIC_IPV4_IFNAME
Donald Sharpd4c27d62015-11-04 13:26:35 -05002383 && strcmp (nexthop->ifname, si->ifname) == 0)
paul718e3742002-12-13 20:15:29 +00002384 return 1;
paul595db7f2003-05-25 21:35:06 +00002385 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2386 && si->type == STATIC_IPV4_BLACKHOLE)
2387 return 1;
Donald Sharpa979ab72015-11-04 13:26:38 -05002388 if (nexthop->type == NEXTHOP_TYPE_IPV6
2389 && si->type == STATIC_IPV6_GATEWAY
2390 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6))
2391 return 1;
2392 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2393 && si->type == STATIC_IPV6_IFNAME
2394 && strcmp (nexthop->ifname, si->ifname) == 0)
2395 return 1;
2396 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2397 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2398 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6)
2399 && strcmp (nexthop->ifname, si->ifname) == 0)
2400 return 1;
paule8e19462006-01-19 20:16:55 +00002401 return 0;
paul718e3742002-12-13 20:15:29 +00002402}
2403
2404/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002405static void
Donald Sharp949b7192015-11-04 13:26:39 -05002406static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si)
paul718e3742002-12-13 20:15:29 +00002407{
2408 struct route_node *rn;
2409 struct rib *rib;
2410 struct nexthop *nexthop;
2411 struct route_table *table;
2412
2413 /* Lookup table. */
Donald Sharp949b7192015-11-04 13:26:39 -05002414 table = zebra_vrf_table (afi, safi, si->vrf_id);
paul718e3742002-12-13 20:15:29 +00002415 if (! table)
2416 return;
paul4d38fdb2005-04-28 17:35:14 +00002417
paul718e3742002-12-13 20:15:29 +00002418 /* Lookup existing route with type and distance. */
2419 rn = route_node_lookup (table, p);
2420 if (! rn)
2421 return;
2422
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002423 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002424 {
2425 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2426 continue;
2427
2428 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2429 break;
2430 }
paul718e3742002-12-13 20:15:29 +00002431
2432 if (! rib)
2433 {
2434 route_unlock_node (rn);
2435 return;
2436 }
2437
2438 /* Lookup nexthop. */
2439 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Donald Sharpa979ab72015-11-04 13:26:38 -05002440 if (static_nexthop_same (nexthop, si))
paul718e3742002-12-13 20:15:29 +00002441 break;
2442
2443 /* Can't find nexthop. */
2444 if (! nexthop)
2445 {
2446 route_unlock_node (rn);
2447 return;
2448 }
2449
2450 /* Check nexthop. */
2451 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002452 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002453 else
2454 {
paul6baeb982003-10-28 03:47:15 +00002455 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2456 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002457 nexthop_delete (rib, nexthop);
2458 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002459 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002460 }
paul718e3742002-12-13 20:15:29 +00002461 /* Unlock node. */
2462 route_unlock_node (rn);
2463}
2464
paul718e3742002-12-13 20:15:29 +00002465int
Everton Marques33d86db2014-07-14 11:19:00 -03002466static_add_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate,
2467 const char *ifname, u_char flags, u_char distance,
Feng Lu0d0686f2015-05-22 11:40:02 +02002468 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002469{
2470 u_char type = 0;
2471 struct route_node *rn;
Donald Sharpd4c27d62015-11-04 13:26:35 -05002472 struct static_route *si;
2473 struct static_route *pp;
2474 struct static_route *cp;
2475 struct static_route *update = NULL;
Feng Lu0d0686f2015-05-22 11:40:02 +02002476 struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
2477 struct route_table *stable = zvrf->stable[AFI_IP][safi];
paul718e3742002-12-13 20:15:29 +00002478
paul718e3742002-12-13 20:15:29 +00002479 if (! stable)
2480 return -1;
2481
2482 /* Lookup static route prefix. */
2483 rn = route_node_get (stable, p);
2484
2485 /* Make flags. */
2486 if (gate)
2487 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002488 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002489 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002490 else
2491 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002492
2493 /* Do nothing if there is a same static route. */
2494 for (si = rn->info; si; si = si->next)
2495 {
2496 if (type == si->type
Donald Sharpd4c27d62015-11-04 13:26:35 -05002497 && (! gate || IPV4_ADDR_SAME (gate, &si->addr.ipv4))
2498 && (! ifname || strcmp (ifname, si->ifname) == 0))
paul718e3742002-12-13 20:15:29 +00002499 {
2500 if (distance == si->distance)
2501 {
2502 route_unlock_node (rn);
2503 return 0;
2504 }
2505 else
2506 update = si;
2507 }
2508 }
2509
Paul Jakma3c0755d2006-12-08 00:53:14 +00002510 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002511 if (update)
Everton Marques33d86db2014-07-14 11:19:00 -03002512 static_delete_ipv4_safi (safi, p, gate, ifname, update->distance, vrf_id);
paul718e3742002-12-13 20:15:29 +00002513
2514 /* Make new static route structure. */
Donald Sharpd4c27d62015-11-04 13:26:35 -05002515 si = XCALLOC (MTYPE_STATIC_ROUTE, sizeof (struct static_route));
paul718e3742002-12-13 20:15:29 +00002516
2517 si->type = type;
2518 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002519 si->flags = flags;
Feng Lu7aaf4ea2015-05-22 11:40:06 +02002520 si->vrf_id = vrf_id;
paul718e3742002-12-13 20:15:29 +00002521
2522 if (gate)
Donald Sharpd4c27d62015-11-04 13:26:35 -05002523 si->addr.ipv4 = *gate;
paul718e3742002-12-13 20:15:29 +00002524 if (ifname)
Donald Sharpd4c27d62015-11-04 13:26:35 -05002525 si->ifname = XSTRDUP (0, ifname);
paul718e3742002-12-13 20:15:29 +00002526
2527 /* Add new static route information to the tree with sort by
2528 distance value and gateway address. */
2529 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2530 {
2531 if (si->distance < cp->distance)
2532 break;
2533 if (si->distance > cp->distance)
2534 continue;
2535 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2536 {
Donald Sharpd4c27d62015-11-04 13:26:35 -05002537 if (ntohl (si->addr.ipv4.s_addr) < ntohl (cp->addr.ipv4.s_addr))
paul718e3742002-12-13 20:15:29 +00002538 break;
Donald Sharpd4c27d62015-11-04 13:26:35 -05002539 if (ntohl (si->addr.ipv4.s_addr) > ntohl (cp->addr.ipv4.s_addr))
paul718e3742002-12-13 20:15:29 +00002540 continue;
2541 }
2542 }
2543
2544 /* Make linked list. */
2545 if (pp)
2546 pp->next = si;
2547 else
2548 rn->info = si;
2549 if (cp)
2550 cp->prev = si;
2551 si->prev = pp;
2552 si->next = cp;
2553
2554 /* Install into rib. */
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002555 static_install_route (AFI_IP, safi, p, si);
paul718e3742002-12-13 20:15:29 +00002556
2557 return 1;
2558}
2559
paul718e3742002-12-13 20:15:29 +00002560int
Everton Marques33d86db2014-07-14 11:19:00 -03002561static_delete_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate,
Feng Lu0d0686f2015-05-22 11:40:02 +02002562 const char *ifname, u_char distance, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002563{
2564 u_char type = 0;
2565 struct route_node *rn;
Donald Sharpd4c27d62015-11-04 13:26:35 -05002566 struct static_route *si;
paul718e3742002-12-13 20:15:29 +00002567 struct route_table *stable;
2568
2569 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02002570 stable = zebra_vrf_static_table (AFI_IP, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002571 if (! stable)
2572 return -1;
2573
2574 /* Lookup static route prefix. */
2575 rn = route_node_lookup (stable, p);
2576 if (! rn)
2577 return 0;
2578
2579 /* Make flags. */
2580 if (gate)
2581 type = STATIC_IPV4_GATEWAY;
2582 else if (ifname)
2583 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002584 else
2585 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002586
2587 /* Find same static route is the tree */
2588 for (si = rn->info; si; si = si->next)
2589 if (type == si->type
Donald Sharpd4c27d62015-11-04 13:26:35 -05002590 && (! gate || IPV4_ADDR_SAME (gate, &si->addr.ipv4))
2591 && (! ifname || strcmp (ifname, si->ifname) == 0))
paul718e3742002-12-13 20:15:29 +00002592 break;
2593
2594 /* Can't find static route. */
2595 if (! si)
2596 {
2597 route_unlock_node (rn);
2598 return 0;
2599 }
2600
2601 /* Install into rib. */
Donald Sharp949b7192015-11-04 13:26:39 -05002602 static_uninstall_route (AFI_IP, safi, p, si);
paul718e3742002-12-13 20:15:29 +00002603
2604 /* Unlink static route from linked list. */
2605 if (si->prev)
2606 si->prev->next = si->next;
2607 else
2608 rn->info = si->next;
2609 if (si->next)
2610 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002611 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002612
2613 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002614 if (ifname)
Donald Sharpd4c27d62015-11-04 13:26:35 -05002615 XFREE (0, si->ifname);
2616 XFREE (MTYPE_STATIC_ROUTE, si);
paul718e3742002-12-13 20:15:29 +00002617
paul143a3852003-09-29 20:06:13 +00002618 route_unlock_node (rn);
2619
paul718e3742002-12-13 20:15:29 +00002620 return 1;
2621}
2622
paul718e3742002-12-13 20:15:29 +00002623int
2624rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
Feng Lu0d0686f2015-05-22 11:40:02 +02002625 struct in6_addr *gate, unsigned int ifindex,
2626 vrf_id_t vrf_id, int table_id,
Timo Teräsb11f3b52015-11-02 16:50:07 +02002627 u_int32_t metric, u_int32_t mtu, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002628{
2629 struct rib *rib;
2630 struct rib *same = NULL;
2631 struct route_table *table;
2632 struct route_node *rn;
2633 struct nexthop *nexthop;
2634
paul718e3742002-12-13 20:15:29 +00002635 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02002636 table = zebra_vrf_table (AFI_IP6, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002637 if (! table)
2638 return 0;
2639
2640 /* Make sure mask is applied. */
2641 apply_mask_ipv6 (p);
2642
2643 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002644 if (!distance)
2645 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002646
2647 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2648 distance = 200;
2649
paul718e3742002-12-13 20:15:29 +00002650 /* Lookup route node.*/
2651 rn = route_node_get (table, (struct prefix *) p);
2652
2653 /* If same type of route are installed, treat it as a implicit
2654 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002655 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002656 {
Paul Jakma6d691122006-07-27 21:49:00 +00002657 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2658 continue;
2659
hassoebf1ead2005-09-21 14:58:20 +00002660 if (rib->type != type)
2661 continue;
2662 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002663 {
2664 same = rib;
paul718e3742002-12-13 20:15:29 +00002665 break;
2666 }
hassoebf1ead2005-09-21 14:58:20 +00002667 else if ((nexthop = rib->nexthop) &&
2668 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2669 nexthop->ifindex == ifindex)
2670 {
2671 rib->refcnt++;
2672 return 0;
2673 }
paul718e3742002-12-13 20:15:29 +00002674 }
2675
2676 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002677 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2678
paul718e3742002-12-13 20:15:29 +00002679 rib->type = type;
2680 rib->distance = distance;
2681 rib->flags = flags;
2682 rib->metric = metric;
Timo Teräsb11f3b52015-11-02 16:50:07 +02002683 rib->mtu = mtu;
Feng Lu0d0686f2015-05-22 11:40:02 +02002684 rib->vrf_id = vrf_id;
2685 rib->table = table_id;
paul718e3742002-12-13 20:15:29 +00002686 rib->nexthop_num = 0;
2687 rib->uptime = time (NULL);
2688
2689 /* Nexthop settings. */
2690 if (gate)
2691 {
2692 if (ifindex)
2693 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2694 else
2695 nexthop_ipv6_add (rib, gate);
2696 }
2697 else
2698 nexthop_ifindex_add (rib, ifindex);
2699
2700 /* If this route is kernel route, set FIB flag to the route. */
2701 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2702 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2703 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2704
2705 /* Link new rib to node.*/
2706 rib_addnode (rn, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002707 if (IS_ZEBRA_DEBUG_RIB)
2708 {
2709 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01002710 __func__, (void *)rn, (void *)rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00002711 rib_dump (p, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002712 }
paul718e3742002-12-13 20:15:29 +00002713
paul718e3742002-12-13 20:15:29 +00002714 /* Free implicit route.*/
2715 if (same)
Vincent Bernatfed643f2012-10-23 16:00:42 +00002716 {
2717 if (IS_ZEBRA_DEBUG_RIB)
2718 {
2719 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
David Lampartereed3c482015-03-03 08:51:53 +01002720 __func__, (void *)rn, (void *)same);
David Lamparterf7bf4152013-10-22 17:10:21 +00002721 rib_dump (p, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002722 }
paul4d38fdb2005-04-28 17:35:14 +00002723 rib_delnode (rn, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002724 }
paul4d38fdb2005-04-28 17:35:14 +00002725
2726 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002727 return 0;
2728}
2729
hassoebf1ead2005-09-21 14:58:20 +00002730/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002731int
2732rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
Feng Lu0d0686f2015-05-22 11:40:02 +02002733 struct in6_addr *gate, unsigned int ifindex, vrf_id_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002734{
2735 struct route_table *table;
2736 struct route_node *rn;
2737 struct rib *rib;
2738 struct rib *fib = NULL;
2739 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002740 struct nexthop *nexthop, *tnexthop;
2741 int recursing;
Timo Teräsbe6335d2015-05-23 11:08:41 +03002742 char buf1[PREFIX_STRLEN];
Stephen Hemminger81cce012009-04-28 14:28:00 -07002743 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002744
2745 /* Apply mask. */
2746 apply_mask_ipv6 (p);
2747
2748 /* Lookup table. */
Feng Lu0d0686f2015-05-22 11:40:02 +02002749 table = zebra_vrf_table (AFI_IP6, safi, vrf_id);
paul718e3742002-12-13 20:15:29 +00002750 if (! table)
2751 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002752
paul718e3742002-12-13 20:15:29 +00002753 /* Lookup route node. */
2754 rn = route_node_lookup (table, (struct prefix *) p);
2755 if (! rn)
2756 {
2757 if (IS_ZEBRA_DEBUG_KERNEL)
2758 {
2759 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002760 zlog_debug ("route %s vrf %u via %s ifindex %d doesn't exist in rib",
2761 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002762 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002763 ifindex);
2764 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002765 zlog_debug ("route %s vrf %u ifindex %d doesn't exist in rib",
2766 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002767 ifindex);
2768 }
2769 return ZEBRA_ERR_RTNOEXIST;
2770 }
2771
2772 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002773 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002774 {
Paul Jakma6d691122006-07-27 21:49:00 +00002775 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2776 continue;
2777
paul718e3742002-12-13 20:15:29 +00002778 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2779 fib = rib;
2780
hassoebf1ead2005-09-21 14:58:20 +00002781 if (rib->type != type)
2782 continue;
2783 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002784 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002785 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002786 if (nexthop->ifindex != ifindex)
2787 continue;
hassoebf1ead2005-09-21 14:58:20 +00002788 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002789 {
hassoebf1ead2005-09-21 14:58:20 +00002790 rib->refcnt--;
2791 route_unlock_node (rn);
2792 route_unlock_node (rn);
2793 return 0;
paul718e3742002-12-13 20:15:29 +00002794 }
hassoebf1ead2005-09-21 14:58:20 +00002795 same = rib;
2796 break;
paul718e3742002-12-13 20:15:29 +00002797 }
hassoebf1ead2005-09-21 14:58:20 +00002798 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002799 else
2800 {
2801 if (gate == NULL)
2802 {
2803 same = rib;
2804 break;
2805 }
2806 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2807 if (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate))
2808 {
2809 same = rib;
2810 break;
2811 }
2812 if (same)
2813 break;
2814 }
paul718e3742002-12-13 20:15:29 +00002815 }
2816
2817 /* If same type of route can't be found and this message is from
2818 kernel. */
2819 if (! same)
2820 {
2821 if (fib && type == ZEBRA_ROUTE_KERNEL)
2822 {
2823 /* Unset flags. */
2824 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2825 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2826
2827 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2828 }
2829 else
2830 {
2831 if (IS_ZEBRA_DEBUG_KERNEL)
2832 {
2833 if (gate)
Feng Lu0d0686f2015-05-22 11:40:02 +02002834 zlog_debug ("route %s vrf %u via %s ifindex %d type %d "
2835 "doesn't exist in rib",
2836 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002837 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002838 ifindex,
2839 type);
2840 else
Feng Lu0d0686f2015-05-22 11:40:02 +02002841 zlog_debug ("route %s vrf %u ifindex %d type %d doesn't exist in rib",
2842 prefix2str (p, buf1, sizeof(buf1)), vrf_id,
paul718e3742002-12-13 20:15:29 +00002843 ifindex,
2844 type);
2845 }
2846 route_unlock_node (rn);
2847 return ZEBRA_ERR_RTNOEXIST;
2848 }
2849 }
2850
2851 if (same)
2852 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002853
paul718e3742002-12-13 20:15:29 +00002854 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002855 return 0;
2856}
David Lamparter6b0655a2014-06-04 06:53:35 +02002857
paul718e3742002-12-13 20:15:29 +00002858
2859/* Add static route into static route configuration. */
2860int
2861static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002862 const char *ifname, u_char flags, u_char distance,
Feng Lu0d0686f2015-05-22 11:40:02 +02002863 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002864{
2865 struct route_node *rn;
Donald Sharpd4c27d62015-11-04 13:26:35 -05002866 struct static_route *si;
2867 struct static_route *pp;
2868 struct static_route *cp;
Feng Lu0d0686f2015-05-22 11:40:02 +02002869 struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
2870 struct route_table *stable = zvrf->stable[AFI_IP6][SAFI_UNICAST];
paul718e3742002-12-13 20:15:29 +00002871
paul718e3742002-12-13 20:15:29 +00002872 if (! stable)
2873 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00002874
2875 if (!gate &&
2876 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
2877 return -1;
2878
2879 if (!ifname &&
2880 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
2881 return -1;
paul718e3742002-12-13 20:15:29 +00002882
2883 /* Lookup static route prefix. */
2884 rn = route_node_get (stable, p);
2885
2886 /* Do nothing if there is a same static route. */
2887 for (si = rn->info; si; si = si->next)
2888 {
2889 if (distance == si->distance
2890 && type == si->type
Donald Sharpd4c27d62015-11-04 13:26:35 -05002891 && (! gate || IPV6_ADDR_SAME (gate, &si->addr.ipv6))
paul718e3742002-12-13 20:15:29 +00002892 && (! ifname || strcmp (ifname, si->ifname) == 0))
2893 {
2894 route_unlock_node (rn);
2895 return 0;
2896 }
2897 }
2898
2899 /* Make new static route structure. */
Donald Sharpd4c27d62015-11-04 13:26:35 -05002900 si = XCALLOC (MTYPE_STATIC_ROUTE, sizeof (struct static_route));
paul718e3742002-12-13 20:15:29 +00002901
2902 si->type = type;
2903 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002904 si->flags = flags;
Feng Lu7aaf4ea2015-05-22 11:40:06 +02002905 si->vrf_id = vrf_id;
paul718e3742002-12-13 20:15:29 +00002906
2907 switch (type)
2908 {
2909 case STATIC_IPV6_GATEWAY:
Donald Sharpd4c27d62015-11-04 13:26:35 -05002910 si->addr.ipv6 = *gate;
paul718e3742002-12-13 20:15:29 +00002911 break;
2912 case STATIC_IPV6_IFNAME:
2913 si->ifname = XSTRDUP (0, ifname);
2914 break;
2915 case STATIC_IPV6_GATEWAY_IFNAME:
Donald Sharpd4c27d62015-11-04 13:26:35 -05002916 si->addr.ipv6 = *gate;
paul718e3742002-12-13 20:15:29 +00002917 si->ifname = XSTRDUP (0, ifname);
2918 break;
2919 }
2920
2921 /* Add new static route information to the tree with sort by
2922 distance value and gateway address. */
2923 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2924 {
2925 if (si->distance < cp->distance)
2926 break;
2927 if (si->distance > cp->distance)
2928 continue;
2929 }
2930
2931 /* Make linked list. */
2932 if (pp)
2933 pp->next = si;
2934 else
2935 rn->info = si;
2936 if (cp)
2937 cp->prev = si;
2938 si->prev = pp;
2939 si->next = cp;
2940
2941 /* Install into rib. */
Donald Sharp9bcdd1a2015-11-04 13:26:37 -05002942 static_install_route (AFI_IP6, SAFI_UNICAST, p, si);
paul718e3742002-12-13 20:15:29 +00002943
2944 return 1;
2945}
2946
2947/* Delete static route from static route configuration. */
2948int
2949static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
Feng Lu0d0686f2015-05-22 11:40:02 +02002950 const char *ifname, u_char distance, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002951{
2952 struct route_node *rn;
Donald Sharpd4c27d62015-11-04 13:26:35 -05002953 struct static_route *si;
paul718e3742002-12-13 20:15:29 +00002954 struct route_table *stable;
2955
2956 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02002957 stable = zebra_vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +00002958 if (! stable)
2959 return -1;
2960
2961 /* Lookup static route prefix. */
2962 rn = route_node_lookup (stable, p);
2963 if (! rn)
2964 return 0;
2965
2966 /* Find same static route is the tree */
2967 for (si = rn->info; si; si = si->next)
2968 if (distance == si->distance
2969 && type == si->type
Donald Sharpd4c27d62015-11-04 13:26:35 -05002970 && (! gate || IPV6_ADDR_SAME (gate, &si->addr.ipv6))
paul718e3742002-12-13 20:15:29 +00002971 && (! ifname || strcmp (ifname, si->ifname) == 0))
2972 break;
2973
2974 /* Can't find static route. */
2975 if (! si)
2976 {
2977 route_unlock_node (rn);
2978 return 0;
2979 }
2980
2981 /* Install into rib. */
Donald Sharp949b7192015-11-04 13:26:39 -05002982 static_uninstall_route (AFI_IP6, SAFI_UNICAST, p, si);
paul718e3742002-12-13 20:15:29 +00002983
2984 /* Unlink static route from linked list. */
2985 if (si->prev)
2986 si->prev->next = si->next;
2987 else
2988 rn->info = si->next;
2989 if (si->next)
2990 si->next->prev = si->prev;
2991
2992 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002993 if (ifname)
2994 XFREE (0, si->ifname);
Donald Sharpd4c27d62015-11-04 13:26:35 -05002995 XFREE (MTYPE_STATIC_ROUTE, si);
paul718e3742002-12-13 20:15:29 +00002996
2997 return 1;
2998}
David Lamparter6b0655a2014-06-04 06:53:35 +02002999
paul718e3742002-12-13 20:15:29 +00003000/* RIB update function. */
3001void
Feng Lu0d0686f2015-05-22 11:40:02 +02003002rib_update (vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00003003{
3004 struct route_node *rn;
3005 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00003006
Feng Lu0d0686f2015-05-22 11:40:02 +02003007 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +00003008 if (table)
3009 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003010 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003011 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003012
Feng Lu0d0686f2015-05-22 11:40:02 +02003013 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +00003014 if (table)
3015 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003016 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003017 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003018}
3019
David Lamparter6b0655a2014-06-04 06:53:35 +02003020
paul718e3742002-12-13 20:15:29 +00003021/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00003022static void
paul718e3742002-12-13 20:15:29 +00003023rib_weed_table (struct route_table *table)
3024{
3025 struct route_node *rn;
3026 struct rib *rib;
3027 struct rib *next;
3028
3029 if (table)
3030 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003031 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003032 {
Paul Jakma6d691122006-07-27 21:49:00 +00003033 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3034 continue;
3035
paulb21b19c2003-06-15 01:28:29 +00003036 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00003037 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00003038 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003039 }
3040}
3041
3042/* Delete all routes from non main table. */
3043void
paula1ac18c2005-06-28 17:17:12 +00003044rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00003045{
Feng Lu0d0686f2015-05-22 11:40:02 +02003046 vrf_iter_t iter;
3047 struct zebra_vrf *zvrf;
3048
3049 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3050 if ((zvrf = vrf_iter2info (iter)) != NULL)
3051 {
3052 rib_weed_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
3053 rib_weed_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
3054 }
paul718e3742002-12-13 20:15:29 +00003055}
David Lamparter6b0655a2014-06-04 06:53:35 +02003056
Feng Lu0d0686f2015-05-22 11:40:02 +02003057#if 0
paul718e3742002-12-13 20:15:29 +00003058/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00003059static void
paul718e3742002-12-13 20:15:29 +00003060rib_sweep_table (struct route_table *table)
3061{
3062 struct route_node *rn;
3063 struct rib *rib;
3064 struct rib *next;
3065 int ret = 0;
3066
3067 if (table)
3068 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003069 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003070 {
Paul Jakma6d691122006-07-27 21:49:00 +00003071 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3072 continue;
3073
paul718e3742002-12-13 20:15:29 +00003074 if (rib->type == ZEBRA_ROUTE_KERNEL &&
3075 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
3076 {
3077 ret = rib_uninstall_kernel (rn, rib);
3078 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00003079 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003080 }
3081 }
3082}
Feng Lu0d0686f2015-05-22 11:40:02 +02003083#endif
paul718e3742002-12-13 20:15:29 +00003084
3085/* Sweep all RIB tables. */
3086void
paula1ac18c2005-06-28 17:17:12 +00003087rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00003088{
Feng Lu0d0686f2015-05-22 11:40:02 +02003089 vrf_iter_t iter;
3090 struct zebra_vrf *zvrf;
3091
3092 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3093 if ((zvrf = vrf_iter2info (iter)) != NULL)
3094 {
3095 rib_weed_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
3096 rib_weed_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
3097 }
paul718e3742002-12-13 20:15:29 +00003098}
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003099
3100/* Remove specific by protocol routes from 'table'. */
3101static unsigned long
3102rib_score_proto_table (u_char proto, struct route_table *table)
3103{
3104 struct route_node *rn;
3105 struct rib *rib;
3106 struct rib *next;
3107 unsigned long n = 0;
3108
3109 if (table)
3110 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003111 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003112 {
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003113 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3114 continue;
3115 if (rib->type == proto)
3116 {
3117 rib_delnode (rn, rib);
3118 n++;
3119 }
3120 }
3121
3122 return n;
3123}
3124
3125/* Remove specific by protocol routes. */
3126unsigned long
3127rib_score_proto (u_char proto)
3128{
Feng Lu0d0686f2015-05-22 11:40:02 +02003129 vrf_iter_t iter;
3130 struct zebra_vrf *zvrf;
3131 unsigned long cnt = 0;
3132
3133 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3134 if ((zvrf = vrf_iter2info (iter)) != NULL)
3135 cnt += rib_score_proto_table (proto, zvrf->table[AFI_IP][SAFI_UNICAST])
3136 +rib_score_proto_table (proto, zvrf->table[AFI_IP6][SAFI_UNICAST]);
3137
3138 return cnt;
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003139}
3140
paul718e3742002-12-13 20:15:29 +00003141/* Close RIB and clean up kernel routes. */
Feng Lu267ceb22015-05-22 11:40:09 +02003142void
paul718e3742002-12-13 20:15:29 +00003143rib_close_table (struct route_table *table)
3144{
3145 struct route_node *rn;
David Lamparter7ce9e6a2015-01-12 07:05:06 +01003146 rib_table_info_t *info = table->info;
paul718e3742002-12-13 20:15:29 +00003147 struct rib *rib;
3148
3149 if (table)
3150 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003151 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00003152 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003153 if (!CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
3154 continue;
3155
David Lamparter7ce9e6a2015-01-12 07:05:06 +01003156 if (info->safi == SAFI_UNICAST)
3157 zfpm_trigger_update (rn, NULL);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00003158
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003159 if (! RIB_SYSTEM_ROUTE (rib))
3160 rib_uninstall_kernel (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00003161 }
paul718e3742002-12-13 20:15:29 +00003162}
3163
3164/* Close all RIB tables. */
3165void
paula1ac18c2005-06-28 17:17:12 +00003166rib_close (void)
paul718e3742002-12-13 20:15:29 +00003167{
Feng Lu0d0686f2015-05-22 11:40:02 +02003168 vrf_iter_t iter;
3169 struct zebra_vrf *zvrf;
3170
3171 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
3172 if ((zvrf = vrf_iter2info (iter)) != NULL)
3173 {
3174 rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
3175 rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
3176 }
paul718e3742002-12-13 20:15:29 +00003177}
David Lamparter6b0655a2014-06-04 06:53:35 +02003178
paul718e3742002-12-13 20:15:29 +00003179/* Routing information base initialize. */
3180void
paula1ac18c2005-06-28 17:17:12 +00003181rib_init (void)
paul718e3742002-12-13 20:15:29 +00003182{
paul4d38fdb2005-04-28 17:35:14 +00003183 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00003184}
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003185
3186/*
3187 * vrf_id_get_next
3188 *
3189 * Get the first vrf id that is greater than the given vrf id if any.
3190 *
3191 * Returns TRUE if a vrf id was found, FALSE otherwise.
3192 */
3193static inline int
Feng Lu41f44a22015-05-22 11:39:56 +02003194vrf_id_get_next (vrf_id_t vrf_id, vrf_id_t *next_id_p)
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003195{
Feng Lu41f44a22015-05-22 11:39:56 +02003196 vrf_iter_t iter = vrf_iterator (vrf_id);
3197 struct zebra_vrf *zvrf = vrf_iter2info (iter);
3198
3199 /* The same one ? Then find out the next. */
3200 if (zvrf && (zvrf->vrf_id == vrf_id))
3201 zvrf = vrf_iter2info (vrf_next (iter));
3202
3203 if (zvrf)
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003204 {
Feng Lu41f44a22015-05-22 11:39:56 +02003205 *next_id_p = zvrf->vrf_id;
3206 return 1;
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003207 }
3208
3209 return 0;
3210}
3211
3212/*
3213 * rib_tables_iter_next
3214 *
3215 * Returns the next table in the iteration.
3216 */
3217struct route_table *
3218rib_tables_iter_next (rib_tables_iter_t *iter)
3219{
3220 struct route_table *table;
3221
3222 /*
3223 * Array that helps us go over all AFI/SAFI combinations via one
3224 * index.
3225 */
3226 static struct {
3227 afi_t afi;
3228 safi_t safi;
3229 } afi_safis[] = {
3230 { AFI_IP, SAFI_UNICAST },
3231 { AFI_IP, SAFI_MULTICAST },
3232 { AFI_IP6, SAFI_UNICAST },
3233 { AFI_IP6, SAFI_MULTICAST },
3234 };
3235
3236 table = NULL;
3237
3238 switch (iter->state)
3239 {
3240
3241 case RIB_TABLES_ITER_S_INIT:
3242 iter->vrf_id = 0;
3243 iter->afi_safi_ix = -1;
3244
3245 /* Fall through */
3246
3247 case RIB_TABLES_ITER_S_ITERATING:
3248 iter->afi_safi_ix++;
3249 while (1)
3250 {
3251
3252 while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
3253 {
Feng Lu41f44a22015-05-22 11:39:56 +02003254 table = zebra_vrf_table (afi_safis[iter->afi_safi_ix].afi,
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003255 afi_safis[iter->afi_safi_ix].safi,
3256 iter->vrf_id);
3257 if (table)
3258 break;
3259
3260 iter->afi_safi_ix++;
3261 }
3262
3263 /*
3264 * Found another table in this vrf.
3265 */
3266 if (table)
3267 break;
3268
3269 /*
3270 * Done with all tables in the current vrf, go to the next
3271 * one.
3272 */
3273 if (!vrf_id_get_next (iter->vrf_id, &iter->vrf_id))
3274 break;
3275
3276 iter->afi_safi_ix = 0;
3277 }
3278
3279 break;
3280
3281 case RIB_TABLES_ITER_S_DONE:
3282 return NULL;
3283 }
3284
3285 if (table)
3286 iter->state = RIB_TABLES_ITER_S_ITERATING;
3287 else
3288 iter->state = RIB_TABLES_ITER_S_DONE;
3289
3290 return table;
3291}
Feng Lu41f44a22015-05-22 11:39:56 +02003292
3293/*
3294 * Create a routing table for the specific AFI/SAFI in the given VRF.
3295 */
3296static void
3297zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi)
3298{
3299 rib_table_info_t *info;
3300 struct route_table *table;
3301
3302 assert (!zvrf->table[afi][safi]);
3303
3304 table = route_table_init ();
3305 zvrf->table[afi][safi] = table;
3306
3307 info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
3308 info->zvrf = zvrf;
3309 info->afi = afi;
3310 info->safi = safi;
3311 table->info = info;
3312}
3313
3314/* Allocate new zebra VRF. */
3315struct zebra_vrf *
3316zebra_vrf_alloc (vrf_id_t vrf_id)
3317{
3318 struct zebra_vrf *zvrf;
Feng Lu758fb8f2014-07-03 18:23:09 +08003319#ifdef HAVE_NETLINK
3320 char nl_name[64];
3321#endif
Feng Lu41f44a22015-05-22 11:39:56 +02003322
3323 zvrf = XCALLOC (MTYPE_ZEBRA_VRF, sizeof (struct zebra_vrf));
3324
3325 /* Allocate routing table and static table. */
3326 zebra_vrf_table_create (zvrf, AFI_IP, SAFI_UNICAST);
3327 zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_UNICAST);
3328 zvrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
3329 zvrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
3330 zebra_vrf_table_create (zvrf, AFI_IP, SAFI_MULTICAST);
3331 zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_MULTICAST);
3332 zvrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
3333 zvrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
3334
3335 /* Set VRF ID */
3336 zvrf->vrf_id = vrf_id;
3337
Feng Lu758fb8f2014-07-03 18:23:09 +08003338#ifdef HAVE_NETLINK
3339 /* Initialize netlink sockets */
3340 snprintf (nl_name, 64, "netlink-listen (vrf %u)", vrf_id);
3341 zvrf->netlink.sock = -1;
3342 zvrf->netlink.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name);
3343
3344 snprintf (nl_name, 64, "netlink-cmd (vrf %u)", vrf_id);
3345 zvrf->netlink_cmd.sock = -1;
3346 zvrf->netlink_cmd.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name);
3347#endif
3348
Feng Lu41f44a22015-05-22 11:39:56 +02003349 return zvrf;
3350}
3351
3352/* Lookup the routing table in an enabled VRF. */
3353struct route_table *
3354zebra_vrf_table (afi_t afi, safi_t safi, vrf_id_t vrf_id)
3355{
3356 struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);
3357
3358 if (!zvrf)
3359 return NULL;
3360
3361 if (afi >= AFI_MAX || safi >= SAFI_MAX)
3362 return NULL;
3363
3364 return zvrf->table[afi][safi];
3365}
3366
3367/* Lookup the static routing table in a VRF. */
3368struct route_table *
3369zebra_vrf_static_table (afi_t afi, safi_t safi, vrf_id_t vrf_id)
3370{
3371 struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);
3372
3373 if (!zvrf)
3374 return NULL;
3375
3376 if (afi >= AFI_MAX || safi >= SAFI_MAX)
3377 return NULL;
3378
3379 return zvrf->stable[afi][safi];
3380}
3381