blob: e39976ee55e065c711f06f3f2d4e0bd815cda071 [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};
74
75/* Vector for routing table. */
Stephen Hemmingerd145bc02008-08-17 17:41:37 +010076static vector vrf_vector;
paul718e3742002-12-13 20:15:29 +000077
Avneesh Sachdev1b5ed1b2012-11-13 22:48:54 +000078/*
79 * vrf_table_create
80 */
81static void
82vrf_table_create (struct vrf *vrf, afi_t afi, safi_t safi)
83{
84 rib_table_info_t *info;
85 struct route_table *table;
86
87 assert (!vrf->table[afi][safi]);
88
89 table = route_table_init ();
90 vrf->table[afi][safi] = table;
91
92 info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
93 info->vrf = vrf;
94 info->afi = afi;
95 info->safi = safi;
96 table->info = info;
97}
98
paul718e3742002-12-13 20:15:29 +000099/* Allocate new VRF. */
paula1ac18c2005-06-28 17:17:12 +0000100static struct vrf *
hassofce954f2004-10-07 20:29:24 +0000101vrf_alloc (const char *name)
paul718e3742002-12-13 20:15:29 +0000102{
103 struct vrf *vrf;
104
105 vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
106
107 /* Put name. */
108 if (name)
109 vrf->name = XSTRDUP (MTYPE_VRF_NAME, name);
110
111 /* Allocate routing table and static table. */
Avneesh Sachdev1b5ed1b2012-11-13 22:48:54 +0000112 vrf_table_create (vrf, AFI_IP, SAFI_UNICAST);
113 vrf_table_create (vrf, AFI_IP6, SAFI_UNICAST);
paul718e3742002-12-13 20:15:29 +0000114 vrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
115 vrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
Avneesh Sachdev1b5ed1b2012-11-13 22:48:54 +0000116 vrf_table_create (vrf, AFI_IP, SAFI_MULTICAST);
117 vrf_table_create (vrf, AFI_IP6, SAFI_MULTICAST);
G.Balajicddf3912011-11-26 21:59:32 +0400118 vrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
119 vrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
120
paul718e3742002-12-13 20:15:29 +0000121
122 return vrf;
123}
124
paul718e3742002-12-13 20:15:29 +0000125/* Lookup VRF by identifier. */
126struct vrf *
127vrf_lookup (u_int32_t id)
128{
129 return vector_lookup (vrf_vector, id);
130}
131
paul718e3742002-12-13 20:15:29 +0000132/* Initialize VRF. */
paula1ac18c2005-06-28 17:17:12 +0000133static void
134vrf_init (void)
paul718e3742002-12-13 20:15:29 +0000135{
136 struct vrf *default_table;
137
138 /* Allocate VRF vector. */
139 vrf_vector = vector_init (1);
140
141 /* Allocate default main table. */
142 default_table = vrf_alloc ("Default-IP-Routing-Table");
143
144 /* Default table index must be 0. */
145 vector_set_index (vrf_vector, 0, default_table);
146}
147
148/* Lookup route table. */
149struct route_table *
150vrf_table (afi_t afi, safi_t safi, u_int32_t id)
151{
152 struct vrf *vrf;
153
154 vrf = vrf_lookup (id);
155 if (! vrf)
156 return NULL;
157
Leonid Rosenboim9499bf22012-12-06 20:17:41 +0000158 if( afi >= AFI_MAX || safi >= SAFI_MAX )
159 return NULL;
160
paul718e3742002-12-13 20:15:29 +0000161 return vrf->table[afi][safi];
162}
163
164/* Lookup static route table. */
165struct route_table *
166vrf_static_table (afi_t afi, safi_t safi, u_int32_t id)
167{
168 struct vrf *vrf;
169
170 vrf = vrf_lookup (id);
171 if (! vrf)
172 return NULL;
173
Leonid Rosenboim9499bf22012-12-06 20:17:41 +0000174 if( afi >= AFI_MAX || safi >= SAFI_MAX )
175 return NULL;
176
paul718e3742002-12-13 20:15:29 +0000177 return vrf->stable[afi][safi];
178}
179
Avneesh Sachdev78deec42012-11-13 22:48:56 +0000180/*
181 * nexthop_type_to_str
182 */
183const char *
184nexthop_type_to_str (enum nexthop_types_t nh_type)
185{
186 static const char *desc[] = {
187 "none",
188 "Directly connected",
189 "Interface route",
190 "IPv4 nexthop",
191 "IPv4 nexthop with ifindex",
192 "IPv4 nexthop with ifname",
193 "IPv6 nexthop",
194 "IPv6 nexthop with ifindex",
195 "IPv6 nexthop with ifname",
196 "Null0 nexthop",
197 };
198
199 if (nh_type >= ZEBRA_NUM_OF (desc))
200 return "<Invalid nh type>";
201
202 return desc[nh_type];
203}
204
Christian Frankefa713d92013-07-05 15:35:37 +0000205/* Add nexthop to the end of a nexthop list. */
paula1ac18c2005-06-28 17:17:12 +0000206static void
Christian Frankefa713d92013-07-05 15:35:37 +0000207_nexthop_add (struct nexthop **target, struct nexthop *nexthop)
paul718e3742002-12-13 20:15:29 +0000208{
209 struct nexthop *last;
210
Christian Frankefa713d92013-07-05 15:35:37 +0000211 for (last = *target; last && last->next; last = last->next)
paul718e3742002-12-13 20:15:29 +0000212 ;
213 if (last)
214 last->next = nexthop;
215 else
Christian Frankefa713d92013-07-05 15:35:37 +0000216 *target = nexthop;
paul718e3742002-12-13 20:15:29 +0000217 nexthop->prev = last;
Christian Frankefa713d92013-07-05 15:35:37 +0000218}
paul718e3742002-12-13 20:15:29 +0000219
Christian Frankefa713d92013-07-05 15:35:37 +0000220/* Add nexthop to the end of a rib node's nexthop list */
221static void
222nexthop_add (struct rib *rib, struct nexthop *nexthop)
223{
224 _nexthop_add(&rib->nexthop, nexthop);
paul718e3742002-12-13 20:15:29 +0000225 rib->nexthop_num++;
226}
227
228/* Delete specified nexthop from the list. */
paula1ac18c2005-06-28 17:17:12 +0000229static void
paul718e3742002-12-13 20:15:29 +0000230nexthop_delete (struct rib *rib, struct nexthop *nexthop)
231{
232 if (nexthop->next)
233 nexthop->next->prev = nexthop->prev;
234 if (nexthop->prev)
235 nexthop->prev->next = nexthop->next;
236 else
237 rib->nexthop = nexthop->next;
238 rib->nexthop_num--;
239}
240
Christian Frankefa713d92013-07-05 15:35:37 +0000241static void nexthops_free(struct nexthop *nexthop);
242
paul718e3742002-12-13 20:15:29 +0000243/* Free nexthop. */
paula1ac18c2005-06-28 17:17:12 +0000244static void
paul718e3742002-12-13 20:15:29 +0000245nexthop_free (struct nexthop *nexthop)
246{
paula4b70762003-05-16 17:19:48 +0000247 if (nexthop->ifname)
248 XFREE (0, nexthop->ifname);
Christian Frankefa713d92013-07-05 15:35:37 +0000249 if (nexthop->resolved)
250 nexthops_free(nexthop->resolved);
paul718e3742002-12-13 20:15:29 +0000251 XFREE (MTYPE_NEXTHOP, nexthop);
252}
253
Christian Frankefa713d92013-07-05 15:35:37 +0000254/* Frees a list of nexthops */
255static void
256nexthops_free (struct nexthop *nexthop)
257{
258 struct nexthop *nh, *next;
259
260 for (nh = nexthop; nh; nh = next)
261 {
262 next = nh->next;
263 nexthop_free (nh);
264 }
265}
266
paul718e3742002-12-13 20:15:29 +0000267struct nexthop *
268nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
269{
270 struct nexthop *nexthop;
271
Stephen Hemminger393deb92008-08-18 14:13:29 -0700272 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000273 nexthop->type = NEXTHOP_TYPE_IFINDEX;
274 nexthop->ifindex = ifindex;
275
276 nexthop_add (rib, nexthop);
277
278 return nexthop;
279}
280
281struct nexthop *
282nexthop_ifname_add (struct rib *rib, char *ifname)
283{
284 struct nexthop *nexthop;
285
Stephen Hemminger393deb92008-08-18 14:13:29 -0700286 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000287 nexthop->type = NEXTHOP_TYPE_IFNAME;
paula4b70762003-05-16 17:19:48 +0000288 nexthop->ifname = XSTRDUP (0, ifname);
paul718e3742002-12-13 20:15:29 +0000289
290 nexthop_add (rib, nexthop);
291
292 return nexthop;
293}
294
295struct nexthop *
Paul Jakma7514fb72007-05-02 16:05:35 +0000296nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src)
paul718e3742002-12-13 20:15:29 +0000297{
298 struct nexthop *nexthop;
299
Stephen Hemminger393deb92008-08-18 14:13:29 -0700300 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000301 nexthop->type = NEXTHOP_TYPE_IPV4;
302 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000303 if (src)
304 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000305
306 nexthop_add (rib, nexthop);
307
308 return nexthop;
309}
310
Josh Bailey26e2ae32012-03-22 01:09:21 -0700311struct nexthop *
paul718e3742002-12-13 20:15:29 +0000312nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
Paul Jakma7514fb72007-05-02 16:05:35 +0000313 struct in_addr *src, unsigned int ifindex)
paul718e3742002-12-13 20:15:29 +0000314{
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_IPV4_IFINDEX;
319 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000320 if (src)
321 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000322 nexthop->ifindex = ifindex;
323
324 nexthop_add (rib, nexthop);
325
326 return nexthop;
327}
328
329#ifdef HAVE_IPV6
330struct nexthop *
331nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
332{
333 struct nexthop *nexthop;
334
Stephen Hemminger393deb92008-08-18 14:13:29 -0700335 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000336 nexthop->type = NEXTHOP_TYPE_IPV6;
337 nexthop->gate.ipv6 = *ipv6;
338
339 nexthop_add (rib, nexthop);
340
341 return nexthop;
342}
343
paula1ac18c2005-06-28 17:17:12 +0000344static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000345nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
346 char *ifname)
347{
348 struct nexthop *nexthop;
349
Stephen Hemminger393deb92008-08-18 14:13:29 -0700350 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000351 nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
352 nexthop->gate.ipv6 = *ipv6;
353 nexthop->ifname = XSTRDUP (0, ifname);
354
355 nexthop_add (rib, nexthop);
356
357 return nexthop;
358}
359
paula1ac18c2005-06-28 17:17:12 +0000360static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000361nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
362 unsigned int ifindex)
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_IFINDEX;
368 nexthop->gate.ipv6 = *ipv6;
369 nexthop->ifindex = ifindex;
370
371 nexthop_add (rib, nexthop);
372
373 return nexthop;
374}
375#endif /* HAVE_IPV6 */
376
paul595db7f2003-05-25 21:35:06 +0000377struct nexthop *
378nexthop_blackhole_add (struct rib *rib)
379{
380 struct nexthop *nexthop;
381
Stephen Hemminger393deb92008-08-18 14:13:29 -0700382 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul595db7f2003-05-25 21:35:06 +0000383 nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
384 SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
385
386 nexthop_add (rib, nexthop);
387
388 return nexthop;
389}
390
Christian Frankefa713d92013-07-05 15:35:37 +0000391/* This method checks whether a recursive nexthop has at
392 * least one resolved nexthop in the fib.
393 */
394int
395nexthop_has_fib_child(struct nexthop *nexthop)
396{
397 struct nexthop *nh;
398
399 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
400 return 0;
401
402 for (nh = nexthop->resolved; nh; nh = nh->next)
403 if (CHECK_FLAG (nh->flags, NEXTHOP_FLAG_FIB))
404 return 1;
405
406 return 0;
407}
408
paul718e3742002-12-13 20:15:29 +0000409/* If force flag is not set, do not modify falgs at all for uninstall
410 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000411static int
paul718e3742002-12-13 20:15:29 +0000412nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
413 struct route_node *top)
414{
415 struct prefix_ipv4 p;
416 struct route_table *table;
417 struct route_node *rn;
418 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000419 int resolved;
paul718e3742002-12-13 20:15:29 +0000420 struct nexthop *newhop;
Christian Frankefa713d92013-07-05 15:35:37 +0000421 struct nexthop *resolved_hop;
paul718e3742002-12-13 20:15:29 +0000422
423 if (nexthop->type == NEXTHOP_TYPE_IPV4)
424 nexthop->ifindex = 0;
425
426 if (set)
Christian Frankefa713d92013-07-05 15:35:37 +0000427 {
428 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
429 nexthops_free(nexthop->resolved);
430 nexthop->resolved = NULL;
431 }
paul718e3742002-12-13 20:15:29 +0000432
433 /* Make lookup prefix. */
434 memset (&p, 0, sizeof (struct prefix_ipv4));
435 p.family = AF_INET;
436 p.prefixlen = IPV4_MAX_PREFIXLEN;
437 p.prefix = nexthop->gate.ipv4;
438
439 /* Lookup table. */
440 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
441 if (! table)
442 return 0;
443
444 rn = route_node_match (table, (struct prefix *) &p);
445 while (rn)
446 {
447 route_unlock_node (rn);
448
David Warda50c1072009-12-03 15:34:39 +0300449 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000450 if (rn == top)
451 return 0;
452
453 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000454 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100455 {
456 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
457 continue;
458 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
459 break;
460 }
paul718e3742002-12-13 20:15:29 +0000461
462 /* If there is no selected route or matched route is EGP, go up
463 tree. */
464 if (! match
465 || match->type == ZEBRA_ROUTE_BGP)
466 {
467 do {
468 rn = rn->parent;
469 } while (rn && rn->info == NULL);
470 if (rn)
471 route_lock_node (rn);
472 }
473 else
474 {
475 if (match->type == ZEBRA_ROUTE_CONNECT)
476 {
477 /* Directly point connected route. */
478 newhop = match->nexthop;
479 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
480 nexthop->ifindex = newhop->ifindex;
481
482 return 1;
483 }
484 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
485 {
Christian Frankefa713d92013-07-05 15:35:37 +0000486 resolved = 0;
paul718e3742002-12-13 20:15:29 +0000487 for (newhop = match->nexthop; newhop; newhop = newhop->next)
488 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
489 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
490 {
491 if (set)
492 {
493 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
Christian Frankefa713d92013-07-05 15:35:37 +0000494
495 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
496 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
497
498 resolved_hop->type = newhop->type;
paul718e3742002-12-13 20:15:29 +0000499 if (newhop->type == NEXTHOP_TYPE_IPV4 ||
500 newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
Christian Frankefa713d92013-07-05 15:35:37 +0000501 resolved_hop->gate.ipv4 = newhop->gate.ipv4;
502
paul718e3742002-12-13 20:15:29 +0000503 if (newhop->type == NEXTHOP_TYPE_IFINDEX
504 || newhop->type == NEXTHOP_TYPE_IFNAME
505 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
Christian Frankefa713d92013-07-05 15:35:37 +0000506 resolved_hop->ifindex = newhop->ifindex;
507
508 _nexthop_add(&nexthop->resolved, resolved_hop);
paul718e3742002-12-13 20:15:29 +0000509 }
Christian Frankefa713d92013-07-05 15:35:37 +0000510 resolved = 1;
paul718e3742002-12-13 20:15:29 +0000511 }
Christian Frankefa713d92013-07-05 15:35:37 +0000512 return resolved;
paul718e3742002-12-13 20:15:29 +0000513 }
514 else
515 {
516 return 0;
517 }
518 }
519 }
520 return 0;
521}
522
523#ifdef HAVE_IPV6
524/* If force flag is not set, do not modify falgs at all for uninstall
525 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000526static int
paul718e3742002-12-13 20:15:29 +0000527nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
528 struct route_node *top)
529{
530 struct prefix_ipv6 p;
531 struct route_table *table;
532 struct route_node *rn;
533 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000534 int resolved;
paul718e3742002-12-13 20:15:29 +0000535 struct nexthop *newhop;
Christian Frankefa713d92013-07-05 15:35:37 +0000536 struct nexthop *resolved_hop;
paul718e3742002-12-13 20:15:29 +0000537
538 if (nexthop->type == NEXTHOP_TYPE_IPV6)
539 nexthop->ifindex = 0;
540
541 if (set)
Christian Frankefa713d92013-07-05 15:35:37 +0000542 {
543 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
544 nexthops_free(nexthop->resolved);
545 nexthop->resolved = NULL;
546 }
paul718e3742002-12-13 20:15:29 +0000547
548 /* Make lookup prefix. */
549 memset (&p, 0, sizeof (struct prefix_ipv6));
550 p.family = AF_INET6;
551 p.prefixlen = IPV6_MAX_PREFIXLEN;
552 p.prefix = nexthop->gate.ipv6;
553
554 /* Lookup table. */
555 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
556 if (! table)
557 return 0;
558
559 rn = route_node_match (table, (struct prefix *) &p);
560 while (rn)
561 {
562 route_unlock_node (rn);
563
David Warda50c1072009-12-03 15:34:39 +0300564 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000565 if (rn == top)
566 return 0;
567
568 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000569 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100570 {
571 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
572 continue;
573 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
574 break;
575 }
paul718e3742002-12-13 20:15:29 +0000576
577 /* If there is no selected route or matched route is EGP, go up
578 tree. */
579 if (! match
580 || match->type == ZEBRA_ROUTE_BGP)
581 {
582 do {
583 rn = rn->parent;
584 } while (rn && rn->info == NULL);
585 if (rn)
586 route_lock_node (rn);
587 }
588 else
589 {
590 if (match->type == ZEBRA_ROUTE_CONNECT)
591 {
592 /* Directly point connected route. */
593 newhop = match->nexthop;
594
595 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
596 nexthop->ifindex = newhop->ifindex;
597
598 return 1;
599 }
600 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
601 {
Christian Frankefa713d92013-07-05 15:35:37 +0000602 resolved = 0;
paul718e3742002-12-13 20:15:29 +0000603 for (newhop = match->nexthop; newhop; newhop = newhop->next)
604 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
605 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
606 {
607 if (set)
608 {
609 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
Christian Frankefa713d92013-07-05 15:35:37 +0000610
611 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
612 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
613
614 resolved_hop->type = newhop->type;
paul718e3742002-12-13 20:15:29 +0000615 if (newhop->type == NEXTHOP_TYPE_IPV6
616 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
617 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
Christian Frankefa713d92013-07-05 15:35:37 +0000618 resolved_hop->gate.ipv6 = newhop->gate.ipv6;
619
paul718e3742002-12-13 20:15:29 +0000620 if (newhop->type == NEXTHOP_TYPE_IFINDEX
621 || newhop->type == NEXTHOP_TYPE_IFNAME
622 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
623 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
Christian Frankefa713d92013-07-05 15:35:37 +0000624 resolved_hop->ifindex = newhop->ifindex;
625
626 _nexthop_add(&nexthop->resolved, resolved_hop);
paul718e3742002-12-13 20:15:29 +0000627 }
Christian Frankefa713d92013-07-05 15:35:37 +0000628 resolved = 1;
paul718e3742002-12-13 20:15:29 +0000629 }
Christian Frankefa713d92013-07-05 15:35:37 +0000630 return resolved;
paul718e3742002-12-13 20:15:29 +0000631 }
632 else
633 {
634 return 0;
635 }
636 }
637 }
638 return 0;
639}
640#endif /* HAVE_IPV6 */
641
642struct rib *
643rib_match_ipv4 (struct in_addr addr)
644{
645 struct prefix_ipv4 p;
646 struct route_table *table;
647 struct route_node *rn;
648 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000649 struct nexthop *newhop, *tnewhop;
650 int recursing;
paul718e3742002-12-13 20:15:29 +0000651
652 /* Lookup table. */
653 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
654 if (! table)
655 return 0;
656
657 memset (&p, 0, sizeof (struct prefix_ipv4));
658 p.family = AF_INET;
659 p.prefixlen = IPV4_MAX_PREFIXLEN;
660 p.prefix = addr;
661
662 rn = route_node_match (table, (struct prefix *) &p);
663
664 while (rn)
665 {
666 route_unlock_node (rn);
667
668 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000669 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100670 {
671 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
672 continue;
673 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
674 break;
675 }
paul718e3742002-12-13 20:15:29 +0000676
677 /* If there is no selected route or matched route is EGP, go up
678 tree. */
679 if (! match
680 || match->type == ZEBRA_ROUTE_BGP)
681 {
682 do {
683 rn = rn->parent;
684 } while (rn && rn->info == NULL);
685 if (rn)
686 route_lock_node (rn);
687 }
688 else
689 {
690 if (match->type == ZEBRA_ROUTE_CONNECT)
691 /* Directly point connected route. */
692 return match;
693 else
694 {
Christian Frankefa713d92013-07-05 15:35:37 +0000695 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
paul718e3742002-12-13 20:15:29 +0000696 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
697 return match;
698 return NULL;
699 }
700 }
701 }
702 return NULL;
703}
704
705struct rib *
706rib_lookup_ipv4 (struct prefix_ipv4 *p)
707{
708 struct route_table *table;
709 struct route_node *rn;
710 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000711 struct nexthop *nexthop, *tnexthop;
712 int recursing;
paul718e3742002-12-13 20:15:29 +0000713
714 /* Lookup table. */
715 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
716 if (! table)
717 return 0;
718
719 rn = route_node_lookup (table, (struct prefix *) p);
720
721 /* No route for this prefix. */
722 if (! rn)
723 return NULL;
724
725 /* Unlock node. */
726 route_unlock_node (rn);
727
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000728 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100729 {
730 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
731 continue;
732 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
733 break;
734 }
paul718e3742002-12-13 20:15:29 +0000735
736 if (! match || match->type == ZEBRA_ROUTE_BGP)
737 return NULL;
738
739 if (match->type == ZEBRA_ROUTE_CONNECT)
740 return match;
741
Christian Frankefa713d92013-07-05 15:35:37 +0000742 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +0000743 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
744 return match;
745
746 return NULL;
747}
748
Denis Ovsienkodc958242007-08-13 16:03:06 +0000749/*
750 * This clone function, unlike its original rib_lookup_ipv4(), checks
751 * if specified IPv4 route record (prefix/mask -> gate) exists in
752 * the whole RIB and has ZEBRA_FLAG_SELECTED set.
753 *
754 * Return values:
755 * -1: error
756 * 0: exact match found
757 * 1: a match was found with a different gate
758 * 2: connected route found
759 * 3: no matches found
760 */
761int
762rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
763{
764 struct route_table *table;
765 struct route_node *rn;
766 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000767 struct nexthop *nexthop, *tnexthop;
768 int recursing;
769 int nexthops_active;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000770
771 /* Lookup table. */
772 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
773 if (! table)
774 return ZEBRA_RIB_LOOKUP_ERROR;
775
776 /* Scan the RIB table for exactly matching RIB entry. */
777 rn = route_node_lookup (table, (struct prefix *) p);
778
779 /* No route for this prefix. */
780 if (! rn)
781 return ZEBRA_RIB_NOTFOUND;
782
783 /* Unlock node. */
784 route_unlock_node (rn);
785
786 /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000787 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100788 {
789 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
790 continue;
791 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
792 break;
793 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000794
795 /* None such found :( */
796 if (!match)
797 return ZEBRA_RIB_NOTFOUND;
798
799 if (match->type == ZEBRA_ROUTE_CONNECT)
800 return ZEBRA_RIB_FOUND_CONNECTED;
801
802 /* Ok, we have a cood candidate, let's check it's nexthop list... */
Christian Frankefa713d92013-07-05 15:35:37 +0000803 nexthops_active = 0;
804 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000805 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000806 {
Christian Frankefa713d92013-07-05 15:35:37 +0000807 nexthops_active = 1;
808 if (nexthop->gate.ipv4.s_addr == sockunion2ip (qgate))
809 return ZEBRA_RIB_FOUND_EXACT;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000810 if (IS_ZEBRA_DEBUG_RIB)
Christian Frankefa713d92013-07-05 15:35:37 +0000811 {
812 char gate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
813 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
814 inet_ntop (AF_INET, &sockunion2ip(qgate), qgate_buf, INET_ADDRSTRLEN);
815 zlog_debug ("%s: qgate == %s, %s == %s", __func__,
816 qgate_buf, recursing ? "rgate" : "gate", gate_buf);
817 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000818 }
Christian Frankefa713d92013-07-05 15:35:37 +0000819
820 if (nexthops_active)
821 return ZEBRA_RIB_FOUND_NOGATE;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000822
823 return ZEBRA_RIB_NOTFOUND;
824}
825
paul718e3742002-12-13 20:15:29 +0000826#ifdef HAVE_IPV6
827struct rib *
828rib_match_ipv6 (struct in6_addr *addr)
829{
830 struct prefix_ipv6 p;
831 struct route_table *table;
832 struct route_node *rn;
833 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000834 struct nexthop *newhop, *tnewhop;
835 int recursing;
paul718e3742002-12-13 20:15:29 +0000836
837 /* Lookup table. */
838 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
839 if (! table)
840 return 0;
841
842 memset (&p, 0, sizeof (struct prefix_ipv6));
843 p.family = AF_INET6;
844 p.prefixlen = IPV6_MAX_PREFIXLEN;
845 IPV6_ADDR_COPY (&p.prefix, addr);
846
847 rn = route_node_match (table, (struct prefix *) &p);
848
849 while (rn)
850 {
851 route_unlock_node (rn);
852
853 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000854 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100855 {
856 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
857 continue;
858 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
859 break;
860 }
paul718e3742002-12-13 20:15:29 +0000861
862 /* If there is no selected route or matched route is EGP, go up
863 tree. */
864 if (! match
865 || match->type == ZEBRA_ROUTE_BGP)
866 {
867 do {
868 rn = rn->parent;
869 } while (rn && rn->info == NULL);
870 if (rn)
871 route_lock_node (rn);
872 }
873 else
874 {
875 if (match->type == ZEBRA_ROUTE_CONNECT)
876 /* Directly point connected route. */
877 return match;
878 else
879 {
Christian Frankefa713d92013-07-05 15:35:37 +0000880 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
paul718e3742002-12-13 20:15:29 +0000881 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
882 return match;
883 return NULL;
884 }
885 }
886 }
887 return NULL;
888}
889#endif /* HAVE_IPV6 */
890
Paul Jakma7514fb72007-05-02 16:05:35 +0000891#define RIB_SYSTEM_ROUTE(R) \
892 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
893
Denis Ovsienkodc958242007-08-13 16:03:06 +0000894/* This function verifies reachability of one given nexthop, which can be
895 * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
896 * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
897 * nexthop->ifindex will be updated appropriately as well.
898 * An existing route map can turn (otherwise active) nexthop into inactive, but
899 * not vice versa.
900 *
901 * The return value is the final value of 'ACTIVE' flag.
902 */
903
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300904static unsigned
paul718e3742002-12-13 20:15:29 +0000905nexthop_active_check (struct route_node *rn, struct rib *rib,
906 struct nexthop *nexthop, int set)
907{
908 struct interface *ifp;
Paul Jakma7514fb72007-05-02 16:05:35 +0000909 route_map_result_t ret = RMAP_MATCH;
910 extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
911 struct route_map *rmap;
912 int family;
paul718e3742002-12-13 20:15:29 +0000913
Paul Jakma7514fb72007-05-02 16:05:35 +0000914 family = 0;
paul718e3742002-12-13 20:15:29 +0000915 switch (nexthop->type)
916 {
917 case NEXTHOP_TYPE_IFINDEX:
918 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000919 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000920 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
921 else
922 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
923 break;
paul718e3742002-12-13 20:15:29 +0000924 case NEXTHOP_TYPE_IPV6_IFNAME:
Paul Jakma7514fb72007-05-02 16:05:35 +0000925 family = AFI_IP6;
926 case NEXTHOP_TYPE_IFNAME:
paul718e3742002-12-13 20:15:29 +0000927 ifp = if_lookup_by_name (nexthop->ifname);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000928 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000929 {
930 if (set)
931 nexthop->ifindex = ifp->ifindex;
932 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
933 }
934 else
935 {
936 if (set)
937 nexthop->ifindex = 0;
938 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
939 }
940 break;
941 case NEXTHOP_TYPE_IPV4:
942 case NEXTHOP_TYPE_IPV4_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000943 family = AFI_IP;
paul718e3742002-12-13 20:15:29 +0000944 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
945 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
946 else
947 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
948 break;
949#ifdef HAVE_IPV6
950 case NEXTHOP_TYPE_IPV6:
Paul Jakma7514fb72007-05-02 16:05:35 +0000951 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000952 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
953 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
954 else
955 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
956 break;
957 case NEXTHOP_TYPE_IPV6_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000958 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000959 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
960 {
961 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000962 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000963 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
964 else
965 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
966 }
967 else
968 {
969 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
970 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
971 else
972 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
973 }
974 break;
975#endif /* HAVE_IPV6 */
paul595db7f2003-05-25 21:35:06 +0000976 case NEXTHOP_TYPE_BLACKHOLE:
977 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
978 break;
paul718e3742002-12-13 20:15:29 +0000979 default:
980 break;
981 }
Paul Jakma7514fb72007-05-02 16:05:35 +0000982 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
983 return 0;
984
985 if (RIB_SYSTEM_ROUTE(rib) ||
986 (family == AFI_IP && rn->p.family != AF_INET) ||
987 (family == AFI_IP6 && rn->p.family != AF_INET6))
988 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
989
990 rmap = 0;
991 if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
992 proto_rm[family][rib->type])
993 rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
994 if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
995 rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
996 if (rmap) {
997 ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, nexthop);
998 }
999
1000 if (ret == RMAP_DENYMATCH)
1001 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
paul718e3742002-12-13 20:15:29 +00001002 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1003}
1004
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001005/* Iterate over all nexthops of the given RIB entry and refresh their
1006 * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
1007 * nexthop is found to toggle the ACTIVE flag, the whole rib structure
1008 * is flagged with ZEBRA_FLAG_CHANGED. The 4th 'set' argument is
1009 * transparently passed to nexthop_active_check().
1010 *
1011 * Return value is the new number of active nexthops.
1012 */
1013
paula1ac18c2005-06-28 17:17:12 +00001014static int
paul718e3742002-12-13 20:15:29 +00001015nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
1016{
1017 struct nexthop *nexthop;
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001018 unsigned int prev_active, prev_index, new_active;
paul718e3742002-12-13 20:15:29 +00001019
1020 rib->nexthop_active_num = 0;
1021 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1022
1023 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001024 {
1025 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001026 prev_index = nexthop->ifindex;
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001027 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
1028 rib->nexthop_active_num++;
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001029 if (prev_active != new_active ||
1030 prev_index != nexthop->ifindex)
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001031 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1032 }
paul718e3742002-12-13 20:15:29 +00001033 return rib->nexthop_active_num;
1034}
paul6baeb982003-10-28 03:47:15 +00001035
paul718e3742002-12-13 20:15:29 +00001036
paul718e3742002-12-13 20:15:29 +00001037
paula1ac18c2005-06-28 17:17:12 +00001038static void
paul718e3742002-12-13 20:15:29 +00001039rib_install_kernel (struct route_node *rn, struct rib *rib)
1040{
1041 int ret = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001042 struct nexthop *nexthop, *tnexthop;
1043 int recursing;
paul718e3742002-12-13 20:15:29 +00001044
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001045 /*
1046 * Make sure we update the FPM any time we send new information to
1047 * the kernel.
1048 */
1049 zfpm_trigger_update (rn, "installing in kernel");
paul718e3742002-12-13 20:15:29 +00001050 switch (PREFIX_FAMILY (&rn->p))
1051 {
1052 case AF_INET:
1053 ret = kernel_add_ipv4 (&rn->p, rib);
1054 break;
1055#ifdef HAVE_IPV6
1056 case AF_INET6:
1057 ret = kernel_add_ipv6 (&rn->p, rib);
1058 break;
1059#endif /* HAVE_IPV6 */
1060 }
1061
Denis Ovsienkodc958242007-08-13 16:03:06 +00001062 /* This condition is never met, if we are using rt_socket.c */
paul718e3742002-12-13 20:15:29 +00001063 if (ret < 0)
1064 {
Christian Frankefa713d92013-07-05 15:35:37 +00001065 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +00001066 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1067 }
1068}
1069
1070/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001071static int
paul718e3742002-12-13 20:15:29 +00001072rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
1073{
1074 int ret = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001075 struct nexthop *nexthop, *tnexthop;
1076 int recursing;
paul718e3742002-12-13 20:15:29 +00001077
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001078 /*
1079 * Make sure we update the FPM any time we send new information to
1080 * the kernel.
1081 */
1082 zfpm_trigger_update (rn, "uninstalling from kernel");
1083
paul718e3742002-12-13 20:15:29 +00001084 switch (PREFIX_FAMILY (&rn->p))
1085 {
1086 case AF_INET:
1087 ret = kernel_delete_ipv4 (&rn->p, rib);
1088 break;
1089#ifdef HAVE_IPV6
1090 case AF_INET6:
1091 ret = kernel_delete_ipv6 (&rn->p, rib);
1092 break;
1093#endif /* HAVE_IPV6 */
1094 }
1095
Christian Frankefa713d92013-07-05 15:35:37 +00001096 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +00001097 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1098
1099 return ret;
1100}
1101
1102/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001103static void
paul718e3742002-12-13 20:15:29 +00001104rib_uninstall (struct route_node *rn, struct rib *rib)
1105{
1106 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1107 {
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001108 zfpm_trigger_update (rn, "rib_uninstall");
1109
paul718e3742002-12-13 20:15:29 +00001110 redistribute_delete (&rn->p, rib);
1111 if (! RIB_SYSTEM_ROUTE (rib))
1112 rib_uninstall_kernel (rn, rib);
1113 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
1114 }
1115}
1116
Paul Jakma6d691122006-07-27 21:49:00 +00001117static void rib_unlink (struct route_node *, struct rib *);
1118
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001119/*
1120 * rib_can_delete_dest
1121 *
1122 * Returns TRUE if the given dest can be deleted from the table.
1123 */
1124static int
1125rib_can_delete_dest (rib_dest_t *dest)
1126{
1127 if (dest->routes)
1128 {
1129 return 0;
1130 }
1131
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001132 /*
1133 * Don't delete the dest if we have to update the FPM about this
1134 * prefix.
1135 */
1136 if (CHECK_FLAG (dest->flags, RIB_DEST_UPDATE_FPM) ||
1137 CHECK_FLAG (dest->flags, RIB_DEST_SENT_TO_FPM))
1138 return 0;
1139
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001140 return 1;
1141}
1142
1143/*
1144 * rib_gc_dest
1145 *
1146 * Garbage collect the rib dest corresponding to the given route node
1147 * if appropriate.
1148 *
1149 * Returns TRUE if the dest was deleted, FALSE otherwise.
1150 */
1151int
1152rib_gc_dest (struct route_node *rn)
1153{
1154 rib_dest_t *dest;
1155 char buf[INET6_ADDRSTRLEN];
1156
1157 dest = rib_dest_from_rnode (rn);
1158 if (!dest)
1159 return 0;
1160
1161 if (!rib_can_delete_dest (dest))
1162 return 0;
1163
1164 if (IS_ZEBRA_DEBUG_RIB)
1165 {
1166 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, sizeof (buf));
1167 zlog_debug ("%s: %s/%d: removing dest from table", __func__,
1168 buf, rn->p.prefixlen);
1169 }
1170
1171 dest->rnode = NULL;
1172 XFREE (MTYPE_RIB_DEST, dest);
1173 rn->info = NULL;
1174
1175 /*
1176 * Release the one reference that we keep on the route node.
1177 */
1178 route_unlock_node (rn);
1179 return 1;
1180}
1181
paul718e3742002-12-13 20:15:29 +00001182/* Core function for processing routing information base. */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001183static void
1184rib_process (struct route_node *rn)
paul718e3742002-12-13 20:15:29 +00001185{
1186 struct rib *rib;
1187 struct rib *next;
1188 struct rib *fib = NULL;
1189 struct rib *select = NULL;
Paul Jakma6d691122006-07-27 21:49:00 +00001190 struct rib *del = NULL;
pauld753e9e2003-01-22 19:45:50 +00001191 int installed = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001192 struct nexthop *nexthop = NULL, *tnexthop;
1193 int recursing;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001194 char buf[INET6_ADDRSTRLEN];
paul4d38fdb2005-04-28 17:35:14 +00001195
1196 assert (rn);
1197
Paul Jakma93bdada2007-08-06 19:25:11 +00001198 if (IS_ZEBRA_DEBUG_RIB || IS_ZEBRA_DEBUG_RIB_Q)
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001199 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001200
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001201 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00001202 {
paul718e3742002-12-13 20:15:29 +00001203 /* Currently installed rib. */
1204 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Paul Jakma6d691122006-07-27 21:49:00 +00001205 {
1206 assert (fib == NULL);
1207 fib = rib;
1208 }
1209
1210 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1211 * which we need to do do further work with below.
1212 */
1213 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1214 {
1215 if (rib != fib)
1216 {
1217 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001218 zlog_debug ("%s: %s/%d: rn %p, removing rib %p", __func__,
1219 buf, rn->p.prefixlen, rn, rib);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001220 rib_unlink (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001221 }
1222 else
1223 del = rib;
1224
1225 continue;
1226 }
paul4d38fdb2005-04-28 17:35:14 +00001227
paul718e3742002-12-13 20:15:29 +00001228 /* Skip unreachable nexthop. */
1229 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +00001230 continue;
paul718e3742002-12-13 20:15:29 +00001231
1232 /* Infinit distance. */
1233 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +00001234 continue;
paul718e3742002-12-13 20:15:29 +00001235
paulaf887b52006-01-18 14:52:52 +00001236 /* Newly selected rib, the common case. */
1237 if (!select)
1238 {
1239 select = rib;
1240 continue;
1241 }
1242
1243 /* filter route selection in following order:
paulaf887b52006-01-18 14:52:52 +00001244 * - connected beats other types
paula8d9c1f2006-01-25 06:31:04 +00001245 * - lower distance beats higher
paulaf887b52006-01-18 14:52:52 +00001246 * - lower metric beats higher for equal distance
1247 * - last, hence oldest, route wins tie break.
1248 */
paula1038a12006-01-30 14:08:51 +00001249
1250 /* Connected routes. Pick the last connected
1251 * route of the set of lowest metric connected routes.
1252 */
paula8d9c1f2006-01-25 06:31:04 +00001253 if (rib->type == ZEBRA_ROUTE_CONNECT)
1254 {
paula1038a12006-01-30 14:08:51 +00001255 if (select->type != ZEBRA_ROUTE_CONNECT
paula8d9c1f2006-01-25 06:31:04 +00001256 || rib->metric <= select->metric)
paula1038a12006-01-30 14:08:51 +00001257 select = rib;
1258 continue;
paula8d9c1f2006-01-25 06:31:04 +00001259 }
1260 else if (select->type == ZEBRA_ROUTE_CONNECT)
1261 continue;
1262
1263 /* higher distance loses */
1264 if (rib->distance > select->distance)
1265 continue;
1266
1267 /* lower wins */
1268 if (rib->distance < select->distance)
1269 {
paulaf887b52006-01-18 14:52:52 +00001270 select = rib;
paula8d9c1f2006-01-25 06:31:04 +00001271 continue;
1272 }
1273
1274 /* metric tie-breaks equal distance */
1275 if (rib->metric <= select->metric)
1276 select = rib;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001277 } /* RNODE_FOREACH_RIB_SAFE */
Denis Ovsienkodc958242007-08-13 16:03:06 +00001278
1279 /* After the cycle is finished, the following pointers will be set:
1280 * select --- the winner RIB entry, if any was found, otherwise NULL
1281 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1282 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1283 * rib --- NULL
1284 */
1285
1286 /* Same RIB entry is selected. Update FIB and finish. */
paul718e3742002-12-13 20:15:29 +00001287 if (select && select == fib)
1288 {
Paul Jakma6d691122006-07-27 21:49:00 +00001289 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001290 zlog_debug ("%s: %s/%d: Updating existing route, select %p, fib %p",
1291 __func__, buf, rn->p.prefixlen, select, fib);
paul718e3742002-12-13 20:15:29 +00001292 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +00001293 {
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001294 zfpm_trigger_update (rn, "updating existing route");
1295
paul4d38fdb2005-04-28 17:35:14 +00001296 redistribute_delete (&rn->p, select);
1297 if (! RIB_SYSTEM_ROUTE (select))
1298 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001299
paul4d38fdb2005-04-28 17:35:14 +00001300 /* Set real nexthop. */
1301 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +00001302
paul4d38fdb2005-04-28 17:35:14 +00001303 if (! RIB_SYSTEM_ROUTE (select))
1304 rib_install_kernel (rn, select);
1305 redistribute_add (&rn->p, select);
1306 }
pauld753e9e2003-01-22 19:45:50 +00001307 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001308 {
1309 /* Housekeeping code to deal with
1310 race conditions in kernel with linux
1311 netlink reporting interface up before IPv4 or IPv6 protocol
1312 is ready to add routes.
1313 This makes sure the routes are IN the kernel.
1314 */
pauld753e9e2003-01-22 19:45:50 +00001315
Christian Frankefa713d92013-07-05 15:35:37 +00001316 for (ALL_NEXTHOPS_RO(select->nexthop, nexthop, tnexthop, recursing))
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001317 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
paul4d38fdb2005-04-28 17:35:14 +00001318 {
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001319 installed = 1;
1320 break;
paul4d38fdb2005-04-28 17:35:14 +00001321 }
1322 if (! installed)
1323 rib_install_kernel (rn, select);
1324 }
Paul Jakma6d691122006-07-27 21:49:00 +00001325 goto end;
paul718e3742002-12-13 20:15:29 +00001326 }
1327
Denis Ovsienkodc958242007-08-13 16:03:06 +00001328 /* At this point we either haven't found the best RIB entry or it is
1329 * different from what we currently intend to flag with SELECTED. In both
1330 * cases, if a RIB block is present in FIB, it should be withdrawn.
1331 */
paul718e3742002-12-13 20:15:29 +00001332 if (fib)
1333 {
Paul Jakma6d691122006-07-27 21:49:00 +00001334 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001335 zlog_debug ("%s: %s/%d: Removing existing route, fib %p", __func__,
1336 buf, rn->p.prefixlen, fib);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001337
1338 zfpm_trigger_update (rn, "removing existing route");
1339
paul718e3742002-12-13 20:15:29 +00001340 redistribute_delete (&rn->p, fib);
1341 if (! RIB_SYSTEM_ROUTE (fib))
1342 rib_uninstall_kernel (rn, fib);
1343 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1344
1345 /* Set real nexthop. */
1346 nexthop_active_update (rn, fib, 1);
1347 }
1348
Denis Ovsienkodc958242007-08-13 16:03:06 +00001349 /* Regardless of some RIB entry being SELECTED or not before, now we can
1350 * tell, that if a new winner exists, FIB is still not updated with this
1351 * data, but ready to be.
1352 */
paul718e3742002-12-13 20:15:29 +00001353 if (select)
1354 {
Paul Jakma6d691122006-07-27 21:49:00 +00001355 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001356 zlog_debug ("%s: %s/%d: Adding route, select %p", __func__, buf,
1357 rn->p.prefixlen, select);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001358
1359 zfpm_trigger_update (rn, "new route selected");
1360
paul718e3742002-12-13 20:15:29 +00001361 /* Set real nexthop. */
1362 nexthop_active_update (rn, select, 1);
1363
1364 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001365 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001366 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1367 redistribute_add (&rn->p, select);
1368 }
paul4d38fdb2005-04-28 17:35:14 +00001369
Paul Jakma6d691122006-07-27 21:49:00 +00001370 /* FIB route was removed, should be deleted */
1371 if (del)
1372 {
1373 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001374 zlog_debug ("%s: %s/%d: Deleting fib %p, rn %p", __func__, buf,
1375 rn->p.prefixlen, del, rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001376 rib_unlink (rn, del);
1377 }
paul4d38fdb2005-04-28 17:35:14 +00001378
Paul Jakma6d691122006-07-27 21:49:00 +00001379end:
1380 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma93bdada2007-08-06 19:25:11 +00001381 zlog_debug ("%s: %s/%d: rn %p dequeued", __func__, buf, rn->p.prefixlen, rn);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001382
1383 /*
1384 * Check if the dest can be deleted now.
1385 */
1386 rib_gc_dest (rn);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001387}
1388
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001389/* Take a list of route_node structs and return 1, if there was a record
1390 * picked from it and processed by rib_process(). Don't process more,
1391 * than one RN record; operate only in the specified sub-queue.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001392 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001393static unsigned int
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001394process_subq (struct list * subq, u_char qindex)
1395{
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001396 struct listnode *lnode = listhead (subq);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001397 struct route_node *rnode;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001398
1399 if (!lnode)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001400 return 0;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001401
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001402 rnode = listgetdata (lnode);
1403 rib_process (rnode);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001404
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001405 if (rnode->info)
1406 UNSET_FLAG (rib_dest_from_rnode (rnode)->flags, RIB_ROUTE_QUEUED (qindex));
1407
Chris Caputo67b94672009-07-18 04:02:26 +00001408#if 0
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001409 else
1410 {
1411 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1412 __func__, rnode, rnode->lock);
1413 zlog_backtrace(LOG_DEBUG);
1414 }
Chris Caputo67b94672009-07-18 04:02:26 +00001415#endif
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001416 route_unlock_node (rnode);
1417 list_delete_node (subq, lnode);
1418 return 1;
1419}
1420
1421/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1422 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1423 * is pointed to the meta queue structure.
1424 */
1425static wq_item_status
1426meta_queue_process (struct work_queue *dummy, void *data)
1427{
1428 struct meta_queue * mq = data;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001429 unsigned i;
1430
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001431 for (i = 0; i < MQ_SIZE; i++)
1432 if (process_subq (mq->subq[i], i))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001433 {
1434 mq->size--;
1435 break;
1436 }
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001437 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1438}
1439
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001440/*
1441 * Map from rib types to queue type (priority) in meta queue
1442 */
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001443static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
1444 [ZEBRA_ROUTE_SYSTEM] = 4,
1445 [ZEBRA_ROUTE_KERNEL] = 0,
1446 [ZEBRA_ROUTE_CONNECT] = 0,
1447 [ZEBRA_ROUTE_STATIC] = 1,
1448 [ZEBRA_ROUTE_RIP] = 2,
1449 [ZEBRA_ROUTE_RIPNG] = 2,
1450 [ZEBRA_ROUTE_OSPF] = 2,
1451 [ZEBRA_ROUTE_OSPF6] = 2,
1452 [ZEBRA_ROUTE_ISIS] = 2,
1453 [ZEBRA_ROUTE_BGP] = 3,
1454 [ZEBRA_ROUTE_HSLS] = 4,
Paul Jakma57345092011-12-25 17:52:09 +01001455 [ZEBRA_ROUTE_BABEL] = 2,
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001456};
1457
1458/* Look into the RN and queue it into one or more priority queues,
1459 * increasing the size for each data push done.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001460 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001461static void
1462rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001463{
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001464 struct rib *rib;
1465 char buf[INET6_ADDRSTRLEN];
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001466
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001467 if (IS_ZEBRA_DEBUG_RIB_Q)
1468 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001469
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001470 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001471 {
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001472 u_char qindex = meta_queue_map[rib->type];
1473
1474 /* Invariant: at this point we always have rn->info set. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001475 if (CHECK_FLAG (rib_dest_from_rnode (rn)->flags,
1476 RIB_ROUTE_QUEUED (qindex)))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001477 {
1478 if (IS_ZEBRA_DEBUG_RIB_Q)
1479 zlog_debug ("%s: %s/%d: rn %p is already queued in sub-queue %u",
1480 __func__, buf, rn->p.prefixlen, rn, qindex);
1481 continue;
1482 }
1483
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001484 SET_FLAG (rib_dest_from_rnode (rn)->flags, RIB_ROUTE_QUEUED (qindex));
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001485 listnode_add (mq->subq[qindex], rn);
1486 route_lock_node (rn);
1487 mq->size++;
1488
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001489 if (IS_ZEBRA_DEBUG_RIB_Q)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001490 zlog_debug ("%s: %s/%d: queued rn %p into sub-queue %u",
1491 __func__, buf, rn->p.prefixlen, rn, qindex);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001492 }
paul4d38fdb2005-04-28 17:35:14 +00001493}
1494
Paul Jakma6d691122006-07-27 21:49:00 +00001495/* Add route_node to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001496static void
Paul Jakma6d691122006-07-27 21:49:00 +00001497rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
paul4d38fdb2005-04-28 17:35:14 +00001498{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001499 char buf[INET_ADDRSTRLEN];
1500 assert (zebra && rn);
paul4d38fdb2005-04-28 17:35:14 +00001501
Paul Jakma93bdada2007-08-06 19:25:11 +00001502 if (IS_ZEBRA_DEBUG_RIB_Q)
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001503 inet_ntop (AF_INET, &rn->p.u.prefix, buf, INET_ADDRSTRLEN);
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001504
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001505 /* Pointless to queue a route_node with no RIB entries to add or remove */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001506 if (!rnode_to_ribs (rn))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001507 {
1508 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1509 __func__, rn, rn->lock);
1510 zlog_backtrace(LOG_DEBUG);
1511 return;
1512 }
1513
1514 if (IS_ZEBRA_DEBUG_RIB_Q)
1515 zlog_info ("%s: %s/%d: work queue added", __func__, buf, rn->p.prefixlen);
1516
1517 assert (zebra);
1518
1519 if (zebra->ribq == NULL)
1520 {
1521 zlog_err ("%s: work_queue does not exist!", __func__);
1522 return;
Paul Jakma6d691122006-07-27 21:49:00 +00001523 }
paul4d38fdb2005-04-28 17:35:14 +00001524
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001525 /*
1526 * The RIB queue should normally be either empty or holding the only
1527 * work_queue_item element. In the latter case this element would
1528 * hold a pointer to the meta queue structure, which must be used to
1529 * actually queue the route nodes to process. So create the MQ
1530 * holder, if necessary, then push the work into it in any case.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001531 * This semantics was introduced after 0.99.9 release.
1532 */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001533 if (!zebra->ribq->items->count)
1534 work_queue_add (zebra->ribq, zebra->mq);
1535
1536 rib_meta_queue_add (zebra->mq, rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001537
1538 if (IS_ZEBRA_DEBUG_RIB_Q)
1539 zlog_debug ("%s: %s/%d: rn %p queued", __func__, buf, rn->p.prefixlen, rn);
1540
1541 return;
paul4d38fdb2005-04-28 17:35:14 +00001542}
1543
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001544/* Create new meta queue.
1545 A destructor function doesn't seem to be necessary here.
1546 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001547static struct meta_queue *
1548meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001549{
1550 struct meta_queue *new;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001551 unsigned i;
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001552
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001553 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1554 assert(new);
1555
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001556 for (i = 0; i < MQ_SIZE; i++)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001557 {
1558 new->subq[i] = list_new ();
1559 assert(new->subq[i]);
1560 }
1561
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001562 return new;
1563}
1564
paul4d38fdb2005-04-28 17:35:14 +00001565/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001566static void
paul4d38fdb2005-04-28 17:35:14 +00001567rib_queue_init (struct zebra_t *zebra)
1568{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001569 assert (zebra);
1570
paul4d38fdb2005-04-28 17:35:14 +00001571 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001572 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001573 {
Paul Jakma6d691122006-07-27 21:49:00 +00001574 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001575 return;
1576 }
1577
1578 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001579 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001580 zebra->ribq->spec.errorfunc = NULL;
paul4d38fdb2005-04-28 17:35:14 +00001581 /* XXX: TODO: These should be runtime configurable via vty */
1582 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001583 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001584
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001585 if (!(zebra->mq = meta_queue_new ()))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001586 {
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001587 zlog_err ("%s: could not initialise meta queue!", __func__);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001588 return;
1589 }
1590 return;
paul718e3742002-12-13 20:15:29 +00001591}
1592
Paul Jakma6d691122006-07-27 21:49:00 +00001593/* RIB updates are processed via a queue of pointers to route_nodes.
1594 *
1595 * The queue length is bounded by the maximal size of the routing table,
1596 * as a route_node will not be requeued, if already queued.
1597 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001598 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1599 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1600 * and then submit route_node to queue for best-path selection later.
1601 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001602 *
1603 * Deleted RIBs are reaped during best-path selection.
1604 *
1605 * rib_addnode
1606 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001607 * |-------->| | best RIB, if required
1608 * | |
1609 * static_install->|->rib_addqueue...... -> rib_process
1610 * | |
1611 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001612 * |-> set RIB_ENTRY_REMOVE |
1613 * rib_delnode (RIB freed)
1614 *
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001615 * The 'info' pointer of a route_node points to a rib_dest_t
1616 * ('dest'). Queueing state for a route_node is kept on the dest. The
1617 * dest is created on-demand by rib_link() and is kept around at least
1618 * as long as there are ribs hanging off it (@see rib_gc_dest()).
Paul Jakma6d691122006-07-27 21:49:00 +00001619 *
1620 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1621 *
1622 * - route_nodes: refcounted by:
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001623 * - dest attached to route_node:
1624 * - managed by: rib_link/rib_gc_dest
Paul Jakma6d691122006-07-27 21:49:00 +00001625 * - route_node processing queue
1626 * - managed by: rib_addqueue, rib_process.
1627 *
1628 */
1629
paul718e3742002-12-13 20:15:29 +00001630/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001631static void
Paul Jakma6d691122006-07-27 21:49:00 +00001632rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001633{
1634 struct rib *head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001635 rib_dest_t *dest;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001636 char buf[INET6_ADDRSTRLEN];
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001637
paul4d38fdb2005-04-28 17:35:14 +00001638 assert (rib && rn);
1639
Paul Jakma6d691122006-07-27 21:49:00 +00001640 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001641 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001642 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001643 zlog_debug ("%s: %s/%d: rn %p, rib %p", __func__,
1644 buf, rn->p.prefixlen, rn, rib);
1645 }
Paul Jakma6d691122006-07-27 21:49:00 +00001646
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001647 dest = rib_dest_from_rnode (rn);
1648 if (!dest)
Paul Jakma6d691122006-07-27 21:49:00 +00001649 {
1650 if (IS_ZEBRA_DEBUG_RIB)
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001651 {
1652 zlog_debug ("%s: %s/%d: adding dest to table", __func__,
1653 buf, rn->p.prefixlen);
1654 }
1655
1656 dest = XCALLOC (MTYPE_RIB_DEST, sizeof (rib_dest_t));
1657 route_lock_node (rn); /* rn route table reference */
1658 rn->info = dest;
1659 dest->rnode = rn;
1660 }
1661
1662 head = dest->routes;
1663 if (head)
1664 {
Paul Jakma6d691122006-07-27 21:49:00 +00001665 head->prev = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001666 }
paul718e3742002-12-13 20:15:29 +00001667 rib->next = head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001668 dest->routes = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001669 rib_queue_add (&zebrad, rn);
1670}
1671
1672static void
1673rib_addnode (struct route_node *rn, struct rib *rib)
1674{
1675 /* RIB node has been un-removed before route-node is processed.
1676 * route_node must hence already be on the queue for processing..
1677 */
1678 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1679 {
1680 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001681 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001682 char buf[INET6_ADDRSTRLEN];
1683 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001684 zlog_debug ("%s: %s/%d: rn %p, un-removed rib %p",
1685 __func__, buf, rn->p.prefixlen, rn, rib);
1686 }
Paul Jakma6d691122006-07-27 21:49:00 +00001687 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1688 return;
1689 }
1690 rib_link (rn, rib);
1691}
1692
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001693/*
1694 * rib_unlink
1695 *
1696 * Detach a rib structure from a route_node.
1697 *
1698 * Note that a call to rib_unlink() should be followed by a call to
1699 * rib_gc_dest() at some point. This allows a rib_dest_t that is no
1700 * longer required to be deleted.
1701 */
Paul Jakma6d691122006-07-27 21:49:00 +00001702static void
1703rib_unlink (struct route_node *rn, struct rib *rib)
1704{
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001705 char buf[INET6_ADDRSTRLEN];
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001706 rib_dest_t *dest;
Paul Jakma6d691122006-07-27 21:49:00 +00001707
1708 assert (rn && rib);
1709
1710 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001711 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001712 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001713 zlog_debug ("%s: %s/%d: rn %p, rib %p",
1714 __func__, buf, rn->p.prefixlen, rn, rib);
1715 }
Paul Jakma6d691122006-07-27 21:49:00 +00001716
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001717 dest = rib_dest_from_rnode (rn);
1718
Paul Jakma6d691122006-07-27 21:49:00 +00001719 if (rib->next)
1720 rib->next->prev = rib->prev;
1721
1722 if (rib->prev)
1723 rib->prev->next = rib->next;
1724 else
1725 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001726 dest->routes = rib->next;
Paul Jakma6d691122006-07-27 21:49:00 +00001727 }
1728
1729 /* free RIB and nexthops */
Christian Frankefa713d92013-07-05 15:35:37 +00001730 nexthops_free(rib->nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00001731 XFREE (MTYPE_RIB, rib);
1732
paul718e3742002-12-13 20:15:29 +00001733}
1734
paula1ac18c2005-06-28 17:17:12 +00001735static void
paul718e3742002-12-13 20:15:29 +00001736rib_delnode (struct route_node *rn, struct rib *rib)
1737{
Paul Jakma6d691122006-07-27 21:49:00 +00001738 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001739 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001740 char buf[INET6_ADDRSTRLEN];
1741 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001742 zlog_debug ("%s: %s/%d: rn %p, rib %p, removing", __func__,
1743 buf, rn->p.prefixlen, rn, rib);
1744 }
Paul Jakma6d691122006-07-27 21:49:00 +00001745 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1746 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001747}
1748
1749int
1750rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001751 struct in_addr *gate, struct in_addr *src,
1752 unsigned int ifindex, u_int32_t vrf_id,
G.Balajicddf3912011-11-26 21:59:32 +04001753 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001754{
1755 struct rib *rib;
1756 struct rib *same = NULL;
1757 struct route_table *table;
1758 struct route_node *rn;
1759 struct nexthop *nexthop;
1760
1761 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04001762 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00001763 if (! table)
1764 return 0;
1765
1766 /* Make it sure prefixlen is applied to the prefix. */
1767 apply_mask_ipv4 (p);
1768
1769 /* Set default distance by route type. */
1770 if (distance == 0)
1771 {
Balaji.G837d16c2012-09-26 14:09:10 +05301772 if ((unsigned)type >= array_size(route_info))
David Lamparter7052f222009-08-27 00:28:28 +02001773 distance = 150;
1774 else
1775 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00001776
1777 /* iBGP distance is 200. */
1778 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1779 distance = 200;
1780 }
1781
1782 /* Lookup route node.*/
1783 rn = route_node_get (table, (struct prefix *) p);
1784
1785 /* If same type of route are installed, treat it as a implicit
1786 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001787 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00001788 {
Paul Jakma6d691122006-07-27 21:49:00 +00001789 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1790 continue;
1791
hassoebf1ead2005-09-21 14:58:20 +00001792 if (rib->type != type)
1793 continue;
1794 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001795 {
1796 same = rib;
1797 break;
1798 }
hassoebf1ead2005-09-21 14:58:20 +00001799 /* Duplicate connected route comes in. */
1800 else if ((nexthop = rib->nexthop) &&
1801 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001802 nexthop->ifindex == ifindex &&
1803 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001804 {
1805 rib->refcnt++;
1806 return 0 ;
1807 }
paul718e3742002-12-13 20:15:29 +00001808 }
1809
1810 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001811 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001812 rib->type = type;
1813 rib->distance = distance;
1814 rib->flags = flags;
1815 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001816 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001817 rib->nexthop_num = 0;
1818 rib->uptime = time (NULL);
1819
1820 /* Nexthop settings. */
1821 if (gate)
1822 {
1823 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001824 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001825 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001826 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001827 }
1828 else
1829 nexthop_ifindex_add (rib, ifindex);
1830
1831 /* If this route is kernel route, set FIB flag to the route. */
1832 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1833 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1834 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1835
1836 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001837 if (IS_ZEBRA_DEBUG_RIB)
1838 zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
paul718e3742002-12-13 20:15:29 +00001839 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001840
paul718e3742002-12-13 20:15:29 +00001841 /* Free implicit route.*/
1842 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001843 {
1844 if (IS_ZEBRA_DEBUG_RIB)
1845 zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001846 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001847 }
paul4d38fdb2005-04-28 17:35:14 +00001848
1849 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001850 return 0;
1851}
1852
Denis Ovsienkodc958242007-08-13 16:03:06 +00001853/* This function dumps the contents of a given RIB entry into
1854 * standard debug log. Calling function name and IP prefix in
1855 * question are passed as 1st and 2nd arguments.
1856 */
1857
1858void rib_dump (const char * func, const struct prefix_ipv4 * p, const struct rib * rib)
1859{
Christian Frankefa713d92013-07-05 15:35:37 +00001860 char straddr[INET_ADDRSTRLEN];
1861 struct nexthop *nexthop, *tnexthop;
1862 int recursing;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001863
Christian Frankefa713d92013-07-05 15:35:37 +00001864 inet_ntop (AF_INET, &p->prefix, straddr, INET_ADDRSTRLEN);
1865 zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr, p->prefixlen);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001866 zlog_debug
1867 (
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001868 "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
Denis Ovsienkodc958242007-08-13 16:03:06 +00001869 func,
1870 rib->refcnt,
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001871 (unsigned long) rib->uptime,
Denis Ovsienkodc958242007-08-13 16:03:06 +00001872 rib->type,
1873 rib->table
1874 );
1875 zlog_debug
1876 (
1877 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1878 func,
1879 rib->metric,
1880 rib->distance,
1881 rib->flags,
1882 rib->status
1883 );
1884 zlog_debug
1885 (
1886 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1887 func,
1888 rib->nexthop_num,
1889 rib->nexthop_active_num,
1890 rib->nexthop_fib_num
1891 );
Christian Frankefa713d92013-07-05 15:35:37 +00001892 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1893 {
1894 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, straddr, INET_ADDRSTRLEN);
1895 zlog_debug
1896 (
1897 "%s: %s %s with flags %s%s%s",
1898 func,
1899 (recursing ? " NH" : "NH"),
1900 straddr,
1901 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1902 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1903 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1904 );
1905 }
Denis Ovsienkodc958242007-08-13 16:03:06 +00001906 zlog_debug ("%s: dump complete", func);
1907}
1908
1909/* This is an exported helper to rtm_read() to dump the strange
1910 * RIB entry found by rib_lookup_ipv4_route()
1911 */
1912
1913void rib_lookup_and_dump (struct prefix_ipv4 * p)
1914{
1915 struct route_table *table;
1916 struct route_node *rn;
1917 struct rib *rib;
1918 char prefix_buf[INET_ADDRSTRLEN];
1919
1920 /* Lookup table. */
1921 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1922 if (! table)
1923 {
1924 zlog_err ("%s: vrf_table() returned NULL", __func__);
1925 return;
1926 }
1927
1928 inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
1929 /* Scan the RIB table for exactly matching RIB entry. */
1930 rn = route_node_lookup (table, (struct prefix *) p);
1931
1932 /* No route for this prefix. */
1933 if (! rn)
1934 {
1935 zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
1936 return;
1937 }
1938
1939 /* Unlock node. */
1940 route_unlock_node (rn);
1941
1942 /* let's go */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001943 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001944 {
1945 zlog_debug
1946 (
1947 "%s: rn %p, rib %p: %s, %s",
1948 __func__,
1949 rn,
1950 rib,
1951 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
1952 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
1953 );
1954 rib_dump (__func__, p, rib);
1955 }
1956}
1957
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001958/* Check if requested address assignment will fail due to another
1959 * route being installed by zebra in FIB already. Take necessary
1960 * actions, if needed: remove such a route from FIB and deSELECT
1961 * corresponding RIB entry. Then put affected RN into RIBQ head.
1962 */
1963void rib_lookup_and_pushup (struct prefix_ipv4 * p)
1964{
1965 struct route_table *table;
1966 struct route_node *rn;
1967 struct rib *rib;
1968 unsigned changed = 0;
1969
1970 if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
1971 {
1972 zlog_err ("%s: vrf_table() returned NULL", __func__);
1973 return;
1974 }
1975
1976 /* No matches would be the simplest case. */
1977 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
1978 return;
1979
1980 /* Unlock node. */
1981 route_unlock_node (rn);
1982
1983 /* Check all RIB entries. In case any changes have to be done, requeue
1984 * the RN into RIBQ head. If the routing message about the new connected
1985 * route (generated by the IP address we are going to assign very soon)
1986 * comes before the RIBQ is processed, the new RIB entry will join
1987 * RIBQ record already on head. This is necessary for proper revalidation
1988 * of the rest of the RIB.
1989 */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001990 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001991 {
1992 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
1993 ! RIB_SYSTEM_ROUTE (rib))
1994 {
1995 changed = 1;
1996 if (IS_ZEBRA_DEBUG_RIB)
1997 {
1998 char buf[INET_ADDRSTRLEN];
1999 inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
2000 zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
2001 rib_dump (__func__, (struct prefix_ipv4 *)&rn->p, rib);
2002 }
2003 rib_uninstall (rn, rib);
2004 }
2005 }
2006 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002007 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002008}
2009
paul718e3742002-12-13 20:15:29 +00002010int
G.Balajicddf3912011-11-26 21:59:32 +04002011rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002012{
2013 struct route_table *table;
2014 struct route_node *rn;
2015 struct rib *same;
2016 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00002017
paul718e3742002-12-13 20:15:29 +00002018 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04002019 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00002020 if (! table)
2021 return 0;
G.Balajicddf3912011-11-26 21:59:32 +04002022
paul718e3742002-12-13 20:15:29 +00002023 /* Make it sure prefixlen is applied to the prefix. */
2024 apply_mask_ipv4 (p);
2025
2026 /* Set default distance by route type. */
2027 if (rib->distance == 0)
2028 {
2029 rib->distance = route_info[rib->type].distance;
2030
2031 /* iBGP distance is 200. */
2032 if (rib->type == ZEBRA_ROUTE_BGP
2033 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
2034 rib->distance = 200;
2035 }
2036
2037 /* Lookup route node.*/
2038 rn = route_node_get (table, (struct prefix *) p);
2039
2040 /* If same type of route are installed, treat it as a implicit
2041 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002042 RNODE_FOREACH_RIB (rn, same)
paul718e3742002-12-13 20:15:29 +00002043 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00002044 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00002045 continue;
2046
paul718e3742002-12-13 20:15:29 +00002047 if (same->type == rib->type && same->table == rib->table
2048 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00002049 break;
paul718e3742002-12-13 20:15:29 +00002050 }
paul4d38fdb2005-04-28 17:35:14 +00002051
paul718e3742002-12-13 20:15:29 +00002052 /* If this route is kernel route, set FIB flag to the route. */
2053 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
2054 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2055 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2056
2057 /* Link new rib to node.*/
2058 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002059 if (IS_ZEBRA_DEBUG_RIB)
2060 {
2061 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
2062 __func__, rn, rib);
2063 rib_dump (__func__, p, rib);
2064 }
paul718e3742002-12-13 20:15:29 +00002065
paul718e3742002-12-13 20:15:29 +00002066 /* Free implicit route.*/
2067 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00002068 {
2069 if (IS_ZEBRA_DEBUG_RIB)
2070 {
2071 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
2072 __func__, rn, same);
2073 rib_dump (__func__, p, same);
2074 }
paul4d38fdb2005-04-28 17:35:14 +00002075 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002076 }
paul4d38fdb2005-04-28 17:35:14 +00002077
2078 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002079 return 0;
2080}
2081
hassoebf1ead2005-09-21 14:58:20 +00002082/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002083int
2084rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
G.Balajicddf3912011-11-26 21:59:32 +04002085 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002086{
2087 struct route_table *table;
2088 struct route_node *rn;
2089 struct rib *rib;
2090 struct rib *fib = NULL;
2091 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002092 struct nexthop *nexthop, *tnexthop;
2093 int recursing;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002094 char buf1[INET_ADDRSTRLEN];
2095 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002096
2097 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04002098 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00002099 if (! table)
2100 return 0;
2101
2102 /* Apply mask. */
2103 apply_mask_ipv4 (p);
2104
paul5ec90d22003-06-19 01:41:37 +00002105 if (IS_ZEBRA_DEBUG_KERNEL && gate)
ajsb6178002004-12-07 21:12:56 +00002106 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002107 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul5ec90d22003-06-19 01:41:37 +00002108 p->prefixlen,
2109 inet_ntoa (*gate),
2110 ifindex);
2111
paul718e3742002-12-13 20:15:29 +00002112 /* Lookup route node. */
2113 rn = route_node_lookup (table, (struct prefix *) p);
2114 if (! rn)
2115 {
2116 if (IS_ZEBRA_DEBUG_KERNEL)
2117 {
2118 if (gate)
ajsb6178002004-12-07 21:12:56 +00002119 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002120 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002121 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002122 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002123 ifindex);
2124 else
ajsb6178002004-12-07 21:12:56 +00002125 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002126 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002127 p->prefixlen,
2128 ifindex);
2129 }
2130 return ZEBRA_ERR_RTNOEXIST;
2131 }
2132
2133 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002134 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002135 {
Paul Jakma6d691122006-07-27 21:49:00 +00002136 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2137 continue;
2138
paul718e3742002-12-13 20:15:29 +00002139 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2140 fib = rib;
2141
hassoebf1ead2005-09-21 14:58:20 +00002142 if (rib->type != type)
2143 continue;
2144 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002145 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002146 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002147 if (nexthop->ifindex != ifindex)
2148 continue;
hassoebf1ead2005-09-21 14:58:20 +00002149 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002150 {
hassoebf1ead2005-09-21 14:58:20 +00002151 rib->refcnt--;
2152 route_unlock_node (rn);
2153 route_unlock_node (rn);
2154 return 0;
paul718e3742002-12-13 20:15:29 +00002155 }
hassoebf1ead2005-09-21 14:58:20 +00002156 same = rib;
2157 break;
paul718e3742002-12-13 20:15:29 +00002158 }
hassoebf1ead2005-09-21 14:58:20 +00002159 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002160 else
paul5ec90d22003-06-19 01:41:37 +00002161 {
Christian Frankefa713d92013-07-05 15:35:37 +00002162 if (gate == NULL)
2163 {
2164 same = rib;
2165 break;
2166 }
2167 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2168 if (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate))
2169 {
2170 same = rib;
2171 break;
2172 }
2173 if (same)
2174 break;
2175 }
paul718e3742002-12-13 20:15:29 +00002176 }
paul718e3742002-12-13 20:15:29 +00002177 /* If same type of route can't be found and this message is from
2178 kernel. */
2179 if (! same)
2180 {
2181 if (fib && type == ZEBRA_ROUTE_KERNEL)
2182 {
2183 /* Unset flags. */
2184 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2185 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2186
2187 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2188 }
2189 else
2190 {
2191 if (IS_ZEBRA_DEBUG_KERNEL)
2192 {
2193 if (gate)
ajsb6178002004-12-07 21:12:56 +00002194 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002195 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002196 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002197 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002198 ifindex,
2199 type);
2200 else
ajsb6178002004-12-07 21:12:56 +00002201 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002202 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002203 p->prefixlen,
2204 ifindex,
2205 type);
2206 }
2207 route_unlock_node (rn);
2208 return ZEBRA_ERR_RTNOEXIST;
2209 }
2210 }
paul4d38fdb2005-04-28 17:35:14 +00002211
paul718e3742002-12-13 20:15:29 +00002212 if (same)
2213 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002214
paul718e3742002-12-13 20:15:29 +00002215 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002216 return 0;
2217}
2218
2219/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002220static void
paul718e3742002-12-13 20:15:29 +00002221static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
2222{
2223 struct rib *rib;
2224 struct route_node *rn;
2225 struct route_table *table;
2226
2227 /* Lookup table. */
2228 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2229 if (! table)
2230 return;
2231
2232 /* Lookup existing route */
2233 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002234 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002235 {
2236 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2237 continue;
2238
2239 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2240 break;
2241 }
paul718e3742002-12-13 20:15:29 +00002242
2243 if (rib)
2244 {
2245 /* Same distance static route is there. Update it with new
2246 nexthop. */
paul718e3742002-12-13 20:15:29 +00002247 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002248 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002249 {
2250 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002251 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002252 break;
2253 case STATIC_IPV4_IFNAME:
2254 nexthop_ifname_add (rib, si->gate.ifname);
2255 break;
2256 case STATIC_IPV4_BLACKHOLE:
2257 nexthop_blackhole_add (rib);
2258 break;
paul4d38fdb2005-04-28 17:35:14 +00002259 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002260 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002261 }
2262 else
2263 {
2264 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002265 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2266
paul718e3742002-12-13 20:15:29 +00002267 rib->type = ZEBRA_ROUTE_STATIC;
2268 rib->distance = si->distance;
2269 rib->metric = 0;
Nolan Leakeb0145dd2012-09-13 17:17:31 +00002270 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002271 rib->nexthop_num = 0;
2272
2273 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002274 {
2275 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002276 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002277 break;
2278 case STATIC_IPV4_IFNAME:
2279 nexthop_ifname_add (rib, si->gate.ifname);
2280 break;
2281 case STATIC_IPV4_BLACKHOLE:
2282 nexthop_blackhole_add (rib);
2283 break;
2284 }
paul718e3742002-12-13 20:15:29 +00002285
hasso81dfcaa2003-05-25 19:21:25 +00002286 /* Save the flags of this static routes (reject, blackhole) */
2287 rib->flags = si->flags;
2288
paul718e3742002-12-13 20:15:29 +00002289 /* Link this rib to the tree. */
2290 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002291 }
2292}
2293
paula1ac18c2005-06-28 17:17:12 +00002294static int
paul718e3742002-12-13 20:15:29 +00002295static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2296{
2297 if (nexthop->type == NEXTHOP_TYPE_IPV4
2298 && si->type == STATIC_IPV4_GATEWAY
2299 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2300 return 1;
2301 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2302 && si->type == STATIC_IPV4_IFNAME
2303 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2304 return 1;
paul595db7f2003-05-25 21:35:06 +00002305 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2306 && si->type == STATIC_IPV4_BLACKHOLE)
2307 return 1;
paule8e19462006-01-19 20:16:55 +00002308 return 0;
paul718e3742002-12-13 20:15:29 +00002309}
2310
2311/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002312static void
paul718e3742002-12-13 20:15:29 +00002313static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
2314{
2315 struct route_node *rn;
2316 struct rib *rib;
2317 struct nexthop *nexthop;
2318 struct route_table *table;
2319
2320 /* Lookup table. */
2321 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2322 if (! table)
2323 return;
paul4d38fdb2005-04-28 17:35:14 +00002324
paul718e3742002-12-13 20:15:29 +00002325 /* Lookup existing route with type and distance. */
2326 rn = route_node_lookup (table, p);
2327 if (! rn)
2328 return;
2329
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002330 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002331 {
2332 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2333 continue;
2334
2335 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2336 break;
2337 }
paul718e3742002-12-13 20:15:29 +00002338
2339 if (! rib)
2340 {
2341 route_unlock_node (rn);
2342 return;
2343 }
2344
2345 /* Lookup nexthop. */
2346 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2347 if (static_ipv4_nexthop_same (nexthop, si))
2348 break;
2349
2350 /* Can't find nexthop. */
2351 if (! nexthop)
2352 {
2353 route_unlock_node (rn);
2354 return;
2355 }
2356
2357 /* Check nexthop. */
2358 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002359 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002360 else
2361 {
paul6baeb982003-10-28 03:47:15 +00002362 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2363 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002364 nexthop_delete (rib, nexthop);
2365 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002366 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002367 }
paul718e3742002-12-13 20:15:29 +00002368 /* Unlock node. */
2369 route_unlock_node (rn);
2370}
2371
2372/* Add static route into static route configuration. */
2373int
hasso39db97e2004-10-12 20:50:58 +00002374static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00002375 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002376{
2377 u_char type = 0;
2378 struct route_node *rn;
2379 struct static_ipv4 *si;
2380 struct static_ipv4 *pp;
2381 struct static_ipv4 *cp;
2382 struct static_ipv4 *update = NULL;
2383 struct route_table *stable;
2384
2385 /* Lookup table. */
2386 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2387 if (! stable)
2388 return -1;
2389
2390 /* Lookup static route prefix. */
2391 rn = route_node_get (stable, p);
2392
2393 /* Make flags. */
2394 if (gate)
2395 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002396 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002397 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002398 else
2399 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002400
2401 /* Do nothing if there is a same static route. */
2402 for (si = rn->info; si; si = si->next)
2403 {
2404 if (type == si->type
2405 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2406 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2407 {
2408 if (distance == si->distance)
2409 {
2410 route_unlock_node (rn);
2411 return 0;
2412 }
2413 else
2414 update = si;
2415 }
2416 }
2417
Paul Jakma3c0755d2006-12-08 00:53:14 +00002418 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002419 if (update)
2420 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
2421
2422 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002423 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
paul718e3742002-12-13 20:15:29 +00002424
2425 si->type = type;
2426 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002427 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002428
2429 if (gate)
2430 si->gate.ipv4 = *gate;
2431 if (ifname)
2432 si->gate.ifname = XSTRDUP (0, ifname);
2433
2434 /* Add new static route information to the tree with sort by
2435 distance value and gateway address. */
2436 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2437 {
2438 if (si->distance < cp->distance)
2439 break;
2440 if (si->distance > cp->distance)
2441 continue;
2442 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2443 {
2444 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2445 break;
2446 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2447 continue;
2448 }
2449 }
2450
2451 /* Make linked list. */
2452 if (pp)
2453 pp->next = si;
2454 else
2455 rn->info = si;
2456 if (cp)
2457 cp->prev = si;
2458 si->prev = pp;
2459 si->next = cp;
2460
2461 /* Install into rib. */
2462 static_install_ipv4 (p, si);
2463
2464 return 1;
2465}
2466
2467/* Delete static route from static route configuration. */
2468int
hasso39db97e2004-10-12 20:50:58 +00002469static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00002470 u_char distance, u_int32_t vrf_id)
2471{
2472 u_char type = 0;
2473 struct route_node *rn;
2474 struct static_ipv4 *si;
2475 struct route_table *stable;
2476
2477 /* Lookup table. */
2478 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2479 if (! stable)
2480 return -1;
2481
2482 /* Lookup static route prefix. */
2483 rn = route_node_lookup (stable, p);
2484 if (! rn)
2485 return 0;
2486
2487 /* Make flags. */
2488 if (gate)
2489 type = STATIC_IPV4_GATEWAY;
2490 else if (ifname)
2491 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002492 else
2493 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002494
2495 /* Find same static route is the tree */
2496 for (si = rn->info; si; si = si->next)
2497 if (type == si->type
2498 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2499 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2500 break;
2501
2502 /* Can't find static route. */
2503 if (! si)
2504 {
2505 route_unlock_node (rn);
2506 return 0;
2507 }
2508
2509 /* Install into rib. */
2510 static_uninstall_ipv4 (p, si);
2511
2512 /* Unlink static route from linked list. */
2513 if (si->prev)
2514 si->prev->next = si->next;
2515 else
2516 rn->info = si->next;
2517 if (si->next)
2518 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002519 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002520
2521 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002522 if (ifname)
2523 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002524 XFREE (MTYPE_STATIC_IPV4, si);
2525
paul143a3852003-09-29 20:06:13 +00002526 route_unlock_node (rn);
2527
paul718e3742002-12-13 20:15:29 +00002528 return 1;
2529}
2530
2531
2532#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00002533static int
paul718e3742002-12-13 20:15:29 +00002534rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2535 struct in6_addr *gate, unsigned int ifindex, int table)
2536{
hasso726f9b22003-05-25 21:04:54 +00002537 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2538#if defined (MUSICA) || defined (LINUX)
2539 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2540 if (p->prefixlen == 96)
2541 return 0;
2542#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00002543 return 1;
hasso726f9b22003-05-25 21:04:54 +00002544 }
paul718e3742002-12-13 20:15:29 +00002545 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
2546 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
2547 {
2548 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
2549 return 1;
2550 }
2551 return 0;
2552}
2553
2554int
2555rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00002556 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
G.Balajif768f362011-11-26 22:10:39 +04002557 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002558{
2559 struct rib *rib;
2560 struct rib *same = NULL;
2561 struct route_table *table;
2562 struct route_node *rn;
2563 struct nexthop *nexthop;
2564
paul718e3742002-12-13 20:15:29 +00002565 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002566 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002567 if (! table)
2568 return 0;
2569
2570 /* Make sure mask is applied. */
2571 apply_mask_ipv6 (p);
2572
2573 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002574 if (!distance)
2575 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002576
2577 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2578 distance = 200;
2579
2580 /* Filter bogus route. */
2581 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
2582 return 0;
2583
2584 /* Lookup route node.*/
2585 rn = route_node_get (table, (struct prefix *) p);
2586
2587 /* If same type of route are installed, treat it as a implicit
2588 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002589 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002590 {
Paul Jakma6d691122006-07-27 21:49:00 +00002591 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2592 continue;
2593
hassoebf1ead2005-09-21 14:58:20 +00002594 if (rib->type != type)
2595 continue;
2596 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002597 {
2598 same = rib;
paul718e3742002-12-13 20:15:29 +00002599 break;
2600 }
hassoebf1ead2005-09-21 14:58:20 +00002601 else if ((nexthop = rib->nexthop) &&
2602 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2603 nexthop->ifindex == ifindex)
2604 {
2605 rib->refcnt++;
2606 return 0;
2607 }
paul718e3742002-12-13 20:15:29 +00002608 }
2609
2610 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002611 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2612
paul718e3742002-12-13 20:15:29 +00002613 rib->type = type;
2614 rib->distance = distance;
2615 rib->flags = flags;
2616 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00002617 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00002618 rib->nexthop_num = 0;
2619 rib->uptime = time (NULL);
2620
2621 /* Nexthop settings. */
2622 if (gate)
2623 {
2624 if (ifindex)
2625 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2626 else
2627 nexthop_ipv6_add (rib, gate);
2628 }
2629 else
2630 nexthop_ifindex_add (rib, ifindex);
2631
2632 /* If this route is kernel route, set FIB flag to the route. */
2633 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2634 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2635 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2636
2637 /* Link new rib to node.*/
2638 rib_addnode (rn, rib);
2639
paul718e3742002-12-13 20:15:29 +00002640 /* Free implicit route.*/
2641 if (same)
paul4d38fdb2005-04-28 17:35:14 +00002642 rib_delnode (rn, same);
2643
2644 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002645 return 0;
2646}
2647
hassoebf1ead2005-09-21 14:58:20 +00002648/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002649int
2650rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
G.Balajif768f362011-11-26 22:10:39 +04002651 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002652{
2653 struct route_table *table;
2654 struct route_node *rn;
2655 struct rib *rib;
2656 struct rib *fib = NULL;
2657 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002658 struct nexthop *nexthop, *tnexthop;
2659 int recursing;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002660 char buf1[INET6_ADDRSTRLEN];
2661 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002662
2663 /* Apply mask. */
2664 apply_mask_ipv6 (p);
2665
2666 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002667 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002668 if (! table)
2669 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002670
paul718e3742002-12-13 20:15:29 +00002671 /* Lookup route node. */
2672 rn = route_node_lookup (table, (struct prefix *) p);
2673 if (! rn)
2674 {
2675 if (IS_ZEBRA_DEBUG_KERNEL)
2676 {
2677 if (gate)
ajsb6178002004-12-07 21:12:56 +00002678 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002679 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002680 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002681 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002682 ifindex);
2683 else
ajsb6178002004-12-07 21:12:56 +00002684 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002685 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002686 p->prefixlen,
2687 ifindex);
2688 }
2689 return ZEBRA_ERR_RTNOEXIST;
2690 }
2691
2692 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002693 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002694 {
Paul Jakma6d691122006-07-27 21:49:00 +00002695 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2696 continue;
2697
paul718e3742002-12-13 20:15:29 +00002698 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2699 fib = rib;
2700
hassoebf1ead2005-09-21 14:58:20 +00002701 if (rib->type != type)
2702 continue;
2703 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002704 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002705 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002706 if (nexthop->ifindex != ifindex)
2707 continue;
hassoebf1ead2005-09-21 14:58:20 +00002708 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002709 {
hassoebf1ead2005-09-21 14:58:20 +00002710 rib->refcnt--;
2711 route_unlock_node (rn);
2712 route_unlock_node (rn);
2713 return 0;
paul718e3742002-12-13 20:15:29 +00002714 }
hassoebf1ead2005-09-21 14:58:20 +00002715 same = rib;
2716 break;
paul718e3742002-12-13 20:15:29 +00002717 }
hassoebf1ead2005-09-21 14:58:20 +00002718 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002719 else
2720 {
2721 if (gate == NULL)
2722 {
2723 same = rib;
2724 break;
2725 }
2726 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2727 if (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate))
2728 {
2729 same = rib;
2730 break;
2731 }
2732 if (same)
2733 break;
2734 }
paul718e3742002-12-13 20:15:29 +00002735 }
2736
2737 /* If same type of route can't be found and this message is from
2738 kernel. */
2739 if (! same)
2740 {
2741 if (fib && type == ZEBRA_ROUTE_KERNEL)
2742 {
2743 /* Unset flags. */
2744 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2745 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2746
2747 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2748 }
2749 else
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 type %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 type);
2760 else
ajsb6178002004-12-07 21:12:56 +00002761 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002762 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002763 p->prefixlen,
2764 ifindex,
2765 type);
2766 }
2767 route_unlock_node (rn);
2768 return ZEBRA_ERR_RTNOEXIST;
2769 }
2770 }
2771
2772 if (same)
2773 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002774
paul718e3742002-12-13 20:15:29 +00002775 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002776 return 0;
2777}
2778
2779/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002780static void
paul718e3742002-12-13 20:15:29 +00002781static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2782{
2783 struct rib *rib;
2784 struct route_table *table;
2785 struct route_node *rn;
2786
2787 /* Lookup table. */
2788 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2789 if (! table)
2790 return;
2791
2792 /* Lookup existing route */
2793 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002794 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002795 {
2796 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2797 continue;
2798
2799 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2800 break;
2801 }
paul718e3742002-12-13 20:15:29 +00002802
2803 if (rib)
2804 {
2805 /* Same distance static route is there. Update it with new
2806 nexthop. */
paul718e3742002-12-13 20:15:29 +00002807 route_unlock_node (rn);
2808
2809 switch (si->type)
2810 {
2811 case STATIC_IPV6_GATEWAY:
2812 nexthop_ipv6_add (rib, &si->ipv6);
2813 break;
2814 case STATIC_IPV6_IFNAME:
2815 nexthop_ifname_add (rib, si->ifname);
2816 break;
2817 case STATIC_IPV6_GATEWAY_IFNAME:
2818 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2819 break;
2820 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002821 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002822 }
2823 else
2824 {
2825 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002826 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2827
paul718e3742002-12-13 20:15:29 +00002828 rib->type = ZEBRA_ROUTE_STATIC;
2829 rib->distance = si->distance;
2830 rib->metric = 0;
2831 rib->nexthop_num = 0;
2832
2833 switch (si->type)
2834 {
2835 case STATIC_IPV6_GATEWAY:
2836 nexthop_ipv6_add (rib, &si->ipv6);
2837 break;
2838 case STATIC_IPV6_IFNAME:
2839 nexthop_ifname_add (rib, si->ifname);
2840 break;
2841 case STATIC_IPV6_GATEWAY_IFNAME:
2842 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2843 break;
2844 }
2845
hasso81dfcaa2003-05-25 19:21:25 +00002846 /* Save the flags of this static routes (reject, blackhole) */
2847 rib->flags = si->flags;
2848
paul718e3742002-12-13 20:15:29 +00002849 /* Link this rib to the tree. */
2850 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002851 }
2852}
2853
paula1ac18c2005-06-28 17:17:12 +00002854static int
paul718e3742002-12-13 20:15:29 +00002855static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2856{
2857 if (nexthop->type == NEXTHOP_TYPE_IPV6
2858 && si->type == STATIC_IPV6_GATEWAY
2859 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2860 return 1;
2861 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2862 && si->type == STATIC_IPV6_IFNAME
2863 && strcmp (nexthop->ifname, si->ifname) == 0)
2864 return 1;
2865 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2866 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2867 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2868 && strcmp (nexthop->ifname, si->ifname) == 0)
2869 return 1;
paule8e19462006-01-19 20:16:55 +00002870 return 0;
paul718e3742002-12-13 20:15:29 +00002871}
2872
paula1ac18c2005-06-28 17:17:12 +00002873static void
paul718e3742002-12-13 20:15:29 +00002874static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2875{
2876 struct route_table *table;
2877 struct route_node *rn;
2878 struct rib *rib;
2879 struct nexthop *nexthop;
2880
2881 /* Lookup table. */
2882 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2883 if (! table)
2884 return;
2885
2886 /* Lookup existing route with type and distance. */
2887 rn = route_node_lookup (table, (struct prefix *) p);
2888 if (! rn)
2889 return;
2890
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002891 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002892 {
2893 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2894 continue;
2895
2896 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2897 break;
2898 }
2899
paul718e3742002-12-13 20:15:29 +00002900 if (! rib)
2901 {
2902 route_unlock_node (rn);
2903 return;
2904 }
2905
2906 /* Lookup nexthop. */
2907 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2908 if (static_ipv6_nexthop_same (nexthop, si))
2909 break;
2910
2911 /* Can't find nexthop. */
2912 if (! nexthop)
2913 {
2914 route_unlock_node (rn);
2915 return;
2916 }
2917
2918 /* Check nexthop. */
2919 if (rib->nexthop_num == 1)
2920 {
2921 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002922 }
2923 else
2924 {
paul6baeb982003-10-28 03:47:15 +00002925 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2926 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002927 nexthop_delete (rib, nexthop);
2928 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002929 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002930 }
paul718e3742002-12-13 20:15:29 +00002931 /* Unlock node. */
2932 route_unlock_node (rn);
2933}
2934
2935/* Add static route into static route configuration. */
2936int
2937static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002938 const char *ifname, u_char flags, u_char distance,
2939 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002940{
2941 struct route_node *rn;
2942 struct static_ipv6 *si;
2943 struct static_ipv6 *pp;
2944 struct static_ipv6 *cp;
2945 struct route_table *stable;
2946
2947 /* Lookup table. */
2948 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2949 if (! stable)
2950 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00002951
2952 if (!gate &&
2953 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
2954 return -1;
2955
2956 if (!ifname &&
2957 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
2958 return -1;
paul718e3742002-12-13 20:15:29 +00002959
2960 /* Lookup static route prefix. */
2961 rn = route_node_get (stable, p);
2962
2963 /* Do nothing if there is a same static route. */
2964 for (si = rn->info; si; si = si->next)
2965 {
2966 if (distance == si->distance
2967 && type == si->type
2968 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2969 && (! ifname || strcmp (ifname, si->ifname) == 0))
2970 {
2971 route_unlock_node (rn);
2972 return 0;
2973 }
2974 }
2975
2976 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002977 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
paul718e3742002-12-13 20:15:29 +00002978
2979 si->type = type;
2980 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002981 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002982
2983 switch (type)
2984 {
2985 case STATIC_IPV6_GATEWAY:
2986 si->ipv6 = *gate;
2987 break;
2988 case STATIC_IPV6_IFNAME:
2989 si->ifname = XSTRDUP (0, ifname);
2990 break;
2991 case STATIC_IPV6_GATEWAY_IFNAME:
2992 si->ipv6 = *gate;
2993 si->ifname = XSTRDUP (0, ifname);
2994 break;
2995 }
2996
2997 /* Add new static route information to the tree with sort by
2998 distance value and gateway address. */
2999 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
3000 {
3001 if (si->distance < cp->distance)
3002 break;
3003 if (si->distance > cp->distance)
3004 continue;
3005 }
3006
3007 /* Make linked list. */
3008 if (pp)
3009 pp->next = si;
3010 else
3011 rn->info = si;
3012 if (cp)
3013 cp->prev = si;
3014 si->prev = pp;
3015 si->next = cp;
3016
3017 /* Install into rib. */
3018 static_install_ipv6 (p, si);
3019
3020 return 1;
3021}
3022
3023/* Delete static route from static route configuration. */
3024int
3025static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00003026 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00003027{
3028 struct route_node *rn;
3029 struct static_ipv6 *si;
3030 struct route_table *stable;
3031
3032 /* Lookup table. */
3033 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
3034 if (! stable)
3035 return -1;
3036
3037 /* Lookup static route prefix. */
3038 rn = route_node_lookup (stable, p);
3039 if (! rn)
3040 return 0;
3041
3042 /* Find same static route is the tree */
3043 for (si = rn->info; si; si = si->next)
3044 if (distance == si->distance
3045 && type == si->type
3046 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
3047 && (! ifname || strcmp (ifname, si->ifname) == 0))
3048 break;
3049
3050 /* Can't find static route. */
3051 if (! si)
3052 {
3053 route_unlock_node (rn);
3054 return 0;
3055 }
3056
3057 /* Install into rib. */
3058 static_uninstall_ipv6 (p, si);
3059
3060 /* Unlink static route from linked list. */
3061 if (si->prev)
3062 si->prev->next = si->next;
3063 else
3064 rn->info = si->next;
3065 if (si->next)
3066 si->next->prev = si->prev;
3067
3068 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00003069 if (ifname)
3070 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00003071 XFREE (MTYPE_STATIC_IPV6, si);
3072
3073 return 1;
3074}
3075#endif /* HAVE_IPV6 */
3076
3077/* RIB update function. */
3078void
paula1ac18c2005-06-28 17:17:12 +00003079rib_update (void)
paul718e3742002-12-13 20:15:29 +00003080{
3081 struct route_node *rn;
3082 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00003083
paul718e3742002-12-13 20:15:29 +00003084 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
3085 if (table)
3086 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003087 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003088 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003089
3090 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
3091 if (table)
3092 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003093 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003094 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003095}
3096
paul718e3742002-12-13 20:15:29 +00003097
3098/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00003099static void
paul718e3742002-12-13 20:15:29 +00003100rib_weed_table (struct route_table *table)
3101{
3102 struct route_node *rn;
3103 struct rib *rib;
3104 struct rib *next;
3105
3106 if (table)
3107 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003108 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003109 {
Paul Jakma6d691122006-07-27 21:49:00 +00003110 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3111 continue;
3112
paulb21b19c2003-06-15 01:28:29 +00003113 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00003114 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00003115 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003116 }
3117}
3118
3119/* Delete all routes from non main table. */
3120void
paula1ac18c2005-06-28 17:17:12 +00003121rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00003122{
3123 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3124 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3125}
3126
3127/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00003128static void
paul718e3742002-12-13 20:15:29 +00003129rib_sweep_table (struct route_table *table)
3130{
3131 struct route_node *rn;
3132 struct rib *rib;
3133 struct rib *next;
3134 int ret = 0;
3135
3136 if (table)
3137 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003138 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003139 {
Paul Jakma6d691122006-07-27 21:49:00 +00003140 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3141 continue;
3142
paul718e3742002-12-13 20:15:29 +00003143 if (rib->type == ZEBRA_ROUTE_KERNEL &&
3144 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
3145 {
3146 ret = rib_uninstall_kernel (rn, rib);
3147 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00003148 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003149 }
3150 }
3151}
3152
3153/* Sweep all RIB tables. */
3154void
paula1ac18c2005-06-28 17:17:12 +00003155rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00003156{
3157 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3158 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3159}
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003160
3161/* Remove specific by protocol routes from 'table'. */
3162static unsigned long
3163rib_score_proto_table (u_char proto, struct route_table *table)
3164{
3165 struct route_node *rn;
3166 struct rib *rib;
3167 struct rib *next;
3168 unsigned long n = 0;
3169
3170 if (table)
3171 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003172 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003173 {
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003174 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3175 continue;
3176 if (rib->type == proto)
3177 {
3178 rib_delnode (rn, rib);
3179 n++;
3180 }
3181 }
3182
3183 return n;
3184}
3185
3186/* Remove specific by protocol routes. */
3187unsigned long
3188rib_score_proto (u_char proto)
3189{
3190 return rib_score_proto_table (proto, vrf_table (AFI_IP, SAFI_UNICAST, 0))
3191 +rib_score_proto_table (proto, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3192}
3193
paul718e3742002-12-13 20:15:29 +00003194/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00003195static void
paul718e3742002-12-13 20:15:29 +00003196rib_close_table (struct route_table *table)
3197{
3198 struct route_node *rn;
3199 struct rib *rib;
3200
3201 if (table)
3202 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003203 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00003204 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003205 if (!CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
3206 continue;
3207
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00003208 zfpm_trigger_update (rn, NULL);
3209
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003210 if (! RIB_SYSTEM_ROUTE (rib))
3211 rib_uninstall_kernel (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00003212 }
paul718e3742002-12-13 20:15:29 +00003213}
3214
3215/* Close all RIB tables. */
3216void
paula1ac18c2005-06-28 17:17:12 +00003217rib_close (void)
paul718e3742002-12-13 20:15:29 +00003218{
3219 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3220 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3221}
3222
3223/* Routing information base initialize. */
3224void
paula1ac18c2005-06-28 17:17:12 +00003225rib_init (void)
paul718e3742002-12-13 20:15:29 +00003226{
paul4d38fdb2005-04-28 17:35:14 +00003227 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00003228 /* VRF initialization. */
3229 vrf_init ();
3230}
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003231
3232/*
3233 * vrf_id_get_next
3234 *
3235 * Get the first vrf id that is greater than the given vrf id if any.
3236 *
3237 * Returns TRUE if a vrf id was found, FALSE otherwise.
3238 */
3239static inline int
3240vrf_id_get_next (uint32_t id, uint32_t *next_id_p)
3241{
3242 while (++id < vector_active (vrf_vector))
3243 {
3244 if (vrf_lookup (id))
3245 {
3246 *next_id_p = id;
3247 return 1;
3248 }
3249 }
3250
3251 return 0;
3252}
3253
3254/*
3255 * rib_tables_iter_next
3256 *
3257 * Returns the next table in the iteration.
3258 */
3259struct route_table *
3260rib_tables_iter_next (rib_tables_iter_t *iter)
3261{
3262 struct route_table *table;
3263
3264 /*
3265 * Array that helps us go over all AFI/SAFI combinations via one
3266 * index.
3267 */
3268 static struct {
3269 afi_t afi;
3270 safi_t safi;
3271 } afi_safis[] = {
3272 { AFI_IP, SAFI_UNICAST },
3273 { AFI_IP, SAFI_MULTICAST },
3274 { AFI_IP6, SAFI_UNICAST },
3275 { AFI_IP6, SAFI_MULTICAST },
3276 };
3277
3278 table = NULL;
3279
3280 switch (iter->state)
3281 {
3282
3283 case RIB_TABLES_ITER_S_INIT:
3284 iter->vrf_id = 0;
3285 iter->afi_safi_ix = -1;
3286
3287 /* Fall through */
3288
3289 case RIB_TABLES_ITER_S_ITERATING:
3290 iter->afi_safi_ix++;
3291 while (1)
3292 {
3293
3294 while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
3295 {
3296 table = vrf_table (afi_safis[iter->afi_safi_ix].afi,
3297 afi_safis[iter->afi_safi_ix].safi,
3298 iter->vrf_id);
3299 if (table)
3300 break;
3301
3302 iter->afi_safi_ix++;
3303 }
3304
3305 /*
3306 * Found another table in this vrf.
3307 */
3308 if (table)
3309 break;
3310
3311 /*
3312 * Done with all tables in the current vrf, go to the next
3313 * one.
3314 */
3315 if (!vrf_id_get_next (iter->vrf_id, &iter->vrf_id))
3316 break;
3317
3318 iter->afi_safi_ix = 0;
3319 }
3320
3321 break;
3322
3323 case RIB_TABLES_ITER_S_DONE:
3324 return NULL;
3325 }
3326
3327 if (table)
3328 iter->state = RIB_TABLES_ITER_S_ITERATING;
3329 else
3330 iter->state = RIB_TABLES_ITER_S_DONE;
3331
3332 return table;
3333}