blob: 4ee1a84c8c796484d9d8079d507305aa624ad76f [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"
paul718e3742002-12-13 20:15:29 +000037
38#include "zebra/rib.h"
39#include "zebra/rt.h"
40#include "zebra/zserv.h"
41#include "zebra/redistribute.h"
42#include "zebra/debug.h"
Avneesh Sachdev5adc2522012-11-13 22:48:59 +000043#include "zebra/zebra_fpm.h"
paul718e3742002-12-13 20:15:29 +000044
45/* Default rtm_table for all clients */
paulb21b19c2003-06-15 01:28:29 +000046extern struct zebra_t zebrad;
paul718e3742002-12-13 20:15:29 +000047
Paul Jakma457eb9a2006-07-27 19:59:58 +000048/* Hold time for RIB process, should be very minimal.
49 * it is useful to able to set it otherwise for testing, hence exported
50 * as global here for test-rig code.
51 */
52int rib_process_hold_time = 10;
53
paul718e3742002-12-13 20:15:29 +000054/* Each route type's string and default distance value. */
Stephen Hemmingerd145bc02008-08-17 17:41:37 +010055static const struct
paul718e3742002-12-13 20:15:29 +000056{
57 int key;
58 int distance;
Paul Jakma57345092011-12-25 17:52:09 +010059} route_info[ZEBRA_ROUTE_MAX] =
paul718e3742002-12-13 20:15:29 +000060{
Paul Jakma57345092011-12-25 17:52:09 +010061 [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0},
62 [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0},
63 [ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0},
64 [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1},
65 [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120},
66 [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120},
67 [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110},
68 [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110},
69 [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115},
70 [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */},
71 [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 95},
David Lamparter7052f222009-08-27 00:28:28 +020072 /* no entry/default: 150 */
paul718e3742002-12-13 20:15:29 +000073};
David Lamparter6b0655a2014-06-04 06:53:35 +020074
paul718e3742002-12-13 20:15:29 +000075/* Vector for routing table. */
Stephen Hemmingerd145bc02008-08-17 17:41:37 +010076static vector vrf_vector;
paul718e3742002-12-13 20:15:29 +000077
David Lampartere0b0ac82014-04-24 20:22:53 +020078static void
79_rnode_zlog(const char *_func, struct route_node *rn, int priority,
80 const char *msgfmt, ...)
81{
82 char buf[INET6_ADDRSTRLEN + 4], *bptr;
83 char msgbuf[512];
84 va_list ap;
85
86 va_start(ap, msgfmt);
87 vsnprintf(msgbuf, sizeof(msgbuf), msgfmt, ap);
88 va_end(ap);
89
90 if (rn)
91 {
92 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
93 bptr = buf + strlen(buf);
94 snprintf(bptr, buf + sizeof(buf) - bptr, "/%d", rn->p.prefixlen);
95 }
96 else
97 {
98 snprintf(buf, sizeof(buf), "{(route_node *) NULL}");
99 }
100
101 zlog (NULL, priority, "%s: %s: %s", _func, buf, msgbuf);
102}
103
104#define rnode_debug(node, ...) \
105 _rnode_zlog(__func__, node, LOG_DEBUG, __VA_ARGS__)
106#define rnode_info(node, ...) \
107 _rnode_zlog(__func__, node, LOG_INFO, __VA_ARGS__)
108
Avneesh Sachdev1b5ed1b2012-11-13 22:48:54 +0000109/*
110 * vrf_table_create
111 */
112static void
113vrf_table_create (struct vrf *vrf, afi_t afi, safi_t safi)
114{
115 rib_table_info_t *info;
116 struct route_table *table;
117
118 assert (!vrf->table[afi][safi]);
119
120 table = route_table_init ();
121 vrf->table[afi][safi] = table;
122
123 info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
124 info->vrf = vrf;
125 info->afi = afi;
126 info->safi = safi;
127 table->info = info;
128}
129
paul718e3742002-12-13 20:15:29 +0000130/* Allocate new VRF. */
paula1ac18c2005-06-28 17:17:12 +0000131static struct vrf *
hassofce954f2004-10-07 20:29:24 +0000132vrf_alloc (const char *name)
paul718e3742002-12-13 20:15:29 +0000133{
134 struct vrf *vrf;
135
136 vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
137
138 /* Put name. */
139 if (name)
140 vrf->name = XSTRDUP (MTYPE_VRF_NAME, name);
141
142 /* Allocate routing table and static table. */
Avneesh Sachdev1b5ed1b2012-11-13 22:48:54 +0000143 vrf_table_create (vrf, AFI_IP, SAFI_UNICAST);
144 vrf_table_create (vrf, AFI_IP6, SAFI_UNICAST);
paul718e3742002-12-13 20:15:29 +0000145 vrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
146 vrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
Avneesh Sachdev1b5ed1b2012-11-13 22:48:54 +0000147 vrf_table_create (vrf, AFI_IP, SAFI_MULTICAST);
148 vrf_table_create (vrf, AFI_IP6, SAFI_MULTICAST);
G.Balajicddf3912011-11-26 21:59:32 +0400149 vrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
150 vrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
151
paul718e3742002-12-13 20:15:29 +0000152
153 return vrf;
154}
155
paul718e3742002-12-13 20:15:29 +0000156/* Lookup VRF by identifier. */
157struct vrf *
158vrf_lookup (u_int32_t id)
159{
160 return vector_lookup (vrf_vector, id);
161}
162
paul718e3742002-12-13 20:15:29 +0000163/* Initialize VRF. */
paula1ac18c2005-06-28 17:17:12 +0000164static void
165vrf_init (void)
paul718e3742002-12-13 20:15:29 +0000166{
167 struct vrf *default_table;
168
169 /* Allocate VRF vector. */
170 vrf_vector = vector_init (1);
171
172 /* Allocate default main table. */
173 default_table = vrf_alloc ("Default-IP-Routing-Table");
174
175 /* Default table index must be 0. */
176 vector_set_index (vrf_vector, 0, default_table);
177}
178
179/* Lookup route table. */
180struct route_table *
181vrf_table (afi_t afi, safi_t safi, u_int32_t id)
182{
183 struct vrf *vrf;
184
185 vrf = vrf_lookup (id);
186 if (! vrf)
187 return NULL;
188
Leonid Rosenboim9499bf22012-12-06 20:17:41 +0000189 if( afi >= AFI_MAX || safi >= SAFI_MAX )
190 return NULL;
191
paul718e3742002-12-13 20:15:29 +0000192 return vrf->table[afi][safi];
193}
194
195/* Lookup static route table. */
196struct route_table *
197vrf_static_table (afi_t afi, safi_t safi, u_int32_t id)
198{
199 struct vrf *vrf;
200
201 vrf = vrf_lookup (id);
202 if (! vrf)
203 return NULL;
204
Leonid Rosenboim9499bf22012-12-06 20:17:41 +0000205 if( afi >= AFI_MAX || safi >= SAFI_MAX )
206 return NULL;
207
paul718e3742002-12-13 20:15:29 +0000208 return vrf->stable[afi][safi];
209}
David Lamparter6b0655a2014-06-04 06:53:35 +0200210
Avneesh Sachdev78deec42012-11-13 22:48:56 +0000211/*
212 * nexthop_type_to_str
213 */
214const char *
215nexthop_type_to_str (enum nexthop_types_t nh_type)
216{
217 static const char *desc[] = {
218 "none",
219 "Directly connected",
220 "Interface route",
221 "IPv4 nexthop",
222 "IPv4 nexthop with ifindex",
223 "IPv4 nexthop with ifname",
224 "IPv6 nexthop",
225 "IPv6 nexthop with ifindex",
226 "IPv6 nexthop with ifname",
227 "Null0 nexthop",
228 };
229
230 if (nh_type >= ZEBRA_NUM_OF (desc))
231 return "<Invalid nh type>";
232
233 return desc[nh_type];
234}
235
Christian Frankefa713d92013-07-05 15:35:37 +0000236/* Add nexthop to the end of a nexthop list. */
paula1ac18c2005-06-28 17:17:12 +0000237static void
Christian Frankefa713d92013-07-05 15:35:37 +0000238_nexthop_add (struct nexthop **target, struct nexthop *nexthop)
paul718e3742002-12-13 20:15:29 +0000239{
240 struct nexthop *last;
241
Christian Frankefa713d92013-07-05 15:35:37 +0000242 for (last = *target; last && last->next; last = last->next)
paul718e3742002-12-13 20:15:29 +0000243 ;
244 if (last)
245 last->next = nexthop;
246 else
Christian Frankefa713d92013-07-05 15:35:37 +0000247 *target = nexthop;
paul718e3742002-12-13 20:15:29 +0000248 nexthop->prev = last;
Christian Frankefa713d92013-07-05 15:35:37 +0000249}
paul718e3742002-12-13 20:15:29 +0000250
Christian Frankefa713d92013-07-05 15:35:37 +0000251/* Add nexthop to the end of a rib node's nexthop list */
252static void
253nexthop_add (struct rib *rib, struct nexthop *nexthop)
254{
255 _nexthop_add(&rib->nexthop, nexthop);
paul718e3742002-12-13 20:15:29 +0000256 rib->nexthop_num++;
257}
258
259/* Delete specified nexthop from the list. */
paula1ac18c2005-06-28 17:17:12 +0000260static void
paul718e3742002-12-13 20:15:29 +0000261nexthop_delete (struct rib *rib, struct nexthop *nexthop)
262{
263 if (nexthop->next)
264 nexthop->next->prev = nexthop->prev;
265 if (nexthop->prev)
266 nexthop->prev->next = nexthop->next;
267 else
268 rib->nexthop = nexthop->next;
269 rib->nexthop_num--;
270}
271
Christian Frankefa713d92013-07-05 15:35:37 +0000272static void nexthops_free(struct nexthop *nexthop);
273
paul718e3742002-12-13 20:15:29 +0000274/* Free nexthop. */
paula1ac18c2005-06-28 17:17:12 +0000275static void
paul718e3742002-12-13 20:15:29 +0000276nexthop_free (struct nexthop *nexthop)
277{
paula4b70762003-05-16 17:19:48 +0000278 if (nexthop->ifname)
279 XFREE (0, nexthop->ifname);
Christian Frankefa713d92013-07-05 15:35:37 +0000280 if (nexthop->resolved)
281 nexthops_free(nexthop->resolved);
paul718e3742002-12-13 20:15:29 +0000282 XFREE (MTYPE_NEXTHOP, nexthop);
283}
284
Christian Frankefa713d92013-07-05 15:35:37 +0000285/* Frees a list of nexthops */
286static void
287nexthops_free (struct nexthop *nexthop)
288{
289 struct nexthop *nh, *next;
290
291 for (nh = nexthop; nh; nh = next)
292 {
293 next = nh->next;
294 nexthop_free (nh);
295 }
296}
297
paul718e3742002-12-13 20:15:29 +0000298struct nexthop *
299nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
300{
301 struct nexthop *nexthop;
302
Stephen Hemminger393deb92008-08-18 14:13:29 -0700303 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000304 nexthop->type = NEXTHOP_TYPE_IFINDEX;
305 nexthop->ifindex = ifindex;
306
307 nexthop_add (rib, nexthop);
308
309 return nexthop;
310}
311
312struct nexthop *
313nexthop_ifname_add (struct rib *rib, char *ifname)
314{
315 struct nexthop *nexthop;
316
Stephen Hemminger393deb92008-08-18 14:13:29 -0700317 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000318 nexthop->type = NEXTHOP_TYPE_IFNAME;
paula4b70762003-05-16 17:19:48 +0000319 nexthop->ifname = XSTRDUP (0, ifname);
paul718e3742002-12-13 20:15:29 +0000320
321 nexthop_add (rib, nexthop);
322
323 return nexthop;
324}
325
326struct nexthop *
Paul Jakma7514fb72007-05-02 16:05:35 +0000327nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src)
paul718e3742002-12-13 20:15:29 +0000328{
329 struct nexthop *nexthop;
330
Stephen Hemminger393deb92008-08-18 14:13:29 -0700331 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000332 nexthop->type = NEXTHOP_TYPE_IPV4;
333 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000334 if (src)
335 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000336
337 nexthop_add (rib, nexthop);
338
339 return nexthop;
340}
341
Josh Bailey26e2ae32012-03-22 01:09:21 -0700342struct nexthop *
paul718e3742002-12-13 20:15:29 +0000343nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
Paul Jakma7514fb72007-05-02 16:05:35 +0000344 struct in_addr *src, unsigned int ifindex)
paul718e3742002-12-13 20:15:29 +0000345{
346 struct nexthop *nexthop;
347
Stephen Hemminger393deb92008-08-18 14:13:29 -0700348 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000349 nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
350 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000351 if (src)
352 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000353 nexthop->ifindex = ifindex;
354
355 nexthop_add (rib, nexthop);
356
357 return nexthop;
358}
359
360#ifdef HAVE_IPV6
361struct nexthop *
362nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
363{
364 struct nexthop *nexthop;
365
Stephen Hemminger393deb92008-08-18 14:13:29 -0700366 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000367 nexthop->type = NEXTHOP_TYPE_IPV6;
368 nexthop->gate.ipv6 = *ipv6;
369
370 nexthop_add (rib, nexthop);
371
372 return nexthop;
373}
374
paula1ac18c2005-06-28 17:17:12 +0000375static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000376nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
377 char *ifname)
378{
379 struct nexthop *nexthop;
380
Stephen Hemminger393deb92008-08-18 14:13:29 -0700381 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000382 nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
383 nexthop->gate.ipv6 = *ipv6;
384 nexthop->ifname = XSTRDUP (0, ifname);
385
386 nexthop_add (rib, nexthop);
387
388 return nexthop;
389}
390
paula1ac18c2005-06-28 17:17:12 +0000391static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000392nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
393 unsigned int ifindex)
394{
395 struct nexthop *nexthop;
396
Stephen Hemminger393deb92008-08-18 14:13:29 -0700397 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000398 nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
399 nexthop->gate.ipv6 = *ipv6;
400 nexthop->ifindex = ifindex;
401
402 nexthop_add (rib, nexthop);
403
404 return nexthop;
405}
406#endif /* HAVE_IPV6 */
407
paul595db7f2003-05-25 21:35:06 +0000408struct nexthop *
409nexthop_blackhole_add (struct rib *rib)
410{
411 struct nexthop *nexthop;
412
Stephen Hemminger393deb92008-08-18 14:13:29 -0700413 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul595db7f2003-05-25 21:35:06 +0000414 nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
415 SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
416
417 nexthop_add (rib, nexthop);
418
419 return nexthop;
420}
421
Christian Frankefa713d92013-07-05 15:35:37 +0000422/* This method checks whether a recursive nexthop has at
423 * least one resolved nexthop in the fib.
424 */
425int
426nexthop_has_fib_child(struct nexthop *nexthop)
427{
428 struct nexthop *nh;
429
430 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
431 return 0;
432
433 for (nh = nexthop->resolved; nh; nh = nh->next)
434 if (CHECK_FLAG (nh->flags, NEXTHOP_FLAG_FIB))
435 return 1;
436
437 return 0;
438}
439
paul718e3742002-12-13 20:15:29 +0000440/* If force flag is not set, do not modify falgs at all for uninstall
441 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000442static int
paul718e3742002-12-13 20:15:29 +0000443nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
444 struct route_node *top)
445{
446 struct prefix_ipv4 p;
447 struct route_table *table;
448 struct route_node *rn;
449 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000450 int resolved;
paul718e3742002-12-13 20:15:29 +0000451 struct nexthop *newhop;
Christian Frankefa713d92013-07-05 15:35:37 +0000452 struct nexthop *resolved_hop;
paul718e3742002-12-13 20:15:29 +0000453
454 if (nexthop->type == NEXTHOP_TYPE_IPV4)
455 nexthop->ifindex = 0;
456
457 if (set)
Christian Frankefa713d92013-07-05 15:35:37 +0000458 {
459 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
460 nexthops_free(nexthop->resolved);
461 nexthop->resolved = NULL;
462 }
paul718e3742002-12-13 20:15:29 +0000463
464 /* Make lookup prefix. */
465 memset (&p, 0, sizeof (struct prefix_ipv4));
466 p.family = AF_INET;
467 p.prefixlen = IPV4_MAX_PREFIXLEN;
468 p.prefix = nexthop->gate.ipv4;
469
470 /* Lookup table. */
471 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
472 if (! table)
473 return 0;
474
475 rn = route_node_match (table, (struct prefix *) &p);
476 while (rn)
477 {
478 route_unlock_node (rn);
479
David Warda50c1072009-12-03 15:34:39 +0300480 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000481 if (rn == top)
482 return 0;
483
484 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000485 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100486 {
487 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
488 continue;
489 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
490 break;
491 }
paul718e3742002-12-13 20:15:29 +0000492
493 /* If there is no selected route or matched route is EGP, go up
494 tree. */
495 if (! match
496 || match->type == ZEBRA_ROUTE_BGP)
497 {
498 do {
499 rn = rn->parent;
500 } while (rn && rn->info == NULL);
501 if (rn)
502 route_lock_node (rn);
503 }
504 else
505 {
Christian Franke48a53dc2013-07-05 15:35:38 +0000506 /* If the longest prefix match for the nexthop yields
507 * a blackhole, mark it as inactive. */
508 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE)
509 || CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT))
510 return 0;
511
paul718e3742002-12-13 20:15:29 +0000512 if (match->type == ZEBRA_ROUTE_CONNECT)
513 {
514 /* Directly point connected route. */
515 newhop = match->nexthop;
516 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
517 nexthop->ifindex = newhop->ifindex;
518
519 return 1;
520 }
521 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
522 {
Christian Frankefa713d92013-07-05 15:35:37 +0000523 resolved = 0;
paul718e3742002-12-13 20:15:29 +0000524 for (newhop = match->nexthop; newhop; newhop = newhop->next)
525 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
526 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
527 {
528 if (set)
529 {
530 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
Christian Frankefa713d92013-07-05 15:35:37 +0000531
532 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
533 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
Christian Frankec3e6b592013-07-05 15:35:40 +0000534 /* If the resolving route specifies a gateway, use it */
535 if (newhop->type == NEXTHOP_TYPE_IPV4
536 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX
537 || newhop->type == NEXTHOP_TYPE_IPV4_IFNAME)
538 {
539 resolved_hop->type = newhop->type;
540 resolved_hop->gate.ipv4 = newhop->gate.ipv4;
Christian Frankefa713d92013-07-05 15:35:37 +0000541
Christian Frankec3e6b592013-07-05 15:35:40 +0000542 if (newhop->ifindex)
543 {
544 resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
545 resolved_hop->ifindex = newhop->ifindex;
546 }
547 }
Christian Frankefa713d92013-07-05 15:35:37 +0000548
Christian Frankec3e6b592013-07-05 15:35:40 +0000549 /* If the resolving route is an interface route,
550 * it means the gateway we are looking up is connected
551 * to that interface. (The actual network is _not_ onlink).
552 * Therefore, the resolved route should have the original
553 * gateway as nexthop as it is directly connected.
554 *
555 * On Linux, we have to set the onlink netlink flag because
556 * otherwise, the kernel won't accept the route. */
paul718e3742002-12-13 20:15:29 +0000557 if (newhop->type == NEXTHOP_TYPE_IFINDEX
Christian Frankec3e6b592013-07-05 15:35:40 +0000558 || newhop->type == NEXTHOP_TYPE_IFNAME)
559 {
560 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
561 resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
562 resolved_hop->gate.ipv4 = nexthop->gate.ipv4;
563 resolved_hop->ifindex = newhop->ifindex;
564 }
Christian Frankefa713d92013-07-05 15:35:37 +0000565
566 _nexthop_add(&nexthop->resolved, resolved_hop);
paul718e3742002-12-13 20:15:29 +0000567 }
Christian Frankefa713d92013-07-05 15:35:37 +0000568 resolved = 1;
paul718e3742002-12-13 20:15:29 +0000569 }
Christian Frankefa713d92013-07-05 15:35:37 +0000570 return resolved;
paul718e3742002-12-13 20:15:29 +0000571 }
572 else
573 {
574 return 0;
575 }
576 }
577 }
578 return 0;
579}
580
581#ifdef HAVE_IPV6
582/* If force flag is not set, do not modify falgs at all for uninstall
583 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000584static int
paul718e3742002-12-13 20:15:29 +0000585nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
586 struct route_node *top)
587{
588 struct prefix_ipv6 p;
589 struct route_table *table;
590 struct route_node *rn;
591 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000592 int resolved;
paul718e3742002-12-13 20:15:29 +0000593 struct nexthop *newhop;
Christian Frankefa713d92013-07-05 15:35:37 +0000594 struct nexthop *resolved_hop;
paul718e3742002-12-13 20:15:29 +0000595
596 if (nexthop->type == NEXTHOP_TYPE_IPV6)
597 nexthop->ifindex = 0;
598
599 if (set)
Christian Frankefa713d92013-07-05 15:35:37 +0000600 {
601 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
602 nexthops_free(nexthop->resolved);
603 nexthop->resolved = NULL;
604 }
paul718e3742002-12-13 20:15:29 +0000605
606 /* Make lookup prefix. */
607 memset (&p, 0, sizeof (struct prefix_ipv6));
608 p.family = AF_INET6;
609 p.prefixlen = IPV6_MAX_PREFIXLEN;
610 p.prefix = nexthop->gate.ipv6;
611
612 /* Lookup table. */
613 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
614 if (! table)
615 return 0;
616
617 rn = route_node_match (table, (struct prefix *) &p);
618 while (rn)
619 {
620 route_unlock_node (rn);
621
David Warda50c1072009-12-03 15:34:39 +0300622 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000623 if (rn == top)
624 return 0;
625
626 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000627 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100628 {
629 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
630 continue;
631 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
632 break;
633 }
paul718e3742002-12-13 20:15:29 +0000634
635 /* If there is no selected route or matched route is EGP, go up
636 tree. */
637 if (! match
638 || match->type == ZEBRA_ROUTE_BGP)
639 {
640 do {
641 rn = rn->parent;
642 } while (rn && rn->info == NULL);
643 if (rn)
644 route_lock_node (rn);
645 }
646 else
647 {
Christian Franke48a53dc2013-07-05 15:35:38 +0000648 /* If the longest prefix match for the nexthop yields
649 * a blackhole, mark it as inactive. */
650 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE)
651 || CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT))
652 return 0;
653
paul718e3742002-12-13 20:15:29 +0000654 if (match->type == ZEBRA_ROUTE_CONNECT)
655 {
656 /* Directly point connected route. */
657 newhop = match->nexthop;
658
659 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
660 nexthop->ifindex = newhop->ifindex;
661
662 return 1;
663 }
664 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
665 {
Christian Frankefa713d92013-07-05 15:35:37 +0000666 resolved = 0;
paul718e3742002-12-13 20:15:29 +0000667 for (newhop = match->nexthop; newhop; newhop = newhop->next)
668 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
669 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
670 {
671 if (set)
672 {
673 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
Christian Frankefa713d92013-07-05 15:35:37 +0000674
675 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
676 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
Christian Frankec3e6b592013-07-05 15:35:40 +0000677 /* See nexthop_active_ipv4 for a description how the
678 * resolved nexthop is constructed. */
paul718e3742002-12-13 20:15:29 +0000679 if (newhop->type == NEXTHOP_TYPE_IPV6
680 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
681 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
Christian Frankec3e6b592013-07-05 15:35:40 +0000682 {
683 resolved_hop->type = newhop->type;
684 resolved_hop->gate.ipv6 = newhop->gate.ipv6;
685
686 if (newhop->ifindex)
687 {
688 resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
689 resolved_hop->ifindex = newhop->ifindex;
690 }
691 }
Christian Frankefa713d92013-07-05 15:35:37 +0000692
paul718e3742002-12-13 20:15:29 +0000693 if (newhop->type == NEXTHOP_TYPE_IFINDEX
Christian Frankec3e6b592013-07-05 15:35:40 +0000694 || newhop->type == NEXTHOP_TYPE_IFNAME)
695 {
696 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
697 resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
698 resolved_hop->gate.ipv6 = nexthop->gate.ipv6;
699 resolved_hop->ifindex = newhop->ifindex;
700 }
Christian Frankefa713d92013-07-05 15:35:37 +0000701
702 _nexthop_add(&nexthop->resolved, resolved_hop);
paul718e3742002-12-13 20:15:29 +0000703 }
Christian Frankefa713d92013-07-05 15:35:37 +0000704 resolved = 1;
paul718e3742002-12-13 20:15:29 +0000705 }
Christian Frankefa713d92013-07-05 15:35:37 +0000706 return resolved;
paul718e3742002-12-13 20:15:29 +0000707 }
708 else
709 {
710 return 0;
711 }
712 }
713 }
714 return 0;
715}
716#endif /* HAVE_IPV6 */
717
718struct rib *
719rib_match_ipv4 (struct in_addr addr)
720{
721 struct prefix_ipv4 p;
722 struct route_table *table;
723 struct route_node *rn;
724 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000725 struct nexthop *newhop, *tnewhop;
726 int recursing;
paul718e3742002-12-13 20:15:29 +0000727
728 /* Lookup table. */
729 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
730 if (! table)
731 return 0;
732
733 memset (&p, 0, sizeof (struct prefix_ipv4));
734 p.family = AF_INET;
735 p.prefixlen = IPV4_MAX_PREFIXLEN;
736 p.prefix = addr;
737
738 rn = route_node_match (table, (struct prefix *) &p);
739
740 while (rn)
741 {
742 route_unlock_node (rn);
743
744 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000745 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100746 {
747 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
748 continue;
749 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
750 break;
751 }
paul718e3742002-12-13 20:15:29 +0000752
753 /* If there is no selected route or matched route is EGP, go up
754 tree. */
755 if (! match
756 || match->type == ZEBRA_ROUTE_BGP)
757 {
758 do {
759 rn = rn->parent;
760 } while (rn && rn->info == NULL);
761 if (rn)
762 route_lock_node (rn);
763 }
764 else
765 {
766 if (match->type == ZEBRA_ROUTE_CONNECT)
767 /* Directly point connected route. */
768 return match;
769 else
770 {
Christian Frankefa713d92013-07-05 15:35:37 +0000771 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
paul718e3742002-12-13 20:15:29 +0000772 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
773 return match;
774 return NULL;
775 }
776 }
777 }
778 return NULL;
779}
780
781struct rib *
782rib_lookup_ipv4 (struct prefix_ipv4 *p)
783{
784 struct route_table *table;
785 struct route_node *rn;
786 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000787 struct nexthop *nexthop, *tnexthop;
788 int recursing;
paul718e3742002-12-13 20:15:29 +0000789
790 /* Lookup table. */
791 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
792 if (! table)
793 return 0;
794
795 rn = route_node_lookup (table, (struct prefix *) p);
796
797 /* No route for this prefix. */
798 if (! rn)
799 return NULL;
800
801 /* Unlock node. */
802 route_unlock_node (rn);
803
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000804 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100805 {
806 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
807 continue;
808 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
809 break;
810 }
paul718e3742002-12-13 20:15:29 +0000811
812 if (! match || match->type == ZEBRA_ROUTE_BGP)
813 return NULL;
814
815 if (match->type == ZEBRA_ROUTE_CONNECT)
816 return match;
817
Christian Frankefa713d92013-07-05 15:35:37 +0000818 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +0000819 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
820 return match;
821
822 return NULL;
823}
824
Denis Ovsienkodc958242007-08-13 16:03:06 +0000825/*
826 * This clone function, unlike its original rib_lookup_ipv4(), checks
827 * if specified IPv4 route record (prefix/mask -> gate) exists in
828 * the whole RIB and has ZEBRA_FLAG_SELECTED set.
829 *
830 * Return values:
831 * -1: error
832 * 0: exact match found
833 * 1: a match was found with a different gate
834 * 2: connected route found
835 * 3: no matches found
836 */
837int
838rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
839{
840 struct route_table *table;
841 struct route_node *rn;
842 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000843 struct nexthop *nexthop, *tnexthop;
844 int recursing;
845 int nexthops_active;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000846
847 /* Lookup table. */
848 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
849 if (! table)
850 return ZEBRA_RIB_LOOKUP_ERROR;
851
852 /* Scan the RIB table for exactly matching RIB entry. */
853 rn = route_node_lookup (table, (struct prefix *) p);
854
855 /* No route for this prefix. */
856 if (! rn)
857 return ZEBRA_RIB_NOTFOUND;
858
859 /* Unlock node. */
860 route_unlock_node (rn);
861
862 /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000863 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100864 {
865 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
866 continue;
867 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
868 break;
869 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000870
871 /* None such found :( */
872 if (!match)
873 return ZEBRA_RIB_NOTFOUND;
874
875 if (match->type == ZEBRA_ROUTE_CONNECT)
876 return ZEBRA_RIB_FOUND_CONNECTED;
877
878 /* Ok, we have a cood candidate, let's check it's nexthop list... */
Christian Frankefa713d92013-07-05 15:35:37 +0000879 nexthops_active = 0;
880 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000881 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000882 {
Christian Frankefa713d92013-07-05 15:35:37 +0000883 nexthops_active = 1;
884 if (nexthop->gate.ipv4.s_addr == sockunion2ip (qgate))
885 return ZEBRA_RIB_FOUND_EXACT;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000886 if (IS_ZEBRA_DEBUG_RIB)
Christian Frankefa713d92013-07-05 15:35:37 +0000887 {
888 char gate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
889 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
890 inet_ntop (AF_INET, &sockunion2ip(qgate), qgate_buf, INET_ADDRSTRLEN);
891 zlog_debug ("%s: qgate == %s, %s == %s", __func__,
892 qgate_buf, recursing ? "rgate" : "gate", gate_buf);
893 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000894 }
Christian Frankefa713d92013-07-05 15:35:37 +0000895
896 if (nexthops_active)
897 return ZEBRA_RIB_FOUND_NOGATE;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000898
899 return ZEBRA_RIB_NOTFOUND;
900}
901
paul718e3742002-12-13 20:15:29 +0000902#ifdef HAVE_IPV6
903struct rib *
904rib_match_ipv6 (struct in6_addr *addr)
905{
906 struct prefix_ipv6 p;
907 struct route_table *table;
908 struct route_node *rn;
909 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000910 struct nexthop *newhop, *tnewhop;
911 int recursing;
paul718e3742002-12-13 20:15:29 +0000912
913 /* Lookup table. */
914 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
915 if (! table)
916 return 0;
917
918 memset (&p, 0, sizeof (struct prefix_ipv6));
919 p.family = AF_INET6;
920 p.prefixlen = IPV6_MAX_PREFIXLEN;
921 IPV6_ADDR_COPY (&p.prefix, addr);
922
923 rn = route_node_match (table, (struct prefix *) &p);
924
925 while (rn)
926 {
927 route_unlock_node (rn);
928
929 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000930 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100931 {
932 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
933 continue;
934 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
935 break;
936 }
paul718e3742002-12-13 20:15:29 +0000937
938 /* If there is no selected route or matched route is EGP, go up
939 tree. */
940 if (! match
941 || match->type == ZEBRA_ROUTE_BGP)
942 {
943 do {
944 rn = rn->parent;
945 } while (rn && rn->info == NULL);
946 if (rn)
947 route_lock_node (rn);
948 }
949 else
950 {
951 if (match->type == ZEBRA_ROUTE_CONNECT)
952 /* Directly point connected route. */
953 return match;
954 else
955 {
Christian Frankefa713d92013-07-05 15:35:37 +0000956 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
paul718e3742002-12-13 20:15:29 +0000957 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
958 return match;
959 return NULL;
960 }
961 }
962 }
963 return NULL;
964}
965#endif /* HAVE_IPV6 */
966
Paul Jakma7514fb72007-05-02 16:05:35 +0000967#define RIB_SYSTEM_ROUTE(R) \
968 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
969
Denis Ovsienkodc958242007-08-13 16:03:06 +0000970/* This function verifies reachability of one given nexthop, which can be
971 * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
972 * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
973 * nexthop->ifindex will be updated appropriately as well.
974 * An existing route map can turn (otherwise active) nexthop into inactive, but
975 * not vice versa.
976 *
977 * The return value is the final value of 'ACTIVE' flag.
978 */
979
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300980static unsigned
paul718e3742002-12-13 20:15:29 +0000981nexthop_active_check (struct route_node *rn, struct rib *rib,
982 struct nexthop *nexthop, int set)
983{
Christian Frankef3a17322013-07-05 15:35:41 +0000984 rib_table_info_t *info = rn->table->info;
paul718e3742002-12-13 20:15:29 +0000985 struct interface *ifp;
Paul Jakma7514fb72007-05-02 16:05:35 +0000986 route_map_result_t ret = RMAP_MATCH;
987 extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
988 struct route_map *rmap;
989 int family;
paul718e3742002-12-13 20:15:29 +0000990
Paul Jakma7514fb72007-05-02 16:05:35 +0000991 family = 0;
paul718e3742002-12-13 20:15:29 +0000992 switch (nexthop->type)
993 {
994 case NEXTHOP_TYPE_IFINDEX:
995 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000996 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000997 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
998 else
999 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1000 break;
paul718e3742002-12-13 20:15:29 +00001001 case NEXTHOP_TYPE_IPV6_IFNAME:
Paul Jakma7514fb72007-05-02 16:05:35 +00001002 family = AFI_IP6;
1003 case NEXTHOP_TYPE_IFNAME:
paul718e3742002-12-13 20:15:29 +00001004 ifp = if_lookup_by_name (nexthop->ifname);
Andrew J. Schorr3f087672008-01-08 20:12:46 +00001005 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001006 {
1007 if (set)
1008 nexthop->ifindex = ifp->ifindex;
1009 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1010 }
1011 else
1012 {
1013 if (set)
1014 nexthop->ifindex = 0;
1015 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1016 }
1017 break;
1018 case NEXTHOP_TYPE_IPV4:
1019 case NEXTHOP_TYPE_IPV4_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +00001020 family = AFI_IP;
paul718e3742002-12-13 20:15:29 +00001021 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
1022 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1023 else
1024 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1025 break;
1026#ifdef HAVE_IPV6
1027 case NEXTHOP_TYPE_IPV6:
Paul Jakma7514fb72007-05-02 16:05:35 +00001028 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +00001029 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
1030 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1031 else
1032 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1033 break;
1034 case NEXTHOP_TYPE_IPV6_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +00001035 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +00001036 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
1037 {
1038 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +00001039 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001040 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1041 else
1042 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1043 }
1044 else
1045 {
1046 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
1047 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1048 else
1049 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1050 }
1051 break;
1052#endif /* HAVE_IPV6 */
paul595db7f2003-05-25 21:35:06 +00001053 case NEXTHOP_TYPE_BLACKHOLE:
1054 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1055 break;
paul718e3742002-12-13 20:15:29 +00001056 default:
1057 break;
1058 }
Paul Jakma7514fb72007-05-02 16:05:35 +00001059 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1060 return 0;
1061
Christian Frankef3a17322013-07-05 15:35:41 +00001062 /* XXX: What exactly do those checks do? Do we support
1063 * e.g. IPv4 routes with IPv6 nexthops or vice versa? */
Paul Jakma7514fb72007-05-02 16:05:35 +00001064 if (RIB_SYSTEM_ROUTE(rib) ||
1065 (family == AFI_IP && rn->p.family != AF_INET) ||
1066 (family == AFI_IP6 && rn->p.family != AF_INET6))
1067 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1068
Christian Frankef3a17322013-07-05 15:35:41 +00001069 /* The original code didn't determine the family correctly
1070 * e.g. for NEXTHOP_TYPE_IFINDEX. Retrieve the correct afi
1071 * from the rib_table_info in those cases.
1072 * Possibly it may be better to use only the rib_table_info
1073 * in every case.
1074 */
1075 if (!family)
1076 family = info->afi;
1077
Paul Jakma7514fb72007-05-02 16:05:35 +00001078 rmap = 0;
1079 if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
1080 proto_rm[family][rib->type])
1081 rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
1082 if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
1083 rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
1084 if (rmap) {
1085 ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, nexthop);
1086 }
1087
1088 if (ret == RMAP_DENYMATCH)
1089 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
paul718e3742002-12-13 20:15:29 +00001090 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1091}
1092
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001093/* Iterate over all nexthops of the given RIB entry and refresh their
1094 * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
1095 * nexthop is found to toggle the ACTIVE flag, the whole rib structure
1096 * is flagged with ZEBRA_FLAG_CHANGED. The 4th 'set' argument is
1097 * transparently passed to nexthop_active_check().
1098 *
1099 * Return value is the new number of active nexthops.
1100 */
1101
paula1ac18c2005-06-28 17:17:12 +00001102static int
paul718e3742002-12-13 20:15:29 +00001103nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
1104{
1105 struct nexthop *nexthop;
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001106 unsigned int prev_active, prev_index, new_active;
paul718e3742002-12-13 20:15:29 +00001107
1108 rib->nexthop_active_num = 0;
1109 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1110
1111 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001112 {
1113 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001114 prev_index = nexthop->ifindex;
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001115 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
1116 rib->nexthop_active_num++;
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001117 if (prev_active != new_active ||
1118 prev_index != nexthop->ifindex)
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001119 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1120 }
paul718e3742002-12-13 20:15:29 +00001121 return rib->nexthop_active_num;
1122}
paul6baeb982003-10-28 03:47:15 +00001123
David Lamparter6b0655a2014-06-04 06:53:35 +02001124
paul718e3742002-12-13 20:15:29 +00001125
paula1ac18c2005-06-28 17:17:12 +00001126static void
paul718e3742002-12-13 20:15:29 +00001127rib_install_kernel (struct route_node *rn, struct rib *rib)
1128{
1129 int ret = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001130 struct nexthop *nexthop, *tnexthop;
1131 int recursing;
paul718e3742002-12-13 20:15:29 +00001132
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001133 /*
1134 * Make sure we update the FPM any time we send new information to
1135 * the kernel.
1136 */
1137 zfpm_trigger_update (rn, "installing in kernel");
paul718e3742002-12-13 20:15:29 +00001138 switch (PREFIX_FAMILY (&rn->p))
1139 {
1140 case AF_INET:
1141 ret = kernel_add_ipv4 (&rn->p, rib);
1142 break;
1143#ifdef HAVE_IPV6
1144 case AF_INET6:
1145 ret = kernel_add_ipv6 (&rn->p, rib);
1146 break;
1147#endif /* HAVE_IPV6 */
1148 }
1149
Denis Ovsienkodc958242007-08-13 16:03:06 +00001150 /* This condition is never met, if we are using rt_socket.c */
paul718e3742002-12-13 20:15:29 +00001151 if (ret < 0)
1152 {
Christian Frankefa713d92013-07-05 15:35:37 +00001153 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +00001154 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1155 }
1156}
1157
1158/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001159static int
paul718e3742002-12-13 20:15:29 +00001160rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
1161{
1162 int ret = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001163 struct nexthop *nexthop, *tnexthop;
1164 int recursing;
paul718e3742002-12-13 20:15:29 +00001165
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001166 /*
1167 * Make sure we update the FPM any time we send new information to
1168 * the kernel.
1169 */
1170 zfpm_trigger_update (rn, "uninstalling from kernel");
1171
paul718e3742002-12-13 20:15:29 +00001172 switch (PREFIX_FAMILY (&rn->p))
1173 {
1174 case AF_INET:
1175 ret = kernel_delete_ipv4 (&rn->p, rib);
1176 break;
1177#ifdef HAVE_IPV6
1178 case AF_INET6:
1179 ret = kernel_delete_ipv6 (&rn->p, rib);
1180 break;
1181#endif /* HAVE_IPV6 */
1182 }
1183
Christian Frankefa713d92013-07-05 15:35:37 +00001184 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +00001185 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1186
1187 return ret;
1188}
1189
1190/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001191static void
paul718e3742002-12-13 20:15:29 +00001192rib_uninstall (struct route_node *rn, struct rib *rib)
1193{
1194 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1195 {
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001196 zfpm_trigger_update (rn, "rib_uninstall");
1197
paul718e3742002-12-13 20:15:29 +00001198 redistribute_delete (&rn->p, rib);
1199 if (! RIB_SYSTEM_ROUTE (rib))
1200 rib_uninstall_kernel (rn, rib);
1201 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
1202 }
1203}
1204
Paul Jakma6d691122006-07-27 21:49:00 +00001205static void rib_unlink (struct route_node *, struct rib *);
1206
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001207/*
1208 * rib_can_delete_dest
1209 *
1210 * Returns TRUE if the given dest can be deleted from the table.
1211 */
1212static int
1213rib_can_delete_dest (rib_dest_t *dest)
1214{
1215 if (dest->routes)
1216 {
1217 return 0;
1218 }
1219
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001220 /*
1221 * Don't delete the dest if we have to update the FPM about this
1222 * prefix.
1223 */
1224 if (CHECK_FLAG (dest->flags, RIB_DEST_UPDATE_FPM) ||
1225 CHECK_FLAG (dest->flags, RIB_DEST_SENT_TO_FPM))
1226 return 0;
1227
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001228 return 1;
1229}
1230
1231/*
1232 * rib_gc_dest
1233 *
1234 * Garbage collect the rib dest corresponding to the given route node
1235 * if appropriate.
1236 *
1237 * Returns TRUE if the dest was deleted, FALSE otherwise.
1238 */
1239int
1240rib_gc_dest (struct route_node *rn)
1241{
1242 rib_dest_t *dest;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001243
1244 dest = rib_dest_from_rnode (rn);
1245 if (!dest)
1246 return 0;
1247
1248 if (!rib_can_delete_dest (dest))
1249 return 0;
1250
1251 if (IS_ZEBRA_DEBUG_RIB)
David Lampartere0b0ac82014-04-24 20:22:53 +02001252 rnode_debug (rn, "removing dest from table");
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001253
1254 dest->rnode = NULL;
1255 XFREE (MTYPE_RIB_DEST, dest);
1256 rn->info = NULL;
1257
1258 /*
1259 * Release the one reference that we keep on the route node.
1260 */
1261 route_unlock_node (rn);
1262 return 1;
1263}
1264
paul718e3742002-12-13 20:15:29 +00001265/* Core function for processing routing information base. */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001266static void
1267rib_process (struct route_node *rn)
paul718e3742002-12-13 20:15:29 +00001268{
1269 struct rib *rib;
1270 struct rib *next;
1271 struct rib *fib = NULL;
1272 struct rib *select = NULL;
Paul Jakma6d691122006-07-27 21:49:00 +00001273 struct rib *del = NULL;
pauld753e9e2003-01-22 19:45:50 +00001274 int installed = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001275 struct nexthop *nexthop = NULL, *tnexthop;
1276 int recursing;
Balaji95116332014-10-23 15:25:25 +00001277 rib_table_info_t *info;
1278
paul4d38fdb2005-04-28 17:35:14 +00001279 assert (rn);
Balaji95116332014-10-23 15:25:25 +00001280
1281 info = rn->table->info;
1282
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001283 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00001284 {
paul718e3742002-12-13 20:15:29 +00001285 /* Currently installed rib. */
1286 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Paul Jakma6d691122006-07-27 21:49:00 +00001287 {
1288 assert (fib == NULL);
1289 fib = rib;
1290 }
1291
1292 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1293 * which we need to do do further work with below.
1294 */
1295 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1296 {
1297 if (rib != fib)
1298 {
1299 if (IS_ZEBRA_DEBUG_RIB)
David Lampartere0b0ac82014-04-24 20:22:53 +02001300 rnode_debug (rn, "rn %p, removing rib %p", rn, rib);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001301 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
Balaji95116332014-10-23 15:25:25 +00001313 if (info->safi == SAFI_MULTICAST)
1314 continue;
1315
paul718e3742002-12-13 20:15:29 +00001316 /* Infinit distance. */
1317 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +00001318 continue;
paul718e3742002-12-13 20:15:29 +00001319
paulaf887b52006-01-18 14:52:52 +00001320 /* Newly selected rib, the common case. */
1321 if (!select)
1322 {
1323 select = rib;
1324 continue;
1325 }
1326
1327 /* filter route selection in following order:
paulaf887b52006-01-18 14:52:52 +00001328 * - connected beats other types
paula8d9c1f2006-01-25 06:31:04 +00001329 * - lower distance beats higher
paulaf887b52006-01-18 14:52:52 +00001330 * - lower metric beats higher for equal distance
1331 * - last, hence oldest, route wins tie break.
1332 */
paula1038a12006-01-30 14:08:51 +00001333
1334 /* Connected routes. Pick the last connected
1335 * route of the set of lowest metric connected routes.
1336 */
paula8d9c1f2006-01-25 06:31:04 +00001337 if (rib->type == ZEBRA_ROUTE_CONNECT)
1338 {
paula1038a12006-01-30 14:08:51 +00001339 if (select->type != ZEBRA_ROUTE_CONNECT
paula8d9c1f2006-01-25 06:31:04 +00001340 || rib->metric <= select->metric)
paula1038a12006-01-30 14:08:51 +00001341 select = rib;
1342 continue;
paula8d9c1f2006-01-25 06:31:04 +00001343 }
1344 else if (select->type == ZEBRA_ROUTE_CONNECT)
1345 continue;
1346
1347 /* higher distance loses */
1348 if (rib->distance > select->distance)
1349 continue;
1350
1351 /* lower wins */
1352 if (rib->distance < select->distance)
1353 {
paulaf887b52006-01-18 14:52:52 +00001354 select = rib;
paula8d9c1f2006-01-25 06:31:04 +00001355 continue;
1356 }
1357
1358 /* metric tie-breaks equal distance */
1359 if (rib->metric <= select->metric)
1360 select = rib;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001361 } /* RNODE_FOREACH_RIB_SAFE */
Denis Ovsienkodc958242007-08-13 16:03:06 +00001362
1363 /* After the cycle is finished, the following pointers will be set:
1364 * select --- the winner RIB entry, if any was found, otherwise NULL
1365 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1366 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1367 * rib --- NULL
1368 */
1369
1370 /* Same RIB entry is selected. Update FIB and finish. */
paul718e3742002-12-13 20:15:29 +00001371 if (select && select == fib)
1372 {
Paul Jakma6d691122006-07-27 21:49:00 +00001373 if (IS_ZEBRA_DEBUG_RIB)
David Lampartere0b0ac82014-04-24 20:22:53 +02001374 rnode_debug (rn, "Updating existing route, select %p, fib %p",
1375 select, fib);
paul718e3742002-12-13 20:15:29 +00001376 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +00001377 {
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001378 zfpm_trigger_update (rn, "updating existing route");
1379
paul4d38fdb2005-04-28 17:35:14 +00001380 redistribute_delete (&rn->p, select);
1381 if (! RIB_SYSTEM_ROUTE (select))
1382 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001383
paul4d38fdb2005-04-28 17:35:14 +00001384 /* Set real nexthop. */
1385 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +00001386
paul4d38fdb2005-04-28 17:35:14 +00001387 if (! RIB_SYSTEM_ROUTE (select))
1388 rib_install_kernel (rn, select);
1389 redistribute_add (&rn->p, select);
1390 }
pauld753e9e2003-01-22 19:45:50 +00001391 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001392 {
1393 /* Housekeeping code to deal with
1394 race conditions in kernel with linux
1395 netlink reporting interface up before IPv4 or IPv6 protocol
1396 is ready to add routes.
1397 This makes sure the routes are IN the kernel.
1398 */
pauld753e9e2003-01-22 19:45:50 +00001399
Christian Frankefa713d92013-07-05 15:35:37 +00001400 for (ALL_NEXTHOPS_RO(select->nexthop, nexthop, tnexthop, recursing))
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001401 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
paul4d38fdb2005-04-28 17:35:14 +00001402 {
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001403 installed = 1;
1404 break;
paul4d38fdb2005-04-28 17:35:14 +00001405 }
1406 if (! installed)
1407 rib_install_kernel (rn, select);
1408 }
Paul Jakma6d691122006-07-27 21:49:00 +00001409 goto end;
paul718e3742002-12-13 20:15:29 +00001410 }
1411
Denis Ovsienkodc958242007-08-13 16:03:06 +00001412 /* At this point we either haven't found the best RIB entry or it is
1413 * different from what we currently intend to flag with SELECTED. In both
1414 * cases, if a RIB block is present in FIB, it should be withdrawn.
1415 */
paul718e3742002-12-13 20:15:29 +00001416 if (fib)
1417 {
Paul Jakma6d691122006-07-27 21:49:00 +00001418 if (IS_ZEBRA_DEBUG_RIB)
David Lampartere0b0ac82014-04-24 20:22:53 +02001419 rnode_debug (rn, "Removing existing route, fib %p", fib);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001420
1421 zfpm_trigger_update (rn, "removing existing route");
1422
paul718e3742002-12-13 20:15:29 +00001423 redistribute_delete (&rn->p, fib);
1424 if (! RIB_SYSTEM_ROUTE (fib))
1425 rib_uninstall_kernel (rn, fib);
1426 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1427
1428 /* Set real nexthop. */
1429 nexthop_active_update (rn, fib, 1);
1430 }
1431
Denis Ovsienkodc958242007-08-13 16:03:06 +00001432 /* Regardless of some RIB entry being SELECTED or not before, now we can
1433 * tell, that if a new winner exists, FIB is still not updated with this
1434 * data, but ready to be.
1435 */
paul718e3742002-12-13 20:15:29 +00001436 if (select)
1437 {
Paul Jakma6d691122006-07-27 21:49:00 +00001438 if (IS_ZEBRA_DEBUG_RIB)
David Lampartere0b0ac82014-04-24 20:22:53 +02001439 rnode_debug (rn, "Adding route, select %p", select);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001440
1441 zfpm_trigger_update (rn, "new route selected");
1442
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 Lampartere0b0ac82014-04-24 20:22:53 +02001456 rnode_debug (rn, "Deleting fib %p, rn %p", del, 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 Lampartere0b0ac82014-04-24 20:22:53 +02001462 rnode_debug (rn, "rn %p dequeued", 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 Lampartere0b0ac82014-04-24 20:22:53 +02001556 rnode_debug (rn, "rn %p is already queued in sub-queue %u",
1557 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 Lampartere0b0ac82014-04-24 20:22:53 +02001567 rnode_debug (rn, "queued rn %p into sub-queue %u",
1568 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",
1582 __func__, rn, rn->lock);
1583 zlog_backtrace(LOG_DEBUG);
1584 return;
1585 }
1586
1587 if (IS_ZEBRA_DEBUG_RIB_Q)
David Lampartere0b0ac82014-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 Lampartere0b0ac82014-04-24 20:22:53 +02001612 rnode_debug (rn, "rn %p queued", 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
1672 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1673 * 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 Lampartere0b0ac82014-04-24 20:22:53 +02001713 rnode_debug (rn, "rn %p, rib %p", rn, 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 Lampartere0b0ac82014-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 Lampartere0b0ac82014-04-24 20:22:53 +02001746 rnode_debug (rn, "rn %p, un-removed rib %p", rn, rib);
1747
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 Lampartere0b0ac82014-04-24 20:22:53 +02001771 rnode_debug (rn, "rn %p, rib %p", rn, 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 Lampartere0b0ac82014-04-24 20:22:53 +02001795 rnode_debug (rn, "rn %p, rib %p, removing", rn, 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,
1803 unsigned int ifindex, u_int32_t vrf_id,
G.Balajicddf3912011-11-26 21:59:32 +04001804 u_int32_t metric, 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. */
G.Balajicddf3912011-11-26 21:59:32 +04001813 table = vrf_table (AFI_IP, safi, 0);
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;
paulb5f45022003-11-02 07:28:05 +00001867 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001868 rib->nexthop_num = 0;
1869 rib->uptime = time (NULL);
1870
1871 /* Nexthop settings. */
1872 if (gate)
1873 {
1874 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001875 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001876 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001877 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001878 }
1879 else
1880 nexthop_ifindex_add (rib, ifindex);
1881
1882 /* If this route is kernel route, set FIB flag to the route. */
1883 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1884 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1885 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1886
1887 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001888 if (IS_ZEBRA_DEBUG_RIB)
1889 zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
paul718e3742002-12-13 20:15:29 +00001890 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001891
paul718e3742002-12-13 20:15:29 +00001892 /* Free implicit route.*/
1893 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001894 {
1895 if (IS_ZEBRA_DEBUG_RIB)
1896 zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001897 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001898 }
paul4d38fdb2005-04-28 17:35:14 +00001899
1900 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001901 return 0;
1902}
1903
Denis Ovsienkodc958242007-08-13 16:03:06 +00001904/* This function dumps the contents of a given RIB entry into
1905 * standard debug log. Calling function name and IP prefix in
1906 * question are passed as 1st and 2nd arguments.
1907 */
1908
David Lamparterf7bf4152013-10-22 17:10:21 +00001909void _rib_dump (const char * func,
1910 union prefix46constptr pp, const struct rib * rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001911{
David Lamparterf7bf4152013-10-22 17:10:21 +00001912 const struct prefix *p = pp.p;
Vincent Bernatfed643f2012-10-23 16:00:42 +00001913 char straddr[INET6_ADDRSTRLEN];
Christian Frankefa713d92013-07-05 15:35:37 +00001914 struct nexthop *nexthop, *tnexthop;
1915 int recursing;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001916
Vincent Bernatfed643f2012-10-23 16:00:42 +00001917 inet_ntop (p->family, &p->u.prefix, straddr, INET6_ADDRSTRLEN);
Christian Frankefa713d92013-07-05 15:35:37 +00001918 zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr, p->prefixlen);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001919 zlog_debug
1920 (
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001921 "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
Denis Ovsienkodc958242007-08-13 16:03:06 +00001922 func,
1923 rib->refcnt,
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001924 (unsigned long) rib->uptime,
Denis Ovsienkodc958242007-08-13 16:03:06 +00001925 rib->type,
1926 rib->table
1927 );
1928 zlog_debug
1929 (
1930 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1931 func,
1932 rib->metric,
1933 rib->distance,
1934 rib->flags,
1935 rib->status
1936 );
1937 zlog_debug
1938 (
1939 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1940 func,
1941 rib->nexthop_num,
1942 rib->nexthop_active_num,
1943 rib->nexthop_fib_num
1944 );
Vincent Bernatfed643f2012-10-23 16:00:42 +00001945
Christian Frankefa713d92013-07-05 15:35:37 +00001946 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1947 {
Vincent Bernatfed643f2012-10-23 16:00:42 +00001948 inet_ntop (p->family, &nexthop->gate, straddr, INET6_ADDRSTRLEN);
Christian Frankefa713d92013-07-05 15:35:37 +00001949 zlog_debug
1950 (
1951 "%s: %s %s with flags %s%s%s",
1952 func,
1953 (recursing ? " NH" : "NH"),
1954 straddr,
1955 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1956 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1957 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1958 );
1959 }
Denis Ovsienkodc958242007-08-13 16:03:06 +00001960 zlog_debug ("%s: dump complete", func);
1961}
1962
1963/* This is an exported helper to rtm_read() to dump the strange
1964 * RIB entry found by rib_lookup_ipv4_route()
1965 */
1966
1967void rib_lookup_and_dump (struct prefix_ipv4 * p)
1968{
1969 struct route_table *table;
1970 struct route_node *rn;
1971 struct rib *rib;
1972 char prefix_buf[INET_ADDRSTRLEN];
1973
1974 /* Lookup table. */
1975 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1976 if (! table)
1977 {
1978 zlog_err ("%s: vrf_table() returned NULL", __func__);
1979 return;
1980 }
1981
1982 inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
1983 /* Scan the RIB table for exactly matching RIB entry. */
1984 rn = route_node_lookup (table, (struct prefix *) p);
1985
1986 /* No route for this prefix. */
1987 if (! rn)
1988 {
1989 zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
1990 return;
1991 }
1992
1993 /* Unlock node. */
1994 route_unlock_node (rn);
1995
1996 /* let's go */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001997 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001998 {
1999 zlog_debug
2000 (
2001 "%s: rn %p, rib %p: %s, %s",
2002 __func__,
2003 rn,
2004 rib,
2005 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
2006 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
2007 );
David Lamparterf7bf4152013-10-22 17:10:21 +00002008 rib_dump (p, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002009 }
2010}
2011
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002012/* Check if requested address assignment will fail due to another
2013 * route being installed by zebra in FIB already. Take necessary
2014 * actions, if needed: remove such a route from FIB and deSELECT
2015 * corresponding RIB entry. Then put affected RN into RIBQ head.
2016 */
2017void rib_lookup_and_pushup (struct prefix_ipv4 * p)
2018{
2019 struct route_table *table;
2020 struct route_node *rn;
2021 struct rib *rib;
2022 unsigned changed = 0;
2023
2024 if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
2025 {
2026 zlog_err ("%s: vrf_table() returned NULL", __func__);
2027 return;
2028 }
2029
2030 /* No matches would be the simplest case. */
2031 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
2032 return;
2033
2034 /* Unlock node. */
2035 route_unlock_node (rn);
2036
2037 /* Check all RIB entries. In case any changes have to be done, requeue
2038 * the RN into RIBQ head. If the routing message about the new connected
2039 * route (generated by the IP address we are going to assign very soon)
2040 * comes before the RIBQ is processed, the new RIB entry will join
2041 * RIBQ record already on head. This is necessary for proper revalidation
2042 * of the rest of the RIB.
2043 */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002044 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002045 {
2046 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
2047 ! RIB_SYSTEM_ROUTE (rib))
2048 {
2049 changed = 1;
2050 if (IS_ZEBRA_DEBUG_RIB)
2051 {
2052 char buf[INET_ADDRSTRLEN];
2053 inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
2054 zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
David Lamparterf7bf4152013-10-22 17:10:21 +00002055 rib_dump (&rn->p, rib);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002056 }
2057 rib_uninstall (rn, rib);
2058 }
2059 }
2060 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002061 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002062}
2063
paul718e3742002-12-13 20:15:29 +00002064int
G.Balajicddf3912011-11-26 21:59:32 +04002065rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002066{
2067 struct route_table *table;
2068 struct route_node *rn;
2069 struct rib *same;
2070 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00002071
paul718e3742002-12-13 20:15:29 +00002072 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04002073 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00002074 if (! table)
2075 return 0;
G.Balajicddf3912011-11-26 21:59:32 +04002076
paul718e3742002-12-13 20:15:29 +00002077 /* Make it sure prefixlen is applied to the prefix. */
2078 apply_mask_ipv4 (p);
2079
2080 /* Set default distance by route type. */
2081 if (rib->distance == 0)
2082 {
2083 rib->distance = route_info[rib->type].distance;
2084
2085 /* iBGP distance is 200. */
2086 if (rib->type == ZEBRA_ROUTE_BGP
2087 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
2088 rib->distance = 200;
2089 }
2090
2091 /* Lookup route node.*/
2092 rn = route_node_get (table, (struct prefix *) p);
2093
2094 /* If same type of route are installed, treat it as a implicit
2095 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002096 RNODE_FOREACH_RIB (rn, same)
paul718e3742002-12-13 20:15:29 +00002097 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00002098 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00002099 continue;
2100
paul718e3742002-12-13 20:15:29 +00002101 if (same->type == rib->type && same->table == rib->table
2102 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00002103 break;
paul718e3742002-12-13 20:15:29 +00002104 }
paul4d38fdb2005-04-28 17:35:14 +00002105
paul718e3742002-12-13 20:15:29 +00002106 /* If this route is kernel route, set FIB flag to the route. */
2107 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
2108 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2109 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2110
2111 /* Link new rib to node.*/
2112 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002113 if (IS_ZEBRA_DEBUG_RIB)
2114 {
2115 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
2116 __func__, rn, rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00002117 rib_dump (p, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002118 }
paul718e3742002-12-13 20:15:29 +00002119
paul718e3742002-12-13 20:15:29 +00002120 /* Free implicit route.*/
2121 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00002122 {
2123 if (IS_ZEBRA_DEBUG_RIB)
2124 {
2125 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
2126 __func__, rn, same);
David Lamparterf7bf4152013-10-22 17:10:21 +00002127 rib_dump (p, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002128 }
paul4d38fdb2005-04-28 17:35:14 +00002129 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002130 }
paul4d38fdb2005-04-28 17:35:14 +00002131
2132 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002133 return 0;
2134}
2135
hassoebf1ead2005-09-21 14:58:20 +00002136/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002137int
2138rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
G.Balajicddf3912011-11-26 21:59:32 +04002139 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002140{
2141 struct route_table *table;
2142 struct route_node *rn;
2143 struct rib *rib;
2144 struct rib *fib = NULL;
2145 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002146 struct nexthop *nexthop, *tnexthop;
2147 int recursing;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002148 char buf1[INET_ADDRSTRLEN];
2149 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002150
2151 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04002152 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00002153 if (! table)
2154 return 0;
2155
2156 /* Apply mask. */
2157 apply_mask_ipv4 (p);
2158
Christian Frankeb52aef12013-11-27 17:06:15 +00002159 if (IS_ZEBRA_DEBUG_KERNEL)
2160 {
2161 if (gate)
2162 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
2163 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
2164 p->prefixlen,
2165 inet_ntoa (*gate),
2166 ifindex);
2167 else
2168 zlog_debug ("rib_delete_ipv4(): route delete %s/%d ifindex %d",
2169 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
2170 p->prefixlen,
2171 ifindex);
2172 }
paul5ec90d22003-06-19 01:41:37 +00002173
paul718e3742002-12-13 20:15:29 +00002174 /* Lookup route node. */
2175 rn = route_node_lookup (table, (struct prefix *) p);
2176 if (! rn)
2177 {
2178 if (IS_ZEBRA_DEBUG_KERNEL)
2179 {
2180 if (gate)
ajsb6178002004-12-07 21:12:56 +00002181 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002182 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002183 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002184 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002185 ifindex);
2186 else
ajsb6178002004-12-07 21:12:56 +00002187 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002188 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002189 p->prefixlen,
2190 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)
ajsb6178002004-12-07 21:12:56 +00002256 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002257 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002258 p->prefixlen,
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
ajsb6178002004-12-07 21:12:56 +00002263 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002264 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002265 p->prefixlen,
2266 ifindex,
2267 type);
2268 }
2269 route_unlock_node (rn);
2270 return ZEBRA_ERR_RTNOEXIST;
2271 }
2272 }
paul4d38fdb2005-04-28 17:35:14 +00002273
paul718e3742002-12-13 20:15:29 +00002274 if (same)
2275 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002276
paul718e3742002-12-13 20:15:29 +00002277 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002278 return 0;
2279}
David Lamparter6b0655a2014-06-04 06:53:35 +02002280
paul718e3742002-12-13 20:15:29 +00002281/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002282static void
paul718e3742002-12-13 20:15:29 +00002283static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
2284{
2285 struct rib *rib;
2286 struct route_node *rn;
2287 struct route_table *table;
2288
2289 /* Lookup table. */
2290 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2291 if (! table)
2292 return;
2293
2294 /* Lookup existing route */
2295 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002296 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002297 {
2298 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2299 continue;
2300
2301 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2302 break;
2303 }
paul718e3742002-12-13 20:15:29 +00002304
2305 if (rib)
2306 {
2307 /* Same distance static route is there. Update it with new
2308 nexthop. */
paul718e3742002-12-13 20:15:29 +00002309 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002310 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002311 {
2312 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002313 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002314 break;
2315 case STATIC_IPV4_IFNAME:
2316 nexthop_ifname_add (rib, si->gate.ifname);
2317 break;
2318 case STATIC_IPV4_BLACKHOLE:
2319 nexthop_blackhole_add (rib);
2320 break;
paul4d38fdb2005-04-28 17:35:14 +00002321 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002322 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002323 }
2324 else
2325 {
2326 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002327 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2328
paul718e3742002-12-13 20:15:29 +00002329 rib->type = ZEBRA_ROUTE_STATIC;
2330 rib->distance = si->distance;
2331 rib->metric = 0;
Nolan Leakeb0145dd2012-09-13 17:17:31 +00002332 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002333 rib->nexthop_num = 0;
2334
2335 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002336 {
2337 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002338 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002339 break;
2340 case STATIC_IPV4_IFNAME:
2341 nexthop_ifname_add (rib, si->gate.ifname);
2342 break;
2343 case STATIC_IPV4_BLACKHOLE:
2344 nexthop_blackhole_add (rib);
2345 break;
2346 }
paul718e3742002-12-13 20:15:29 +00002347
hasso81dfcaa2003-05-25 19:21:25 +00002348 /* Save the flags of this static routes (reject, blackhole) */
2349 rib->flags = si->flags;
2350
paul718e3742002-12-13 20:15:29 +00002351 /* Link this rib to the tree. */
2352 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002353 }
2354}
2355
paula1ac18c2005-06-28 17:17:12 +00002356static int
paul718e3742002-12-13 20:15:29 +00002357static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2358{
2359 if (nexthop->type == NEXTHOP_TYPE_IPV4
2360 && si->type == STATIC_IPV4_GATEWAY
2361 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2362 return 1;
2363 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2364 && si->type == STATIC_IPV4_IFNAME
2365 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2366 return 1;
paul595db7f2003-05-25 21:35:06 +00002367 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2368 && si->type == STATIC_IPV4_BLACKHOLE)
2369 return 1;
paule8e19462006-01-19 20:16:55 +00002370 return 0;
paul718e3742002-12-13 20:15:29 +00002371}
2372
2373/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002374static void
paul718e3742002-12-13 20:15:29 +00002375static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
2376{
2377 struct route_node *rn;
2378 struct rib *rib;
2379 struct nexthop *nexthop;
2380 struct route_table *table;
2381
2382 /* Lookup table. */
2383 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2384 if (! table)
2385 return;
paul4d38fdb2005-04-28 17:35:14 +00002386
paul718e3742002-12-13 20:15:29 +00002387 /* Lookup existing route with type and distance. */
2388 rn = route_node_lookup (table, p);
2389 if (! rn)
2390 return;
2391
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002392 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002393 {
2394 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2395 continue;
2396
2397 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2398 break;
2399 }
paul718e3742002-12-13 20:15:29 +00002400
2401 if (! rib)
2402 {
2403 route_unlock_node (rn);
2404 return;
2405 }
2406
2407 /* Lookup nexthop. */
2408 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2409 if (static_ipv4_nexthop_same (nexthop, si))
2410 break;
2411
2412 /* Can't find nexthop. */
2413 if (! nexthop)
2414 {
2415 route_unlock_node (rn);
2416 return;
2417 }
2418
2419 /* Check nexthop. */
2420 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002421 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002422 else
2423 {
paul6baeb982003-10-28 03:47:15 +00002424 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2425 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002426 nexthop_delete (rib, nexthop);
2427 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002428 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002429 }
paul718e3742002-12-13 20:15:29 +00002430 /* Unlock node. */
2431 route_unlock_node (rn);
2432}
2433
2434/* Add static route into static route configuration. */
2435int
hasso39db97e2004-10-12 20:50:58 +00002436static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00002437 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002438{
2439 u_char type = 0;
2440 struct route_node *rn;
2441 struct static_ipv4 *si;
2442 struct static_ipv4 *pp;
2443 struct static_ipv4 *cp;
2444 struct static_ipv4 *update = NULL;
2445 struct route_table *stable;
2446
2447 /* Lookup table. */
2448 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2449 if (! stable)
2450 return -1;
2451
2452 /* Lookup static route prefix. */
2453 rn = route_node_get (stable, p);
2454
2455 /* Make flags. */
2456 if (gate)
2457 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002458 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002459 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002460 else
2461 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002462
2463 /* Do nothing if there is a same static route. */
2464 for (si = rn->info; si; si = si->next)
2465 {
2466 if (type == si->type
2467 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2468 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2469 {
2470 if (distance == si->distance)
2471 {
2472 route_unlock_node (rn);
2473 return 0;
2474 }
2475 else
2476 update = si;
2477 }
2478 }
2479
Paul Jakma3c0755d2006-12-08 00:53:14 +00002480 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002481 if (update)
2482 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
2483
2484 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002485 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
paul718e3742002-12-13 20:15:29 +00002486
2487 si->type = type;
2488 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002489 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002490
2491 if (gate)
2492 si->gate.ipv4 = *gate;
2493 if (ifname)
2494 si->gate.ifname = XSTRDUP (0, ifname);
2495
2496 /* Add new static route information to the tree with sort by
2497 distance value and gateway address. */
2498 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2499 {
2500 if (si->distance < cp->distance)
2501 break;
2502 if (si->distance > cp->distance)
2503 continue;
2504 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2505 {
2506 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2507 break;
2508 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2509 continue;
2510 }
2511 }
2512
2513 /* Make linked list. */
2514 if (pp)
2515 pp->next = si;
2516 else
2517 rn->info = si;
2518 if (cp)
2519 cp->prev = si;
2520 si->prev = pp;
2521 si->next = cp;
2522
2523 /* Install into rib. */
2524 static_install_ipv4 (p, si);
2525
2526 return 1;
2527}
2528
2529/* Delete static route from static route configuration. */
2530int
hasso39db97e2004-10-12 20:50:58 +00002531static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00002532 u_char distance, u_int32_t vrf_id)
2533{
2534 u_char type = 0;
2535 struct route_node *rn;
2536 struct static_ipv4 *si;
2537 struct route_table *stable;
2538
2539 /* Lookup table. */
2540 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2541 if (! stable)
2542 return -1;
2543
2544 /* Lookup static route prefix. */
2545 rn = route_node_lookup (stable, p);
2546 if (! rn)
2547 return 0;
2548
2549 /* Make flags. */
2550 if (gate)
2551 type = STATIC_IPV4_GATEWAY;
2552 else if (ifname)
2553 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002554 else
2555 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002556
2557 /* Find same static route is the tree */
2558 for (si = rn->info; si; si = si->next)
2559 if (type == si->type
2560 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2561 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2562 break;
2563
2564 /* Can't find static route. */
2565 if (! si)
2566 {
2567 route_unlock_node (rn);
2568 return 0;
2569 }
2570
2571 /* Install into rib. */
2572 static_uninstall_ipv4 (p, si);
2573
2574 /* Unlink static route from linked list. */
2575 if (si->prev)
2576 si->prev->next = si->next;
2577 else
2578 rn->info = si->next;
2579 if (si->next)
2580 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002581 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002582
2583 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002584 if (ifname)
2585 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002586 XFREE (MTYPE_STATIC_IPV4, si);
2587
paul143a3852003-09-29 20:06:13 +00002588 route_unlock_node (rn);
2589
paul718e3742002-12-13 20:15:29 +00002590 return 1;
2591}
2592
David Lamparter6b0655a2014-06-04 06:53:35 +02002593
paul718e3742002-12-13 20:15:29 +00002594#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00002595static int
paul718e3742002-12-13 20:15:29 +00002596rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2597 struct in6_addr *gate, unsigned int ifindex, int table)
2598{
hasso726f9b22003-05-25 21:04:54 +00002599 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2600#if defined (MUSICA) || defined (LINUX)
2601 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2602 if (p->prefixlen == 96)
2603 return 0;
2604#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00002605 return 1;
hasso726f9b22003-05-25 21:04:54 +00002606 }
paul718e3742002-12-13 20:15:29 +00002607 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
2608 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
2609 {
2610 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
2611 return 1;
2612 }
2613 return 0;
2614}
2615
2616int
2617rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00002618 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
G.Balajif768f362011-11-26 22:10:39 +04002619 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002620{
2621 struct rib *rib;
2622 struct rib *same = NULL;
2623 struct route_table *table;
2624 struct route_node *rn;
2625 struct nexthop *nexthop;
2626
paul718e3742002-12-13 20:15:29 +00002627 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002628 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002629 if (! table)
2630 return 0;
2631
2632 /* Make sure mask is applied. */
2633 apply_mask_ipv6 (p);
2634
2635 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002636 if (!distance)
2637 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002638
2639 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2640 distance = 200;
2641
2642 /* Filter bogus route. */
2643 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
2644 return 0;
2645
2646 /* Lookup route node.*/
2647 rn = route_node_get (table, (struct prefix *) p);
2648
2649 /* If same type of route are installed, treat it as a implicit
2650 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002651 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002652 {
Paul Jakma6d691122006-07-27 21:49:00 +00002653 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2654 continue;
2655
hassoebf1ead2005-09-21 14:58:20 +00002656 if (rib->type != type)
2657 continue;
2658 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002659 {
2660 same = rib;
paul718e3742002-12-13 20:15:29 +00002661 break;
2662 }
hassoebf1ead2005-09-21 14:58:20 +00002663 else if ((nexthop = rib->nexthop) &&
2664 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2665 nexthop->ifindex == ifindex)
2666 {
2667 rib->refcnt++;
2668 return 0;
2669 }
paul718e3742002-12-13 20:15:29 +00002670 }
2671
2672 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002673 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2674
paul718e3742002-12-13 20:15:29 +00002675 rib->type = type;
2676 rib->distance = distance;
2677 rib->flags = flags;
2678 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00002679 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00002680 rib->nexthop_num = 0;
2681 rib->uptime = time (NULL);
2682
2683 /* Nexthop settings. */
2684 if (gate)
2685 {
2686 if (ifindex)
2687 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2688 else
2689 nexthop_ipv6_add (rib, gate);
2690 }
2691 else
2692 nexthop_ifindex_add (rib, ifindex);
2693
2694 /* If this route is kernel route, set FIB flag to the route. */
2695 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2696 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2697 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2698
2699 /* Link new rib to node.*/
2700 rib_addnode (rn, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002701 if (IS_ZEBRA_DEBUG_RIB)
2702 {
2703 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
2704 __func__, rn, rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00002705 rib_dump (p, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002706 }
paul718e3742002-12-13 20:15:29 +00002707
paul718e3742002-12-13 20:15:29 +00002708 /* Free implicit route.*/
2709 if (same)
Vincent Bernatfed643f2012-10-23 16:00:42 +00002710 {
2711 if (IS_ZEBRA_DEBUG_RIB)
2712 {
2713 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
2714 __func__, rn, same);
David Lamparterf7bf4152013-10-22 17:10:21 +00002715 rib_dump (p, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002716 }
paul4d38fdb2005-04-28 17:35:14 +00002717 rib_delnode (rn, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002718 }
paul4d38fdb2005-04-28 17:35:14 +00002719
2720 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002721 return 0;
2722}
2723
hassoebf1ead2005-09-21 14:58:20 +00002724/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002725int
2726rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
G.Balajif768f362011-11-26 22:10:39 +04002727 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002728{
2729 struct route_table *table;
2730 struct route_node *rn;
2731 struct rib *rib;
2732 struct rib *fib = NULL;
2733 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002734 struct nexthop *nexthop, *tnexthop;
2735 int recursing;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002736 char buf1[INET6_ADDRSTRLEN];
2737 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002738
2739 /* Apply mask. */
2740 apply_mask_ipv6 (p);
2741
2742 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002743 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002744 if (! table)
2745 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002746
paul718e3742002-12-13 20:15:29 +00002747 /* Lookup route node. */
2748 rn = route_node_lookup (table, (struct prefix *) p);
2749 if (! rn)
2750 {
2751 if (IS_ZEBRA_DEBUG_KERNEL)
2752 {
2753 if (gate)
ajsb6178002004-12-07 21:12:56 +00002754 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002755 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002756 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002757 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002758 ifindex);
2759 else
ajsb6178002004-12-07 21:12:56 +00002760 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002761 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002762 p->prefixlen,
2763 ifindex);
2764 }
2765 return ZEBRA_ERR_RTNOEXIST;
2766 }
2767
2768 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002769 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002770 {
Paul Jakma6d691122006-07-27 21:49:00 +00002771 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2772 continue;
2773
paul718e3742002-12-13 20:15:29 +00002774 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2775 fib = rib;
2776
hassoebf1ead2005-09-21 14:58:20 +00002777 if (rib->type != type)
2778 continue;
2779 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002780 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002781 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002782 if (nexthop->ifindex != ifindex)
2783 continue;
hassoebf1ead2005-09-21 14:58:20 +00002784 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002785 {
hassoebf1ead2005-09-21 14:58:20 +00002786 rib->refcnt--;
2787 route_unlock_node (rn);
2788 route_unlock_node (rn);
2789 return 0;
paul718e3742002-12-13 20:15:29 +00002790 }
hassoebf1ead2005-09-21 14:58:20 +00002791 same = rib;
2792 break;
paul718e3742002-12-13 20:15:29 +00002793 }
hassoebf1ead2005-09-21 14:58:20 +00002794 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002795 else
2796 {
2797 if (gate == NULL)
2798 {
2799 same = rib;
2800 break;
2801 }
2802 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2803 if (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate))
2804 {
2805 same = rib;
2806 break;
2807 }
2808 if (same)
2809 break;
2810 }
paul718e3742002-12-13 20:15:29 +00002811 }
2812
2813 /* If same type of route can't be found and this message is from
2814 kernel. */
2815 if (! same)
2816 {
2817 if (fib && type == ZEBRA_ROUTE_KERNEL)
2818 {
2819 /* Unset flags. */
2820 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2821 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2822
2823 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2824 }
2825 else
2826 {
2827 if (IS_ZEBRA_DEBUG_KERNEL)
2828 {
2829 if (gate)
ajsb6178002004-12-07 21:12:56 +00002830 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002831 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002832 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002833 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002834 ifindex,
2835 type);
2836 else
ajsb6178002004-12-07 21:12:56 +00002837 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002838 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002839 p->prefixlen,
2840 ifindex,
2841 type);
2842 }
2843 route_unlock_node (rn);
2844 return ZEBRA_ERR_RTNOEXIST;
2845 }
2846 }
2847
2848 if (same)
2849 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002850
paul718e3742002-12-13 20:15:29 +00002851 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002852 return 0;
2853}
David Lamparter6b0655a2014-06-04 06:53:35 +02002854
paul718e3742002-12-13 20:15:29 +00002855/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002856static void
paul718e3742002-12-13 20:15:29 +00002857static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2858{
2859 struct rib *rib;
2860 struct route_table *table;
2861 struct route_node *rn;
2862
2863 /* Lookup table. */
2864 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2865 if (! table)
2866 return;
2867
2868 /* Lookup existing route */
2869 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002870 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002871 {
2872 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2873 continue;
2874
2875 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2876 break;
2877 }
paul718e3742002-12-13 20:15:29 +00002878
2879 if (rib)
2880 {
2881 /* Same distance static route is there. Update it with new
2882 nexthop. */
paul718e3742002-12-13 20:15:29 +00002883 route_unlock_node (rn);
2884
2885 switch (si->type)
2886 {
2887 case STATIC_IPV6_GATEWAY:
2888 nexthop_ipv6_add (rib, &si->ipv6);
2889 break;
2890 case STATIC_IPV6_IFNAME:
2891 nexthop_ifname_add (rib, si->ifname);
2892 break;
2893 case STATIC_IPV6_GATEWAY_IFNAME:
2894 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2895 break;
2896 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002897 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002898 }
2899 else
2900 {
2901 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002902 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2903
paul718e3742002-12-13 20:15:29 +00002904 rib->type = ZEBRA_ROUTE_STATIC;
2905 rib->distance = si->distance;
2906 rib->metric = 0;
Dinesh G Duttd1b09912014-09-30 12:54:13 -07002907 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002908 rib->nexthop_num = 0;
2909
2910 switch (si->type)
2911 {
2912 case STATIC_IPV6_GATEWAY:
2913 nexthop_ipv6_add (rib, &si->ipv6);
2914 break;
2915 case STATIC_IPV6_IFNAME:
2916 nexthop_ifname_add (rib, si->ifname);
2917 break;
2918 case STATIC_IPV6_GATEWAY_IFNAME:
2919 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2920 break;
2921 }
2922
hasso81dfcaa2003-05-25 19:21:25 +00002923 /* Save the flags of this static routes (reject, blackhole) */
2924 rib->flags = si->flags;
2925
paul718e3742002-12-13 20:15:29 +00002926 /* Link this rib to the tree. */
2927 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002928 }
2929}
2930
paula1ac18c2005-06-28 17:17:12 +00002931static int
paul718e3742002-12-13 20:15:29 +00002932static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2933{
2934 if (nexthop->type == NEXTHOP_TYPE_IPV6
2935 && si->type == STATIC_IPV6_GATEWAY
2936 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2937 return 1;
2938 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2939 && si->type == STATIC_IPV6_IFNAME
2940 && strcmp (nexthop->ifname, si->ifname) == 0)
2941 return 1;
2942 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2943 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2944 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2945 && strcmp (nexthop->ifname, si->ifname) == 0)
2946 return 1;
paule8e19462006-01-19 20:16:55 +00002947 return 0;
paul718e3742002-12-13 20:15:29 +00002948}
2949
paula1ac18c2005-06-28 17:17:12 +00002950static void
paul718e3742002-12-13 20:15:29 +00002951static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2952{
2953 struct route_table *table;
2954 struct route_node *rn;
2955 struct rib *rib;
2956 struct nexthop *nexthop;
2957
2958 /* Lookup table. */
2959 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2960 if (! table)
2961 return;
2962
2963 /* Lookup existing route with type and distance. */
2964 rn = route_node_lookup (table, (struct prefix *) p);
2965 if (! rn)
2966 return;
2967
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002968 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002969 {
2970 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2971 continue;
2972
2973 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2974 break;
2975 }
2976
paul718e3742002-12-13 20:15:29 +00002977 if (! rib)
2978 {
2979 route_unlock_node (rn);
2980 return;
2981 }
2982
2983 /* Lookup nexthop. */
2984 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2985 if (static_ipv6_nexthop_same (nexthop, si))
2986 break;
2987
2988 /* Can't find nexthop. */
2989 if (! nexthop)
2990 {
2991 route_unlock_node (rn);
2992 return;
2993 }
2994
2995 /* Check nexthop. */
2996 if (rib->nexthop_num == 1)
2997 {
2998 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002999 }
3000 else
3001 {
paul6baeb982003-10-28 03:47:15 +00003002 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
3003 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00003004 nexthop_delete (rib, nexthop);
3005 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00003006 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003007 }
paul718e3742002-12-13 20:15:29 +00003008 /* Unlock node. */
3009 route_unlock_node (rn);
3010}
3011
3012/* Add static route into static route configuration. */
3013int
3014static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00003015 const char *ifname, u_char flags, u_char distance,
3016 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00003017{
3018 struct route_node *rn;
3019 struct static_ipv6 *si;
3020 struct static_ipv6 *pp;
3021 struct static_ipv6 *cp;
3022 struct route_table *stable;
3023
3024 /* Lookup table. */
3025 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
3026 if (! stable)
3027 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00003028
3029 if (!gate &&
3030 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
3031 return -1;
3032
3033 if (!ifname &&
3034 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
3035 return -1;
paul718e3742002-12-13 20:15:29 +00003036
3037 /* Lookup static route prefix. */
3038 rn = route_node_get (stable, p);
3039
3040 /* Do nothing if there is a same static route. */
3041 for (si = rn->info; si; si = si->next)
3042 {
3043 if (distance == si->distance
3044 && type == si->type
3045 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
3046 && (! ifname || strcmp (ifname, si->ifname) == 0))
3047 {
3048 route_unlock_node (rn);
3049 return 0;
3050 }
3051 }
3052
3053 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07003054 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
paul718e3742002-12-13 20:15:29 +00003055
3056 si->type = type;
3057 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00003058 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00003059
3060 switch (type)
3061 {
3062 case STATIC_IPV6_GATEWAY:
3063 si->ipv6 = *gate;
3064 break;
3065 case STATIC_IPV6_IFNAME:
3066 si->ifname = XSTRDUP (0, ifname);
3067 break;
3068 case STATIC_IPV6_GATEWAY_IFNAME:
3069 si->ipv6 = *gate;
3070 si->ifname = XSTRDUP (0, ifname);
3071 break;
3072 }
3073
3074 /* Add new static route information to the tree with sort by
3075 distance value and gateway address. */
3076 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
3077 {
3078 if (si->distance < cp->distance)
3079 break;
3080 if (si->distance > cp->distance)
3081 continue;
3082 }
3083
3084 /* Make linked list. */
3085 if (pp)
3086 pp->next = si;
3087 else
3088 rn->info = si;
3089 if (cp)
3090 cp->prev = si;
3091 si->prev = pp;
3092 si->next = cp;
3093
3094 /* Install into rib. */
3095 static_install_ipv6 (p, si);
3096
3097 return 1;
3098}
3099
3100/* Delete static route from static route configuration. */
3101int
3102static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00003103 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00003104{
3105 struct route_node *rn;
3106 struct static_ipv6 *si;
3107 struct route_table *stable;
3108
3109 /* Lookup table. */
3110 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
3111 if (! stable)
3112 return -1;
3113
3114 /* Lookup static route prefix. */
3115 rn = route_node_lookup (stable, p);
3116 if (! rn)
3117 return 0;
3118
3119 /* Find same static route is the tree */
3120 for (si = rn->info; si; si = si->next)
3121 if (distance == si->distance
3122 && type == si->type
3123 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
3124 && (! ifname || strcmp (ifname, si->ifname) == 0))
3125 break;
3126
3127 /* Can't find static route. */
3128 if (! si)
3129 {
3130 route_unlock_node (rn);
3131 return 0;
3132 }
3133
3134 /* Install into rib. */
3135 static_uninstall_ipv6 (p, si);
3136
3137 /* Unlink static route from linked list. */
3138 if (si->prev)
3139 si->prev->next = si->next;
3140 else
3141 rn->info = si->next;
3142 if (si->next)
3143 si->next->prev = si->prev;
3144
3145 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00003146 if (ifname)
3147 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00003148 XFREE (MTYPE_STATIC_IPV6, si);
3149
3150 return 1;
3151}
3152#endif /* HAVE_IPV6 */
David Lamparter6b0655a2014-06-04 06:53:35 +02003153
paul718e3742002-12-13 20:15:29 +00003154/* RIB update function. */
3155void
paula1ac18c2005-06-28 17:17:12 +00003156rib_update (void)
paul718e3742002-12-13 20:15:29 +00003157{
3158 struct route_node *rn;
3159 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00003160
paul718e3742002-12-13 20:15:29 +00003161 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
3162 if (table)
3163 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003164 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003165 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003166
3167 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
3168 if (table)
3169 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003170 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003171 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003172}
3173
David Lamparter6b0655a2014-06-04 06:53:35 +02003174
paul718e3742002-12-13 20:15:29 +00003175/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00003176static void
paul718e3742002-12-13 20:15:29 +00003177rib_weed_table (struct route_table *table)
3178{
3179 struct route_node *rn;
3180 struct rib *rib;
3181 struct rib *next;
3182
3183 if (table)
3184 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003185 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003186 {
Paul Jakma6d691122006-07-27 21:49:00 +00003187 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3188 continue;
3189
paulb21b19c2003-06-15 01:28:29 +00003190 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00003191 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00003192 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003193 }
3194}
3195
3196/* Delete all routes from non main table. */
3197void
paula1ac18c2005-06-28 17:17:12 +00003198rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00003199{
3200 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3201 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3202}
David Lamparter6b0655a2014-06-04 06:53:35 +02003203
paul718e3742002-12-13 20:15:29 +00003204/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00003205static void
paul718e3742002-12-13 20:15:29 +00003206rib_sweep_table (struct route_table *table)
3207{
3208 struct route_node *rn;
3209 struct rib *rib;
3210 struct rib *next;
3211 int ret = 0;
3212
3213 if (table)
3214 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003215 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003216 {
Paul Jakma6d691122006-07-27 21:49:00 +00003217 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3218 continue;
3219
paul718e3742002-12-13 20:15:29 +00003220 if (rib->type == ZEBRA_ROUTE_KERNEL &&
3221 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
3222 {
3223 ret = rib_uninstall_kernel (rn, rib);
3224 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00003225 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003226 }
3227 }
3228}
3229
3230/* Sweep all RIB tables. */
3231void
paula1ac18c2005-06-28 17:17:12 +00003232rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00003233{
3234 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3235 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3236}
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003237
3238/* Remove specific by protocol routes from 'table'. */
3239static unsigned long
3240rib_score_proto_table (u_char proto, struct route_table *table)
3241{
3242 struct route_node *rn;
3243 struct rib *rib;
3244 struct rib *next;
3245 unsigned long n = 0;
3246
3247 if (table)
3248 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003249 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003250 {
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003251 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3252 continue;
3253 if (rib->type == proto)
3254 {
3255 rib_delnode (rn, rib);
3256 n++;
3257 }
3258 }
3259
3260 return n;
3261}
3262
3263/* Remove specific by protocol routes. */
3264unsigned long
3265rib_score_proto (u_char proto)
3266{
3267 return rib_score_proto_table (proto, vrf_table (AFI_IP, SAFI_UNICAST, 0))
3268 +rib_score_proto_table (proto, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3269}
3270
paul718e3742002-12-13 20:15:29 +00003271/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00003272static void
paul718e3742002-12-13 20:15:29 +00003273rib_close_table (struct route_table *table)
3274{
3275 struct route_node *rn;
3276 struct rib *rib;
3277
3278 if (table)
3279 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003280 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00003281 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003282 if (!CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
3283 continue;
3284
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00003285 zfpm_trigger_update (rn, NULL);
3286
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003287 if (! RIB_SYSTEM_ROUTE (rib))
3288 rib_uninstall_kernel (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00003289 }
paul718e3742002-12-13 20:15:29 +00003290}
3291
3292/* Close all RIB tables. */
3293void
paula1ac18c2005-06-28 17:17:12 +00003294rib_close (void)
paul718e3742002-12-13 20:15:29 +00003295{
3296 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3297 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3298}
David Lamparter6b0655a2014-06-04 06:53:35 +02003299
paul718e3742002-12-13 20:15:29 +00003300/* Routing information base initialize. */
3301void
paula1ac18c2005-06-28 17:17:12 +00003302rib_init (void)
paul718e3742002-12-13 20:15:29 +00003303{
paul4d38fdb2005-04-28 17:35:14 +00003304 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00003305 /* VRF initialization. */
3306 vrf_init ();
3307}
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003308
3309/*
3310 * vrf_id_get_next
3311 *
3312 * Get the first vrf id that is greater than the given vrf id if any.
3313 *
3314 * Returns TRUE if a vrf id was found, FALSE otherwise.
3315 */
3316static inline int
3317vrf_id_get_next (uint32_t id, uint32_t *next_id_p)
3318{
3319 while (++id < vector_active (vrf_vector))
3320 {
3321 if (vrf_lookup (id))
3322 {
3323 *next_id_p = id;
3324 return 1;
3325 }
3326 }
3327
3328 return 0;
3329}
3330
3331/*
3332 * rib_tables_iter_next
3333 *
3334 * Returns the next table in the iteration.
3335 */
3336struct route_table *
3337rib_tables_iter_next (rib_tables_iter_t *iter)
3338{
3339 struct route_table *table;
3340
3341 /*
3342 * Array that helps us go over all AFI/SAFI combinations via one
3343 * index.
3344 */
3345 static struct {
3346 afi_t afi;
3347 safi_t safi;
3348 } afi_safis[] = {
3349 { AFI_IP, SAFI_UNICAST },
3350 { AFI_IP, SAFI_MULTICAST },
3351 { AFI_IP6, SAFI_UNICAST },
3352 { AFI_IP6, SAFI_MULTICAST },
3353 };
3354
3355 table = NULL;
3356
3357 switch (iter->state)
3358 {
3359
3360 case RIB_TABLES_ITER_S_INIT:
3361 iter->vrf_id = 0;
3362 iter->afi_safi_ix = -1;
3363
3364 /* Fall through */
3365
3366 case RIB_TABLES_ITER_S_ITERATING:
3367 iter->afi_safi_ix++;
3368 while (1)
3369 {
3370
3371 while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
3372 {
3373 table = vrf_table (afi_safis[iter->afi_safi_ix].afi,
3374 afi_safis[iter->afi_safi_ix].safi,
3375 iter->vrf_id);
3376 if (table)
3377 break;
3378
3379 iter->afi_safi_ix++;
3380 }
3381
3382 /*
3383 * Found another table in this vrf.
3384 */
3385 if (table)
3386 break;
3387
3388 /*
3389 * Done with all tables in the current vrf, go to the next
3390 * one.
3391 */
3392 if (!vrf_id_get_next (iter->vrf_id, &iter->vrf_id))
3393 break;
3394
3395 iter->afi_safi_ix = 0;
3396 }
3397
3398 break;
3399
3400 case RIB_TABLES_ITER_S_DONE:
3401 return NULL;
3402 }
3403
3404 if (table)
3405 iter->state = RIB_TABLES_ITER_S_ITERATING;
3406 else
3407 iter->state = RIB_TABLES_ITER_S_DONE;
3408
3409 return table;
3410}