blob: 245011ebfccbf9702863d39aa3923a1432794aad [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* Routing Information Base.
2 * Copyright (C) 1997, 98, 99, 2001 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "prefix.h"
25#include "table.h"
26#include "memory.h"
27#include "str.h"
28#include "command.h"
29#include "if.h"
30#include "log.h"
31#include "sockunion.h"
paul4d38fdb2005-04-28 17:35:14 +000032#include "linklist.h"
33#include "thread.h"
34#include "workqueue.h"
Paul Jakma7514fb72007-05-02 16:05:35 +000035#include "prefix.h"
36#include "routemap.h"
paul718e3742002-12-13 20:15:29 +000037
38#include "zebra/rib.h"
39#include "zebra/rt.h"
40#include "zebra/zserv.h"
41#include "zebra/redistribute.h"
42#include "zebra/debug.h"
Avneesh Sachdev5adc2522012-11-13 22:48:59 +000043#include "zebra/zebra_fpm.h"
paul718e3742002-12-13 20:15:29 +000044
45/* Default rtm_table for all clients */
paulb21b19c2003-06-15 01:28:29 +000046extern struct zebra_t zebrad;
paul718e3742002-12-13 20:15:29 +000047
Paul Jakma457eb9a2006-07-27 19:59:58 +000048/* Hold time for RIB process, should be very minimal.
49 * it is useful to able to set it otherwise for testing, hence exported
50 * as global here for test-rig code.
51 */
52int rib_process_hold_time = 10;
53
paul718e3742002-12-13 20:15:29 +000054/* Each route type's string and default distance value. */
Stephen Hemmingerd145bc02008-08-17 17:41:37 +010055static const struct
paul718e3742002-12-13 20:15:29 +000056{
57 int key;
58 int distance;
Paul Jakma57345092011-12-25 17:52:09 +010059} route_info[ZEBRA_ROUTE_MAX] =
paul718e3742002-12-13 20:15:29 +000060{
Paul Jakma57345092011-12-25 17:52:09 +010061 [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0},
62 [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0},
63 [ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0},
64 [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1},
65 [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120},
66 [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120},
67 [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110},
68 [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110},
69 [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115},
70 [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */},
71 [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 95},
David Lamparter7052f222009-08-27 00:28:28 +020072 /* no entry/default: 150 */
paul718e3742002-12-13 20:15:29 +000073};
David Lamparter6b0655a2014-06-04 06:53:35 +020074
paul718e3742002-12-13 20:15:29 +000075/* Vector for routing table. */
Stephen Hemmingerd145bc02008-08-17 17:41:37 +010076static vector vrf_vector;
paul718e3742002-12-13 20:15:29 +000077
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}
David Lamparter6b0655a2014-06-04 06:53:35 +0200179
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 {
Christian Franke48a53dc2013-07-05 15:35:38 +0000475 /* If the longest prefix match for the nexthop yields
476 * a blackhole, mark it as inactive. */
477 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE)
478 || CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT))
479 return 0;
480
paul718e3742002-12-13 20:15:29 +0000481 if (match->type == ZEBRA_ROUTE_CONNECT)
482 {
483 /* Directly point connected route. */
484 newhop = match->nexthop;
485 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
486 nexthop->ifindex = newhop->ifindex;
487
488 return 1;
489 }
490 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
491 {
Christian Frankefa713d92013-07-05 15:35:37 +0000492 resolved = 0;
paul718e3742002-12-13 20:15:29 +0000493 for (newhop = match->nexthop; newhop; newhop = newhop->next)
494 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
495 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
496 {
497 if (set)
498 {
499 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
Christian Frankefa713d92013-07-05 15:35:37 +0000500
501 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
502 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
Christian Frankec3e6b592013-07-05 15:35:40 +0000503 /* If the resolving route specifies a gateway, use it */
504 if (newhop->type == NEXTHOP_TYPE_IPV4
505 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX
506 || newhop->type == NEXTHOP_TYPE_IPV4_IFNAME)
507 {
508 resolved_hop->type = newhop->type;
509 resolved_hop->gate.ipv4 = newhop->gate.ipv4;
Christian Frankefa713d92013-07-05 15:35:37 +0000510
Christian Frankec3e6b592013-07-05 15:35:40 +0000511 if (newhop->ifindex)
512 {
513 resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
514 resolved_hop->ifindex = newhop->ifindex;
515 }
516 }
Christian Frankefa713d92013-07-05 15:35:37 +0000517
Christian Frankec3e6b592013-07-05 15:35:40 +0000518 /* If the resolving route is an interface route,
519 * it means the gateway we are looking up is connected
520 * to that interface. (The actual network is _not_ onlink).
521 * Therefore, the resolved route should have the original
522 * gateway as nexthop as it is directly connected.
523 *
524 * On Linux, we have to set the onlink netlink flag because
525 * otherwise, the kernel won't accept the route. */
paul718e3742002-12-13 20:15:29 +0000526 if (newhop->type == NEXTHOP_TYPE_IFINDEX
Christian Frankec3e6b592013-07-05 15:35:40 +0000527 || newhop->type == NEXTHOP_TYPE_IFNAME)
528 {
529 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
530 resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
531 resolved_hop->gate.ipv4 = nexthop->gate.ipv4;
532 resolved_hop->ifindex = newhop->ifindex;
533 }
Christian Frankefa713d92013-07-05 15:35:37 +0000534
535 _nexthop_add(&nexthop->resolved, resolved_hop);
paul718e3742002-12-13 20:15:29 +0000536 }
Christian Frankefa713d92013-07-05 15:35:37 +0000537 resolved = 1;
paul718e3742002-12-13 20:15:29 +0000538 }
Christian Frankefa713d92013-07-05 15:35:37 +0000539 return resolved;
paul718e3742002-12-13 20:15:29 +0000540 }
541 else
542 {
543 return 0;
544 }
545 }
546 }
547 return 0;
548}
549
550#ifdef HAVE_IPV6
551/* If force flag is not set, do not modify falgs at all for uninstall
552 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000553static int
paul718e3742002-12-13 20:15:29 +0000554nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
555 struct route_node *top)
556{
557 struct prefix_ipv6 p;
558 struct route_table *table;
559 struct route_node *rn;
560 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000561 int resolved;
paul718e3742002-12-13 20:15:29 +0000562 struct nexthop *newhop;
Christian Frankefa713d92013-07-05 15:35:37 +0000563 struct nexthop *resolved_hop;
paul718e3742002-12-13 20:15:29 +0000564
565 if (nexthop->type == NEXTHOP_TYPE_IPV6)
566 nexthop->ifindex = 0;
567
568 if (set)
Christian Frankefa713d92013-07-05 15:35:37 +0000569 {
570 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
571 nexthops_free(nexthop->resolved);
572 nexthop->resolved = NULL;
573 }
paul718e3742002-12-13 20:15:29 +0000574
575 /* Make lookup prefix. */
576 memset (&p, 0, sizeof (struct prefix_ipv6));
577 p.family = AF_INET6;
578 p.prefixlen = IPV6_MAX_PREFIXLEN;
579 p.prefix = nexthop->gate.ipv6;
580
581 /* Lookup table. */
582 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
583 if (! table)
584 return 0;
585
586 rn = route_node_match (table, (struct prefix *) &p);
587 while (rn)
588 {
589 route_unlock_node (rn);
590
David Warda50c1072009-12-03 15:34:39 +0300591 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000592 if (rn == top)
593 return 0;
594
595 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000596 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100597 {
598 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
599 continue;
600 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
601 break;
602 }
paul718e3742002-12-13 20:15:29 +0000603
604 /* If there is no selected route or matched route is EGP, go up
605 tree. */
606 if (! match
607 || match->type == ZEBRA_ROUTE_BGP)
608 {
609 do {
610 rn = rn->parent;
611 } while (rn && rn->info == NULL);
612 if (rn)
613 route_lock_node (rn);
614 }
615 else
616 {
Christian Franke48a53dc2013-07-05 15:35:38 +0000617 /* If the longest prefix match for the nexthop yields
618 * a blackhole, mark it as inactive. */
619 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE)
620 || CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT))
621 return 0;
622
paul718e3742002-12-13 20:15:29 +0000623 if (match->type == ZEBRA_ROUTE_CONNECT)
624 {
625 /* Directly point connected route. */
626 newhop = match->nexthop;
627
628 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
629 nexthop->ifindex = newhop->ifindex;
630
631 return 1;
632 }
633 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
634 {
Christian Frankefa713d92013-07-05 15:35:37 +0000635 resolved = 0;
paul718e3742002-12-13 20:15:29 +0000636 for (newhop = match->nexthop; newhop; newhop = newhop->next)
637 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
638 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
639 {
640 if (set)
641 {
642 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
Christian Frankefa713d92013-07-05 15:35:37 +0000643
644 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
645 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
Christian Frankec3e6b592013-07-05 15:35:40 +0000646 /* See nexthop_active_ipv4 for a description how the
647 * resolved nexthop is constructed. */
paul718e3742002-12-13 20:15:29 +0000648 if (newhop->type == NEXTHOP_TYPE_IPV6
649 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
650 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
Christian Frankec3e6b592013-07-05 15:35:40 +0000651 {
652 resolved_hop->type = newhop->type;
653 resolved_hop->gate.ipv6 = newhop->gate.ipv6;
654
655 if (newhop->ifindex)
656 {
657 resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
658 resolved_hop->ifindex = newhop->ifindex;
659 }
660 }
Christian Frankefa713d92013-07-05 15:35:37 +0000661
paul718e3742002-12-13 20:15:29 +0000662 if (newhop->type == NEXTHOP_TYPE_IFINDEX
Christian Frankec3e6b592013-07-05 15:35:40 +0000663 || newhop->type == NEXTHOP_TYPE_IFNAME)
664 {
665 resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
666 resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
667 resolved_hop->gate.ipv6 = nexthop->gate.ipv6;
668 resolved_hop->ifindex = newhop->ifindex;
669 }
Christian Frankefa713d92013-07-05 15:35:37 +0000670
671 _nexthop_add(&nexthop->resolved, resolved_hop);
paul718e3742002-12-13 20:15:29 +0000672 }
Christian Frankefa713d92013-07-05 15:35:37 +0000673 resolved = 1;
paul718e3742002-12-13 20:15:29 +0000674 }
Christian Frankefa713d92013-07-05 15:35:37 +0000675 return resolved;
paul718e3742002-12-13 20:15:29 +0000676 }
677 else
678 {
679 return 0;
680 }
681 }
682 }
683 return 0;
684}
685#endif /* HAVE_IPV6 */
686
687struct rib *
688rib_match_ipv4 (struct in_addr addr)
689{
690 struct prefix_ipv4 p;
691 struct route_table *table;
692 struct route_node *rn;
693 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000694 struct nexthop *newhop, *tnewhop;
695 int recursing;
paul718e3742002-12-13 20:15:29 +0000696
697 /* Lookup table. */
698 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
699 if (! table)
700 return 0;
701
702 memset (&p, 0, sizeof (struct prefix_ipv4));
703 p.family = AF_INET;
704 p.prefixlen = IPV4_MAX_PREFIXLEN;
705 p.prefix = addr;
706
707 rn = route_node_match (table, (struct prefix *) &p);
708
709 while (rn)
710 {
711 route_unlock_node (rn);
712
713 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000714 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100715 {
716 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
717 continue;
718 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
719 break;
720 }
paul718e3742002-12-13 20:15:29 +0000721
722 /* If there is no selected route or matched route is EGP, go up
723 tree. */
724 if (! match
725 || match->type == ZEBRA_ROUTE_BGP)
726 {
727 do {
728 rn = rn->parent;
729 } while (rn && rn->info == NULL);
730 if (rn)
731 route_lock_node (rn);
732 }
733 else
734 {
735 if (match->type == ZEBRA_ROUTE_CONNECT)
736 /* Directly point connected route. */
737 return match;
738 else
739 {
Christian Frankefa713d92013-07-05 15:35:37 +0000740 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
paul718e3742002-12-13 20:15:29 +0000741 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
742 return match;
743 return NULL;
744 }
745 }
746 }
747 return NULL;
748}
749
750struct rib *
751rib_lookup_ipv4 (struct prefix_ipv4 *p)
752{
753 struct route_table *table;
754 struct route_node *rn;
755 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000756 struct nexthop *nexthop, *tnexthop;
757 int recursing;
paul718e3742002-12-13 20:15:29 +0000758
759 /* Lookup table. */
760 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
761 if (! table)
762 return 0;
763
764 rn = route_node_lookup (table, (struct prefix *) p);
765
766 /* No route for this prefix. */
767 if (! rn)
768 return NULL;
769
770 /* Unlock node. */
771 route_unlock_node (rn);
772
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000773 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100774 {
775 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
776 continue;
777 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
778 break;
779 }
paul718e3742002-12-13 20:15:29 +0000780
781 if (! match || match->type == ZEBRA_ROUTE_BGP)
782 return NULL;
783
784 if (match->type == ZEBRA_ROUTE_CONNECT)
785 return match;
786
Christian Frankefa713d92013-07-05 15:35:37 +0000787 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +0000788 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
789 return match;
790
791 return NULL;
792}
793
Denis Ovsienkodc958242007-08-13 16:03:06 +0000794/*
795 * This clone function, unlike its original rib_lookup_ipv4(), checks
796 * if specified IPv4 route record (prefix/mask -> gate) exists in
797 * the whole RIB and has ZEBRA_FLAG_SELECTED set.
798 *
799 * Return values:
800 * -1: error
801 * 0: exact match found
802 * 1: a match was found with a different gate
803 * 2: connected route found
804 * 3: no matches found
805 */
806int
807rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
808{
809 struct route_table *table;
810 struct route_node *rn;
811 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000812 struct nexthop *nexthop, *tnexthop;
813 int recursing;
814 int nexthops_active;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000815
816 /* Lookup table. */
817 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
818 if (! table)
819 return ZEBRA_RIB_LOOKUP_ERROR;
820
821 /* Scan the RIB table for exactly matching RIB entry. */
822 rn = route_node_lookup (table, (struct prefix *) p);
823
824 /* No route for this prefix. */
825 if (! rn)
826 return ZEBRA_RIB_NOTFOUND;
827
828 /* Unlock node. */
829 route_unlock_node (rn);
830
831 /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000832 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100833 {
834 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
835 continue;
836 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
837 break;
838 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000839
840 /* None such found :( */
841 if (!match)
842 return ZEBRA_RIB_NOTFOUND;
843
844 if (match->type == ZEBRA_ROUTE_CONNECT)
845 return ZEBRA_RIB_FOUND_CONNECTED;
846
847 /* Ok, we have a cood candidate, let's check it's nexthop list... */
Christian Frankefa713d92013-07-05 15:35:37 +0000848 nexthops_active = 0;
849 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000850 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000851 {
Christian Frankefa713d92013-07-05 15:35:37 +0000852 nexthops_active = 1;
853 if (nexthop->gate.ipv4.s_addr == sockunion2ip (qgate))
854 return ZEBRA_RIB_FOUND_EXACT;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000855 if (IS_ZEBRA_DEBUG_RIB)
Christian Frankefa713d92013-07-05 15:35:37 +0000856 {
857 char gate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
858 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
859 inet_ntop (AF_INET, &sockunion2ip(qgate), qgate_buf, INET_ADDRSTRLEN);
860 zlog_debug ("%s: qgate == %s, %s == %s", __func__,
861 qgate_buf, recursing ? "rgate" : "gate", gate_buf);
862 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000863 }
Christian Frankefa713d92013-07-05 15:35:37 +0000864
865 if (nexthops_active)
866 return ZEBRA_RIB_FOUND_NOGATE;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000867
868 return ZEBRA_RIB_NOTFOUND;
869}
870
paul718e3742002-12-13 20:15:29 +0000871#ifdef HAVE_IPV6
872struct rib *
873rib_match_ipv6 (struct in6_addr *addr)
874{
875 struct prefix_ipv6 p;
876 struct route_table *table;
877 struct route_node *rn;
878 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000879 struct nexthop *newhop, *tnewhop;
880 int recursing;
paul718e3742002-12-13 20:15:29 +0000881
882 /* Lookup table. */
883 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
884 if (! table)
885 return 0;
886
887 memset (&p, 0, sizeof (struct prefix_ipv6));
888 p.family = AF_INET6;
889 p.prefixlen = IPV6_MAX_PREFIXLEN;
890 IPV6_ADDR_COPY (&p.prefix, addr);
891
892 rn = route_node_match (table, (struct prefix *) &p);
893
894 while (rn)
895 {
896 route_unlock_node (rn);
897
898 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000899 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100900 {
901 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
902 continue;
903 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
904 break;
905 }
paul718e3742002-12-13 20:15:29 +0000906
907 /* If there is no selected route or matched route is EGP, go up
908 tree. */
909 if (! match
910 || match->type == ZEBRA_ROUTE_BGP)
911 {
912 do {
913 rn = rn->parent;
914 } while (rn && rn->info == NULL);
915 if (rn)
916 route_lock_node (rn);
917 }
918 else
919 {
920 if (match->type == ZEBRA_ROUTE_CONNECT)
921 /* Directly point connected route. */
922 return match;
923 else
924 {
Christian Frankefa713d92013-07-05 15:35:37 +0000925 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
paul718e3742002-12-13 20:15:29 +0000926 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
927 return match;
928 return NULL;
929 }
930 }
931 }
932 return NULL;
933}
934#endif /* HAVE_IPV6 */
935
Paul Jakma7514fb72007-05-02 16:05:35 +0000936#define RIB_SYSTEM_ROUTE(R) \
937 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
938
Denis Ovsienkodc958242007-08-13 16:03:06 +0000939/* This function verifies reachability of one given nexthop, which can be
940 * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
941 * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
942 * nexthop->ifindex will be updated appropriately as well.
943 * An existing route map can turn (otherwise active) nexthop into inactive, but
944 * not vice versa.
945 *
946 * The return value is the final value of 'ACTIVE' flag.
947 */
948
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300949static unsigned
paul718e3742002-12-13 20:15:29 +0000950nexthop_active_check (struct route_node *rn, struct rib *rib,
951 struct nexthop *nexthop, int set)
952{
Christian Frankef3a17322013-07-05 15:35:41 +0000953 rib_table_info_t *info = rn->table->info;
paul718e3742002-12-13 20:15:29 +0000954 struct interface *ifp;
Paul Jakma7514fb72007-05-02 16:05:35 +0000955 route_map_result_t ret = RMAP_MATCH;
956 extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
957 struct route_map *rmap;
958 int family;
paul718e3742002-12-13 20:15:29 +0000959
Paul Jakma7514fb72007-05-02 16:05:35 +0000960 family = 0;
paul718e3742002-12-13 20:15:29 +0000961 switch (nexthop->type)
962 {
963 case NEXTHOP_TYPE_IFINDEX:
964 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000965 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000966 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
967 else
968 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
969 break;
paul718e3742002-12-13 20:15:29 +0000970 case NEXTHOP_TYPE_IPV6_IFNAME:
Paul Jakma7514fb72007-05-02 16:05:35 +0000971 family = AFI_IP6;
972 case NEXTHOP_TYPE_IFNAME:
paul718e3742002-12-13 20:15:29 +0000973 ifp = if_lookup_by_name (nexthop->ifname);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000974 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000975 {
976 if (set)
977 nexthop->ifindex = ifp->ifindex;
978 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
979 }
980 else
981 {
982 if (set)
983 nexthop->ifindex = 0;
984 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
985 }
986 break;
987 case NEXTHOP_TYPE_IPV4:
988 case NEXTHOP_TYPE_IPV4_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000989 family = AFI_IP;
paul718e3742002-12-13 20:15:29 +0000990 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
991 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
992 else
993 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
994 break;
995#ifdef HAVE_IPV6
996 case NEXTHOP_TYPE_IPV6:
Paul Jakma7514fb72007-05-02 16:05:35 +0000997 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000998 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
999 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1000 else
1001 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1002 break;
1003 case NEXTHOP_TYPE_IPV6_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +00001004 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +00001005 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
1006 {
1007 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +00001008 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001009 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1010 else
1011 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1012 }
1013 else
1014 {
1015 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
1016 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1017 else
1018 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1019 }
1020 break;
1021#endif /* HAVE_IPV6 */
paul595db7f2003-05-25 21:35:06 +00001022 case NEXTHOP_TYPE_BLACKHOLE:
1023 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1024 break;
paul718e3742002-12-13 20:15:29 +00001025 default:
1026 break;
1027 }
Paul Jakma7514fb72007-05-02 16:05:35 +00001028 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1029 return 0;
1030
Christian Frankef3a17322013-07-05 15:35:41 +00001031 /* XXX: What exactly do those checks do? Do we support
1032 * e.g. IPv4 routes with IPv6 nexthops or vice versa? */
Paul Jakma7514fb72007-05-02 16:05:35 +00001033 if (RIB_SYSTEM_ROUTE(rib) ||
1034 (family == AFI_IP && rn->p.family != AF_INET) ||
1035 (family == AFI_IP6 && rn->p.family != AF_INET6))
1036 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1037
Christian Frankef3a17322013-07-05 15:35:41 +00001038 /* The original code didn't determine the family correctly
1039 * e.g. for NEXTHOP_TYPE_IFINDEX. Retrieve the correct afi
1040 * from the rib_table_info in those cases.
1041 * Possibly it may be better to use only the rib_table_info
1042 * in every case.
1043 */
1044 if (!family)
1045 family = info->afi;
1046
Paul Jakma7514fb72007-05-02 16:05:35 +00001047 rmap = 0;
1048 if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
1049 proto_rm[family][rib->type])
1050 rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
1051 if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
1052 rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
1053 if (rmap) {
1054 ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, nexthop);
1055 }
1056
1057 if (ret == RMAP_DENYMATCH)
1058 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
paul718e3742002-12-13 20:15:29 +00001059 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1060}
1061
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001062/* Iterate over all nexthops of the given RIB entry and refresh their
1063 * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
1064 * nexthop is found to toggle the ACTIVE flag, the whole rib structure
1065 * is flagged with ZEBRA_FLAG_CHANGED. The 4th 'set' argument is
1066 * transparently passed to nexthop_active_check().
1067 *
1068 * Return value is the new number of active nexthops.
1069 */
1070
paula1ac18c2005-06-28 17:17:12 +00001071static int
paul718e3742002-12-13 20:15:29 +00001072nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
1073{
1074 struct nexthop *nexthop;
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001075 unsigned int prev_active, prev_index, new_active;
paul718e3742002-12-13 20:15:29 +00001076
1077 rib->nexthop_active_num = 0;
1078 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1079
1080 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001081 {
1082 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001083 prev_index = nexthop->ifindex;
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001084 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
1085 rib->nexthop_active_num++;
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001086 if (prev_active != new_active ||
1087 prev_index != nexthop->ifindex)
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001088 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1089 }
paul718e3742002-12-13 20:15:29 +00001090 return rib->nexthop_active_num;
1091}
paul6baeb982003-10-28 03:47:15 +00001092
David Lamparter6b0655a2014-06-04 06:53:35 +02001093
paul718e3742002-12-13 20:15:29 +00001094
paula1ac18c2005-06-28 17:17:12 +00001095static void
paul718e3742002-12-13 20:15:29 +00001096rib_install_kernel (struct route_node *rn, struct rib *rib)
1097{
1098 int ret = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001099 struct nexthop *nexthop, *tnexthop;
1100 int recursing;
paul718e3742002-12-13 20:15:29 +00001101
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001102 /*
1103 * Make sure we update the FPM any time we send new information to
1104 * the kernel.
1105 */
1106 zfpm_trigger_update (rn, "installing in kernel");
paul718e3742002-12-13 20:15:29 +00001107 switch (PREFIX_FAMILY (&rn->p))
1108 {
1109 case AF_INET:
1110 ret = kernel_add_ipv4 (&rn->p, rib);
1111 break;
1112#ifdef HAVE_IPV6
1113 case AF_INET6:
1114 ret = kernel_add_ipv6 (&rn->p, rib);
1115 break;
1116#endif /* HAVE_IPV6 */
1117 }
1118
Denis Ovsienkodc958242007-08-13 16:03:06 +00001119 /* This condition is never met, if we are using rt_socket.c */
paul718e3742002-12-13 20:15:29 +00001120 if (ret < 0)
1121 {
Christian Frankefa713d92013-07-05 15:35:37 +00001122 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +00001123 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1124 }
1125}
1126
1127/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001128static int
paul718e3742002-12-13 20:15:29 +00001129rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
1130{
1131 int ret = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001132 struct nexthop *nexthop, *tnexthop;
1133 int recursing;
paul718e3742002-12-13 20:15:29 +00001134
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001135 /*
1136 * Make sure we update the FPM any time we send new information to
1137 * the kernel.
1138 */
1139 zfpm_trigger_update (rn, "uninstalling from kernel");
1140
paul718e3742002-12-13 20:15:29 +00001141 switch (PREFIX_FAMILY (&rn->p))
1142 {
1143 case AF_INET:
1144 ret = kernel_delete_ipv4 (&rn->p, rib);
1145 break;
1146#ifdef HAVE_IPV6
1147 case AF_INET6:
1148 ret = kernel_delete_ipv6 (&rn->p, rib);
1149 break;
1150#endif /* HAVE_IPV6 */
1151 }
1152
Christian Frankefa713d92013-07-05 15:35:37 +00001153 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +00001154 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1155
1156 return ret;
1157}
1158
1159/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001160static void
paul718e3742002-12-13 20:15:29 +00001161rib_uninstall (struct route_node *rn, struct rib *rib)
1162{
1163 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1164 {
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001165 zfpm_trigger_update (rn, "rib_uninstall");
1166
paul718e3742002-12-13 20:15:29 +00001167 redistribute_delete (&rn->p, rib);
1168 if (! RIB_SYSTEM_ROUTE (rib))
1169 rib_uninstall_kernel (rn, rib);
1170 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
1171 }
1172}
1173
Paul Jakma6d691122006-07-27 21:49:00 +00001174static void rib_unlink (struct route_node *, struct rib *);
1175
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001176/*
1177 * rib_can_delete_dest
1178 *
1179 * Returns TRUE if the given dest can be deleted from the table.
1180 */
1181static int
1182rib_can_delete_dest (rib_dest_t *dest)
1183{
1184 if (dest->routes)
1185 {
1186 return 0;
1187 }
1188
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001189 /*
1190 * Don't delete the dest if we have to update the FPM about this
1191 * prefix.
1192 */
1193 if (CHECK_FLAG (dest->flags, RIB_DEST_UPDATE_FPM) ||
1194 CHECK_FLAG (dest->flags, RIB_DEST_SENT_TO_FPM))
1195 return 0;
1196
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001197 return 1;
1198}
1199
1200/*
1201 * rib_gc_dest
1202 *
1203 * Garbage collect the rib dest corresponding to the given route node
1204 * if appropriate.
1205 *
1206 * Returns TRUE if the dest was deleted, FALSE otherwise.
1207 */
1208int
1209rib_gc_dest (struct route_node *rn)
1210{
1211 rib_dest_t *dest;
1212 char buf[INET6_ADDRSTRLEN];
1213
1214 dest = rib_dest_from_rnode (rn);
1215 if (!dest)
1216 return 0;
1217
1218 if (!rib_can_delete_dest (dest))
1219 return 0;
1220
1221 if (IS_ZEBRA_DEBUG_RIB)
1222 {
1223 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, sizeof (buf));
1224 zlog_debug ("%s: %s/%d: removing dest from table", __func__,
1225 buf, rn->p.prefixlen);
1226 }
1227
1228 dest->rnode = NULL;
1229 XFREE (MTYPE_RIB_DEST, dest);
1230 rn->info = NULL;
1231
1232 /*
1233 * Release the one reference that we keep on the route node.
1234 */
1235 route_unlock_node (rn);
1236 return 1;
1237}
1238
paul718e3742002-12-13 20:15:29 +00001239/* Core function for processing routing information base. */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001240static void
1241rib_process (struct route_node *rn)
paul718e3742002-12-13 20:15:29 +00001242{
1243 struct rib *rib;
1244 struct rib *next;
1245 struct rib *fib = NULL;
1246 struct rib *select = NULL;
Paul Jakma6d691122006-07-27 21:49:00 +00001247 struct rib *del = NULL;
pauld753e9e2003-01-22 19:45:50 +00001248 int installed = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001249 struct nexthop *nexthop = NULL, *tnexthop;
1250 int recursing;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001251 char buf[INET6_ADDRSTRLEN];
Balaji95116332014-10-23 15:25:25 +00001252 rib_table_info_t *info;
1253
paul4d38fdb2005-04-28 17:35:14 +00001254 assert (rn);
Balaji95116332014-10-23 15:25:25 +00001255
1256 info = rn->table->info;
1257
Paul Jakma93bdada2007-08-06 19:25:11 +00001258 if (IS_ZEBRA_DEBUG_RIB || IS_ZEBRA_DEBUG_RIB_Q)
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001259 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001260
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001261 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00001262 {
paul718e3742002-12-13 20:15:29 +00001263 /* Currently installed rib. */
1264 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Paul Jakma6d691122006-07-27 21:49:00 +00001265 {
1266 assert (fib == NULL);
1267 fib = rib;
1268 }
1269
1270 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1271 * which we need to do do further work with below.
1272 */
1273 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1274 {
1275 if (rib != fib)
1276 {
1277 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001278 zlog_debug ("%s: %s/%d: rn %p, removing rib %p", __func__,
1279 buf, rn->p.prefixlen, rn, rib);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001280 rib_unlink (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001281 }
1282 else
1283 del = rib;
1284
1285 continue;
1286 }
paul4d38fdb2005-04-28 17:35:14 +00001287
paul718e3742002-12-13 20:15:29 +00001288 /* Skip unreachable nexthop. */
1289 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +00001290 continue;
paul718e3742002-12-13 20:15:29 +00001291
Balaji95116332014-10-23 15:25:25 +00001292 if (info->safi == SAFI_MULTICAST)
1293 continue;
1294
paul718e3742002-12-13 20:15:29 +00001295 /* Infinit distance. */
1296 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +00001297 continue;
paul718e3742002-12-13 20:15:29 +00001298
paulaf887b52006-01-18 14:52:52 +00001299 /* Newly selected rib, the common case. */
1300 if (!select)
1301 {
1302 select = rib;
1303 continue;
1304 }
1305
1306 /* filter route selection in following order:
paulaf887b52006-01-18 14:52:52 +00001307 * - connected beats other types
paula8d9c1f2006-01-25 06:31:04 +00001308 * - lower distance beats higher
paulaf887b52006-01-18 14:52:52 +00001309 * - lower metric beats higher for equal distance
1310 * - last, hence oldest, route wins tie break.
1311 */
paula1038a12006-01-30 14:08:51 +00001312
1313 /* Connected routes. Pick the last connected
1314 * route of the set of lowest metric connected routes.
1315 */
paula8d9c1f2006-01-25 06:31:04 +00001316 if (rib->type == ZEBRA_ROUTE_CONNECT)
1317 {
paula1038a12006-01-30 14:08:51 +00001318 if (select->type != ZEBRA_ROUTE_CONNECT
paula8d9c1f2006-01-25 06:31:04 +00001319 || rib->metric <= select->metric)
paula1038a12006-01-30 14:08:51 +00001320 select = rib;
1321 continue;
paula8d9c1f2006-01-25 06:31:04 +00001322 }
1323 else if (select->type == ZEBRA_ROUTE_CONNECT)
1324 continue;
1325
1326 /* higher distance loses */
1327 if (rib->distance > select->distance)
1328 continue;
1329
1330 /* lower wins */
1331 if (rib->distance < select->distance)
1332 {
paulaf887b52006-01-18 14:52:52 +00001333 select = rib;
paula8d9c1f2006-01-25 06:31:04 +00001334 continue;
1335 }
1336
1337 /* metric tie-breaks equal distance */
1338 if (rib->metric <= select->metric)
1339 select = rib;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001340 } /* RNODE_FOREACH_RIB_SAFE */
Denis Ovsienkodc958242007-08-13 16:03:06 +00001341
1342 /* After the cycle is finished, the following pointers will be set:
1343 * select --- the winner RIB entry, if any was found, otherwise NULL
1344 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1345 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1346 * rib --- NULL
1347 */
1348
1349 /* Same RIB entry is selected. Update FIB and finish. */
paul718e3742002-12-13 20:15:29 +00001350 if (select && select == fib)
1351 {
Paul Jakma6d691122006-07-27 21:49:00 +00001352 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001353 zlog_debug ("%s: %s/%d: Updating existing route, select %p, fib %p",
1354 __func__, buf, rn->p.prefixlen, select, fib);
paul718e3742002-12-13 20:15:29 +00001355 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +00001356 {
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001357 zfpm_trigger_update (rn, "updating existing route");
1358
paul4d38fdb2005-04-28 17:35:14 +00001359 redistribute_delete (&rn->p, select);
1360 if (! RIB_SYSTEM_ROUTE (select))
1361 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001362
paul4d38fdb2005-04-28 17:35:14 +00001363 /* Set real nexthop. */
1364 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +00001365
paul4d38fdb2005-04-28 17:35:14 +00001366 if (! RIB_SYSTEM_ROUTE (select))
1367 rib_install_kernel (rn, select);
1368 redistribute_add (&rn->p, select);
1369 }
pauld753e9e2003-01-22 19:45:50 +00001370 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001371 {
1372 /* Housekeeping code to deal with
1373 race conditions in kernel with linux
1374 netlink reporting interface up before IPv4 or IPv6 protocol
1375 is ready to add routes.
1376 This makes sure the routes are IN the kernel.
1377 */
pauld753e9e2003-01-22 19:45:50 +00001378
Christian Frankefa713d92013-07-05 15:35:37 +00001379 for (ALL_NEXTHOPS_RO(select->nexthop, nexthop, tnexthop, recursing))
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001380 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
paul4d38fdb2005-04-28 17:35:14 +00001381 {
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001382 installed = 1;
1383 break;
paul4d38fdb2005-04-28 17:35:14 +00001384 }
1385 if (! installed)
1386 rib_install_kernel (rn, select);
1387 }
Paul Jakma6d691122006-07-27 21:49:00 +00001388 goto end;
paul718e3742002-12-13 20:15:29 +00001389 }
1390
Denis Ovsienkodc958242007-08-13 16:03:06 +00001391 /* At this point we either haven't found the best RIB entry or it is
1392 * different from what we currently intend to flag with SELECTED. In both
1393 * cases, if a RIB block is present in FIB, it should be withdrawn.
1394 */
paul718e3742002-12-13 20:15:29 +00001395 if (fib)
1396 {
Paul Jakma6d691122006-07-27 21:49:00 +00001397 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001398 zlog_debug ("%s: %s/%d: Removing existing route, fib %p", __func__,
1399 buf, rn->p.prefixlen, fib);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001400
1401 zfpm_trigger_update (rn, "removing existing route");
1402
paul718e3742002-12-13 20:15:29 +00001403 redistribute_delete (&rn->p, fib);
1404 if (! RIB_SYSTEM_ROUTE (fib))
1405 rib_uninstall_kernel (rn, fib);
1406 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1407
1408 /* Set real nexthop. */
1409 nexthop_active_update (rn, fib, 1);
1410 }
1411
Denis Ovsienkodc958242007-08-13 16:03:06 +00001412 /* Regardless of some RIB entry being SELECTED or not before, now we can
1413 * tell, that if a new winner exists, FIB is still not updated with this
1414 * data, but ready to be.
1415 */
paul718e3742002-12-13 20:15:29 +00001416 if (select)
1417 {
Paul Jakma6d691122006-07-27 21:49:00 +00001418 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001419 zlog_debug ("%s: %s/%d: Adding route, select %p", __func__, buf,
1420 rn->p.prefixlen, select);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001421
1422 zfpm_trigger_update (rn, "new route selected");
1423
paul718e3742002-12-13 20:15:29 +00001424 /* Set real nexthop. */
1425 nexthop_active_update (rn, select, 1);
1426
1427 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001428 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001429 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1430 redistribute_add (&rn->p, select);
1431 }
paul4d38fdb2005-04-28 17:35:14 +00001432
Paul Jakma6d691122006-07-27 21:49:00 +00001433 /* FIB route was removed, should be deleted */
1434 if (del)
1435 {
1436 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001437 zlog_debug ("%s: %s/%d: Deleting fib %p, rn %p", __func__, buf,
1438 rn->p.prefixlen, del, rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001439 rib_unlink (rn, del);
1440 }
paul4d38fdb2005-04-28 17:35:14 +00001441
Paul Jakma6d691122006-07-27 21:49:00 +00001442end:
1443 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma93bdada2007-08-06 19:25:11 +00001444 zlog_debug ("%s: %s/%d: rn %p dequeued", __func__, buf, rn->p.prefixlen, rn);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001445
1446 /*
1447 * Check if the dest can be deleted now.
1448 */
1449 rib_gc_dest (rn);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001450}
1451
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001452/* Take a list of route_node structs and return 1, if there was a record
1453 * picked from it and processed by rib_process(). Don't process more,
1454 * than one RN record; operate only in the specified sub-queue.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001455 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001456static unsigned int
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001457process_subq (struct list * subq, u_char qindex)
1458{
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001459 struct listnode *lnode = listhead (subq);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001460 struct route_node *rnode;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001461
1462 if (!lnode)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001463 return 0;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001464
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001465 rnode = listgetdata (lnode);
1466 rib_process (rnode);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001467
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001468 if (rnode->info)
1469 UNSET_FLAG (rib_dest_from_rnode (rnode)->flags, RIB_ROUTE_QUEUED (qindex));
1470
Chris Caputo67b94672009-07-18 04:02:26 +00001471#if 0
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001472 else
1473 {
1474 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1475 __func__, rnode, rnode->lock);
1476 zlog_backtrace(LOG_DEBUG);
1477 }
Chris Caputo67b94672009-07-18 04:02:26 +00001478#endif
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001479 route_unlock_node (rnode);
1480 list_delete_node (subq, lnode);
1481 return 1;
1482}
1483
1484/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1485 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1486 * is pointed to the meta queue structure.
1487 */
1488static wq_item_status
1489meta_queue_process (struct work_queue *dummy, void *data)
1490{
1491 struct meta_queue * mq = data;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001492 unsigned i;
1493
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001494 for (i = 0; i < MQ_SIZE; i++)
1495 if (process_subq (mq->subq[i], i))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001496 {
1497 mq->size--;
1498 break;
1499 }
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001500 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1501}
1502
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001503/*
1504 * Map from rib types to queue type (priority) in meta queue
1505 */
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001506static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
1507 [ZEBRA_ROUTE_SYSTEM] = 4,
1508 [ZEBRA_ROUTE_KERNEL] = 0,
1509 [ZEBRA_ROUTE_CONNECT] = 0,
1510 [ZEBRA_ROUTE_STATIC] = 1,
1511 [ZEBRA_ROUTE_RIP] = 2,
1512 [ZEBRA_ROUTE_RIPNG] = 2,
1513 [ZEBRA_ROUTE_OSPF] = 2,
1514 [ZEBRA_ROUTE_OSPF6] = 2,
1515 [ZEBRA_ROUTE_ISIS] = 2,
1516 [ZEBRA_ROUTE_BGP] = 3,
1517 [ZEBRA_ROUTE_HSLS] = 4,
Paul Jakma57345092011-12-25 17:52:09 +01001518 [ZEBRA_ROUTE_BABEL] = 2,
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001519};
1520
1521/* Look into the RN and queue it into one or more priority queues,
1522 * increasing the size for each data push done.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001523 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001524static void
1525rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001526{
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001527 struct rib *rib;
1528 char buf[INET6_ADDRSTRLEN];
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001529
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001530 if (IS_ZEBRA_DEBUG_RIB_Q)
1531 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001532
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001533 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001534 {
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001535 u_char qindex = meta_queue_map[rib->type];
1536
1537 /* Invariant: at this point we always have rn->info set. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001538 if (CHECK_FLAG (rib_dest_from_rnode (rn)->flags,
1539 RIB_ROUTE_QUEUED (qindex)))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001540 {
1541 if (IS_ZEBRA_DEBUG_RIB_Q)
1542 zlog_debug ("%s: %s/%d: rn %p is already queued in sub-queue %u",
1543 __func__, buf, rn->p.prefixlen, rn, qindex);
1544 continue;
1545 }
1546
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001547 SET_FLAG (rib_dest_from_rnode (rn)->flags, RIB_ROUTE_QUEUED (qindex));
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001548 listnode_add (mq->subq[qindex], rn);
1549 route_lock_node (rn);
1550 mq->size++;
1551
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001552 if (IS_ZEBRA_DEBUG_RIB_Q)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001553 zlog_debug ("%s: %s/%d: queued rn %p into sub-queue %u",
1554 __func__, buf, rn->p.prefixlen, rn, qindex);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001555 }
paul4d38fdb2005-04-28 17:35:14 +00001556}
1557
Paul Jakma6d691122006-07-27 21:49:00 +00001558/* Add route_node to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001559static void
Paul Jakma6d691122006-07-27 21:49:00 +00001560rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
paul4d38fdb2005-04-28 17:35:14 +00001561{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001562 char buf[INET_ADDRSTRLEN];
1563 assert (zebra && rn);
paul4d38fdb2005-04-28 17:35:14 +00001564
Paul Jakma93bdada2007-08-06 19:25:11 +00001565 if (IS_ZEBRA_DEBUG_RIB_Q)
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001566 inet_ntop (AF_INET, &rn->p.u.prefix, buf, INET_ADDRSTRLEN);
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001567
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001568 /* Pointless to queue a route_node with no RIB entries to add or remove */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001569 if (!rnode_to_ribs (rn))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001570 {
1571 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1572 __func__, rn, rn->lock);
1573 zlog_backtrace(LOG_DEBUG);
1574 return;
1575 }
1576
1577 if (IS_ZEBRA_DEBUG_RIB_Q)
1578 zlog_info ("%s: %s/%d: work queue added", __func__, buf, rn->p.prefixlen);
1579
1580 assert (zebra);
1581
1582 if (zebra->ribq == NULL)
1583 {
1584 zlog_err ("%s: work_queue does not exist!", __func__);
1585 return;
Paul Jakma6d691122006-07-27 21:49:00 +00001586 }
paul4d38fdb2005-04-28 17:35:14 +00001587
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001588 /*
1589 * The RIB queue should normally be either empty or holding the only
1590 * work_queue_item element. In the latter case this element would
1591 * hold a pointer to the meta queue structure, which must be used to
1592 * actually queue the route nodes to process. So create the MQ
1593 * holder, if necessary, then push the work into it in any case.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001594 * This semantics was introduced after 0.99.9 release.
1595 */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001596 if (!zebra->ribq->items->count)
1597 work_queue_add (zebra->ribq, zebra->mq);
1598
1599 rib_meta_queue_add (zebra->mq, rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001600
1601 if (IS_ZEBRA_DEBUG_RIB_Q)
1602 zlog_debug ("%s: %s/%d: rn %p queued", __func__, buf, rn->p.prefixlen, rn);
1603
1604 return;
paul4d38fdb2005-04-28 17:35:14 +00001605}
1606
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001607/* Create new meta queue.
1608 A destructor function doesn't seem to be necessary here.
1609 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001610static struct meta_queue *
1611meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001612{
1613 struct meta_queue *new;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001614 unsigned i;
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001615
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001616 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1617 assert(new);
1618
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001619 for (i = 0; i < MQ_SIZE; i++)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001620 {
1621 new->subq[i] = list_new ();
1622 assert(new->subq[i]);
1623 }
1624
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001625 return new;
1626}
1627
paul4d38fdb2005-04-28 17:35:14 +00001628/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001629static void
paul4d38fdb2005-04-28 17:35:14 +00001630rib_queue_init (struct zebra_t *zebra)
1631{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001632 assert (zebra);
1633
paul4d38fdb2005-04-28 17:35:14 +00001634 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001635 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001636 {
Paul Jakma6d691122006-07-27 21:49:00 +00001637 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001638 return;
1639 }
1640
1641 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001642 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001643 zebra->ribq->spec.errorfunc = NULL;
paul4d38fdb2005-04-28 17:35:14 +00001644 /* XXX: TODO: These should be runtime configurable via vty */
1645 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001646 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001647
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001648 if (!(zebra->mq = meta_queue_new ()))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001649 {
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001650 zlog_err ("%s: could not initialise meta queue!", __func__);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001651 return;
1652 }
1653 return;
paul718e3742002-12-13 20:15:29 +00001654}
1655
Paul Jakma6d691122006-07-27 21:49:00 +00001656/* RIB updates are processed via a queue of pointers to route_nodes.
1657 *
1658 * The queue length is bounded by the maximal size of the routing table,
1659 * as a route_node will not be requeued, if already queued.
1660 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001661 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1662 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1663 * and then submit route_node to queue for best-path selection later.
1664 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001665 *
1666 * Deleted RIBs are reaped during best-path selection.
1667 *
1668 * rib_addnode
1669 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001670 * |-------->| | best RIB, if required
1671 * | |
1672 * static_install->|->rib_addqueue...... -> rib_process
1673 * | |
1674 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001675 * |-> set RIB_ENTRY_REMOVE |
1676 * rib_delnode (RIB freed)
1677 *
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001678 * The 'info' pointer of a route_node points to a rib_dest_t
1679 * ('dest'). Queueing state for a route_node is kept on the dest. The
1680 * dest is created on-demand by rib_link() and is kept around at least
1681 * as long as there are ribs hanging off it (@see rib_gc_dest()).
Paul Jakma6d691122006-07-27 21:49:00 +00001682 *
1683 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1684 *
1685 * - route_nodes: refcounted by:
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001686 * - dest attached to route_node:
1687 * - managed by: rib_link/rib_gc_dest
Paul Jakma6d691122006-07-27 21:49:00 +00001688 * - route_node processing queue
1689 * - managed by: rib_addqueue, rib_process.
1690 *
1691 */
1692
paul718e3742002-12-13 20:15:29 +00001693/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001694static void
Paul Jakma6d691122006-07-27 21:49:00 +00001695rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001696{
1697 struct rib *head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001698 rib_dest_t *dest;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001699 char buf[INET6_ADDRSTRLEN];
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001700
paul4d38fdb2005-04-28 17:35:14 +00001701 assert (rib && rn);
1702
Paul Jakma6d691122006-07-27 21:49:00 +00001703 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001704 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001705 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001706 zlog_debug ("%s: %s/%d: rn %p, rib %p", __func__,
1707 buf, rn->p.prefixlen, rn, rib);
1708 }
Paul Jakma6d691122006-07-27 21:49:00 +00001709
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001710 dest = rib_dest_from_rnode (rn);
1711 if (!dest)
Paul Jakma6d691122006-07-27 21:49:00 +00001712 {
1713 if (IS_ZEBRA_DEBUG_RIB)
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001714 {
1715 zlog_debug ("%s: %s/%d: adding dest to table", __func__,
1716 buf, rn->p.prefixlen);
1717 }
1718
1719 dest = XCALLOC (MTYPE_RIB_DEST, sizeof (rib_dest_t));
1720 route_lock_node (rn); /* rn route table reference */
1721 rn->info = dest;
1722 dest->rnode = rn;
1723 }
1724
1725 head = dest->routes;
1726 if (head)
1727 {
Paul Jakma6d691122006-07-27 21:49:00 +00001728 head->prev = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001729 }
paul718e3742002-12-13 20:15:29 +00001730 rib->next = head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001731 dest->routes = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001732 rib_queue_add (&zebrad, rn);
1733}
1734
1735static void
1736rib_addnode (struct route_node *rn, struct rib *rib)
1737{
1738 /* RIB node has been un-removed before route-node is processed.
1739 * route_node must hence already be on the queue for processing..
1740 */
1741 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1742 {
1743 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001744 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001745 char buf[INET6_ADDRSTRLEN];
1746 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001747 zlog_debug ("%s: %s/%d: rn %p, un-removed rib %p",
1748 __func__, buf, rn->p.prefixlen, rn, rib);
1749 }
Paul Jakma6d691122006-07-27 21:49:00 +00001750 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1751 return;
1752 }
1753 rib_link (rn, rib);
1754}
1755
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001756/*
1757 * rib_unlink
1758 *
1759 * Detach a rib structure from a route_node.
1760 *
1761 * Note that a call to rib_unlink() should be followed by a call to
1762 * rib_gc_dest() at some point. This allows a rib_dest_t that is no
1763 * longer required to be deleted.
1764 */
Paul Jakma6d691122006-07-27 21:49:00 +00001765static void
1766rib_unlink (struct route_node *rn, struct rib *rib)
1767{
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001768 char buf[INET6_ADDRSTRLEN];
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001769 rib_dest_t *dest;
Paul Jakma6d691122006-07-27 21:49:00 +00001770
1771 assert (rn && rib);
1772
1773 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001774 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001775 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001776 zlog_debug ("%s: %s/%d: rn %p, rib %p",
1777 __func__, buf, rn->p.prefixlen, rn, rib);
1778 }
Paul Jakma6d691122006-07-27 21:49:00 +00001779
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001780 dest = rib_dest_from_rnode (rn);
1781
Paul Jakma6d691122006-07-27 21:49:00 +00001782 if (rib->next)
1783 rib->next->prev = rib->prev;
1784
1785 if (rib->prev)
1786 rib->prev->next = rib->next;
1787 else
1788 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001789 dest->routes = rib->next;
Paul Jakma6d691122006-07-27 21:49:00 +00001790 }
1791
1792 /* free RIB and nexthops */
Christian Frankefa713d92013-07-05 15:35:37 +00001793 nexthops_free(rib->nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00001794 XFREE (MTYPE_RIB, rib);
1795
paul718e3742002-12-13 20:15:29 +00001796}
1797
paula1ac18c2005-06-28 17:17:12 +00001798static void
paul718e3742002-12-13 20:15:29 +00001799rib_delnode (struct route_node *rn, struct rib *rib)
1800{
Paul Jakma6d691122006-07-27 21:49:00 +00001801 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001802 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001803 char buf[INET6_ADDRSTRLEN];
1804 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001805 zlog_debug ("%s: %s/%d: rn %p, rib %p, removing", __func__,
1806 buf, rn->p.prefixlen, rn, rib);
1807 }
Paul Jakma6d691122006-07-27 21:49:00 +00001808 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1809 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001810}
1811
1812int
1813rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001814 struct in_addr *gate, struct in_addr *src,
1815 unsigned int ifindex, u_int32_t vrf_id,
G.Balajicddf3912011-11-26 21:59:32 +04001816 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001817{
1818 struct rib *rib;
1819 struct rib *same = NULL;
1820 struct route_table *table;
1821 struct route_node *rn;
1822 struct nexthop *nexthop;
1823
1824 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04001825 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00001826 if (! table)
1827 return 0;
1828
1829 /* Make it sure prefixlen is applied to the prefix. */
1830 apply_mask_ipv4 (p);
1831
1832 /* Set default distance by route type. */
1833 if (distance == 0)
1834 {
Balaji.G837d16c2012-09-26 14:09:10 +05301835 if ((unsigned)type >= array_size(route_info))
David Lamparter7052f222009-08-27 00:28:28 +02001836 distance = 150;
1837 else
1838 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00001839
1840 /* iBGP distance is 200. */
1841 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1842 distance = 200;
1843 }
1844
1845 /* Lookup route node.*/
1846 rn = route_node_get (table, (struct prefix *) p);
1847
1848 /* If same type of route are installed, treat it as a implicit
1849 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001850 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00001851 {
Paul Jakma6d691122006-07-27 21:49:00 +00001852 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1853 continue;
1854
hassoebf1ead2005-09-21 14:58:20 +00001855 if (rib->type != type)
1856 continue;
1857 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001858 {
1859 same = rib;
1860 break;
1861 }
hassoebf1ead2005-09-21 14:58:20 +00001862 /* Duplicate connected route comes in. */
1863 else if ((nexthop = rib->nexthop) &&
1864 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001865 nexthop->ifindex == ifindex &&
1866 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001867 {
1868 rib->refcnt++;
1869 return 0 ;
1870 }
paul718e3742002-12-13 20:15:29 +00001871 }
1872
1873 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001874 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001875 rib->type = type;
1876 rib->distance = distance;
1877 rib->flags = flags;
1878 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001879 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001880 rib->nexthop_num = 0;
1881 rib->uptime = time (NULL);
1882
1883 /* Nexthop settings. */
1884 if (gate)
1885 {
1886 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001887 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001888 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001889 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001890 }
1891 else
1892 nexthop_ifindex_add (rib, ifindex);
1893
1894 /* If this route is kernel route, set FIB flag to the route. */
1895 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1896 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1897 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1898
1899 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001900 if (IS_ZEBRA_DEBUG_RIB)
1901 zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
paul718e3742002-12-13 20:15:29 +00001902 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001903
paul718e3742002-12-13 20:15:29 +00001904 /* Free implicit route.*/
1905 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001906 {
1907 if (IS_ZEBRA_DEBUG_RIB)
1908 zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001909 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001910 }
paul4d38fdb2005-04-28 17:35:14 +00001911
1912 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001913 return 0;
1914}
1915
Denis Ovsienkodc958242007-08-13 16:03:06 +00001916/* This function dumps the contents of a given RIB entry into
1917 * standard debug log. Calling function name and IP prefix in
1918 * question are passed as 1st and 2nd arguments.
1919 */
1920
David Lamparterf7bf4152013-10-22 17:10:21 +00001921void _rib_dump (const char * func,
1922 union prefix46constptr pp, const struct rib * rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001923{
David Lamparterf7bf4152013-10-22 17:10:21 +00001924 const struct prefix *p = pp.p;
Vincent Bernatfed643f2012-10-23 16:00:42 +00001925 char straddr[INET6_ADDRSTRLEN];
Christian Frankefa713d92013-07-05 15:35:37 +00001926 struct nexthop *nexthop, *tnexthop;
1927 int recursing;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001928
Vincent Bernatfed643f2012-10-23 16:00:42 +00001929 inet_ntop (p->family, &p->u.prefix, straddr, INET6_ADDRSTRLEN);
Christian Frankefa713d92013-07-05 15:35:37 +00001930 zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr, p->prefixlen);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001931 zlog_debug
1932 (
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001933 "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
Denis Ovsienkodc958242007-08-13 16:03:06 +00001934 func,
1935 rib->refcnt,
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001936 (unsigned long) rib->uptime,
Denis Ovsienkodc958242007-08-13 16:03:06 +00001937 rib->type,
1938 rib->table
1939 );
1940 zlog_debug
1941 (
1942 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1943 func,
1944 rib->metric,
1945 rib->distance,
1946 rib->flags,
1947 rib->status
1948 );
1949 zlog_debug
1950 (
1951 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1952 func,
1953 rib->nexthop_num,
1954 rib->nexthop_active_num,
1955 rib->nexthop_fib_num
1956 );
Vincent Bernatfed643f2012-10-23 16:00:42 +00001957
Christian Frankefa713d92013-07-05 15:35:37 +00001958 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1959 {
Vincent Bernatfed643f2012-10-23 16:00:42 +00001960 inet_ntop (p->family, &nexthop->gate, straddr, INET6_ADDRSTRLEN);
Christian Frankefa713d92013-07-05 15:35:37 +00001961 zlog_debug
1962 (
1963 "%s: %s %s with flags %s%s%s",
1964 func,
1965 (recursing ? " NH" : "NH"),
1966 straddr,
1967 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1968 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1969 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1970 );
1971 }
Denis Ovsienkodc958242007-08-13 16:03:06 +00001972 zlog_debug ("%s: dump complete", func);
1973}
1974
1975/* This is an exported helper to rtm_read() to dump the strange
1976 * RIB entry found by rib_lookup_ipv4_route()
1977 */
1978
1979void rib_lookup_and_dump (struct prefix_ipv4 * p)
1980{
1981 struct route_table *table;
1982 struct route_node *rn;
1983 struct rib *rib;
1984 char prefix_buf[INET_ADDRSTRLEN];
1985
1986 /* Lookup table. */
1987 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1988 if (! table)
1989 {
1990 zlog_err ("%s: vrf_table() returned NULL", __func__);
1991 return;
1992 }
1993
1994 inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
1995 /* Scan the RIB table for exactly matching RIB entry. */
1996 rn = route_node_lookup (table, (struct prefix *) p);
1997
1998 /* No route for this prefix. */
1999 if (! rn)
2000 {
2001 zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
2002 return;
2003 }
2004
2005 /* Unlock node. */
2006 route_unlock_node (rn);
2007
2008 /* let's go */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002009 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00002010 {
2011 zlog_debug
2012 (
2013 "%s: rn %p, rib %p: %s, %s",
2014 __func__,
2015 rn,
2016 rib,
2017 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
2018 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
2019 );
David Lamparterf7bf4152013-10-22 17:10:21 +00002020 rib_dump (p, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002021 }
2022}
2023
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002024/* Check if requested address assignment will fail due to another
2025 * route being installed by zebra in FIB already. Take necessary
2026 * actions, if needed: remove such a route from FIB and deSELECT
2027 * corresponding RIB entry. Then put affected RN into RIBQ head.
2028 */
2029void rib_lookup_and_pushup (struct prefix_ipv4 * p)
2030{
2031 struct route_table *table;
2032 struct route_node *rn;
2033 struct rib *rib;
2034 unsigned changed = 0;
2035
2036 if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
2037 {
2038 zlog_err ("%s: vrf_table() returned NULL", __func__);
2039 return;
2040 }
2041
2042 /* No matches would be the simplest case. */
2043 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
2044 return;
2045
2046 /* Unlock node. */
2047 route_unlock_node (rn);
2048
2049 /* Check all RIB entries. In case any changes have to be done, requeue
2050 * the RN into RIBQ head. If the routing message about the new connected
2051 * route (generated by the IP address we are going to assign very soon)
2052 * comes before the RIBQ is processed, the new RIB entry will join
2053 * RIBQ record already on head. This is necessary for proper revalidation
2054 * of the rest of the RIB.
2055 */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002056 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002057 {
2058 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
2059 ! RIB_SYSTEM_ROUTE (rib))
2060 {
2061 changed = 1;
2062 if (IS_ZEBRA_DEBUG_RIB)
2063 {
2064 char buf[INET_ADDRSTRLEN];
2065 inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
2066 zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
David Lamparterf7bf4152013-10-22 17:10:21 +00002067 rib_dump (&rn->p, rib);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002068 }
2069 rib_uninstall (rn, rib);
2070 }
2071 }
2072 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002073 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002074}
2075
paul718e3742002-12-13 20:15:29 +00002076int
G.Balajicddf3912011-11-26 21:59:32 +04002077rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002078{
2079 struct route_table *table;
2080 struct route_node *rn;
2081 struct rib *same;
2082 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00002083
paul718e3742002-12-13 20:15:29 +00002084 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04002085 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00002086 if (! table)
2087 return 0;
G.Balajicddf3912011-11-26 21:59:32 +04002088
paul718e3742002-12-13 20:15:29 +00002089 /* Make it sure prefixlen is applied to the prefix. */
2090 apply_mask_ipv4 (p);
2091
2092 /* Set default distance by route type. */
2093 if (rib->distance == 0)
2094 {
2095 rib->distance = route_info[rib->type].distance;
2096
2097 /* iBGP distance is 200. */
2098 if (rib->type == ZEBRA_ROUTE_BGP
2099 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
2100 rib->distance = 200;
2101 }
2102
2103 /* Lookup route node.*/
2104 rn = route_node_get (table, (struct prefix *) p);
2105
2106 /* If same type of route are installed, treat it as a implicit
2107 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002108 RNODE_FOREACH_RIB (rn, same)
paul718e3742002-12-13 20:15:29 +00002109 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00002110 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00002111 continue;
2112
paul718e3742002-12-13 20:15:29 +00002113 if (same->type == rib->type && same->table == rib->table
2114 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00002115 break;
paul718e3742002-12-13 20:15:29 +00002116 }
paul4d38fdb2005-04-28 17:35:14 +00002117
paul718e3742002-12-13 20:15:29 +00002118 /* If this route is kernel route, set FIB flag to the route. */
2119 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
2120 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2121 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2122
2123 /* Link new rib to node.*/
2124 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002125 if (IS_ZEBRA_DEBUG_RIB)
2126 {
2127 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
2128 __func__, rn, rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00002129 rib_dump (p, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002130 }
paul718e3742002-12-13 20:15:29 +00002131
paul718e3742002-12-13 20:15:29 +00002132 /* Free implicit route.*/
2133 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00002134 {
2135 if (IS_ZEBRA_DEBUG_RIB)
2136 {
2137 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
2138 __func__, rn, same);
David Lamparterf7bf4152013-10-22 17:10:21 +00002139 rib_dump (p, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002140 }
paul4d38fdb2005-04-28 17:35:14 +00002141 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002142 }
paul4d38fdb2005-04-28 17:35:14 +00002143
2144 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002145 return 0;
2146}
2147
hassoebf1ead2005-09-21 14:58:20 +00002148/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002149int
2150rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
G.Balajicddf3912011-11-26 21:59:32 +04002151 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002152{
2153 struct route_table *table;
2154 struct route_node *rn;
2155 struct rib *rib;
2156 struct rib *fib = NULL;
2157 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002158 struct nexthop *nexthop, *tnexthop;
2159 int recursing;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002160 char buf1[INET_ADDRSTRLEN];
2161 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002162
2163 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04002164 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00002165 if (! table)
2166 return 0;
2167
2168 /* Apply mask. */
2169 apply_mask_ipv4 (p);
2170
Christian Frankeb52aef12013-11-27 17:06:15 +00002171 if (IS_ZEBRA_DEBUG_KERNEL)
2172 {
2173 if (gate)
2174 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
2175 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
2176 p->prefixlen,
2177 inet_ntoa (*gate),
2178 ifindex);
2179 else
2180 zlog_debug ("rib_delete_ipv4(): route delete %s/%d ifindex %d",
2181 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
2182 p->prefixlen,
2183 ifindex);
2184 }
paul5ec90d22003-06-19 01:41:37 +00002185
paul718e3742002-12-13 20:15:29 +00002186 /* Lookup route node. */
2187 rn = route_node_lookup (table, (struct prefix *) p);
2188 if (! rn)
2189 {
2190 if (IS_ZEBRA_DEBUG_KERNEL)
2191 {
2192 if (gate)
ajsb6178002004-12-07 21:12:56 +00002193 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002194 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002195 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002196 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002197 ifindex);
2198 else
ajsb6178002004-12-07 21:12:56 +00002199 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002200 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002201 p->prefixlen,
2202 ifindex);
2203 }
2204 return ZEBRA_ERR_RTNOEXIST;
2205 }
2206
2207 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002208 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002209 {
Paul Jakma6d691122006-07-27 21:49:00 +00002210 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2211 continue;
2212
paul718e3742002-12-13 20:15:29 +00002213 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2214 fib = rib;
2215
hassoebf1ead2005-09-21 14:58:20 +00002216 if (rib->type != type)
2217 continue;
2218 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002219 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002220 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002221 if (nexthop->ifindex != ifindex)
2222 continue;
hassoebf1ead2005-09-21 14:58:20 +00002223 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002224 {
hassoebf1ead2005-09-21 14:58:20 +00002225 rib->refcnt--;
2226 route_unlock_node (rn);
2227 route_unlock_node (rn);
2228 return 0;
paul718e3742002-12-13 20:15:29 +00002229 }
hassoebf1ead2005-09-21 14:58:20 +00002230 same = rib;
2231 break;
paul718e3742002-12-13 20:15:29 +00002232 }
hassoebf1ead2005-09-21 14:58:20 +00002233 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002234 else
paul5ec90d22003-06-19 01:41:37 +00002235 {
Christian Frankefa713d92013-07-05 15:35:37 +00002236 if (gate == NULL)
2237 {
2238 same = rib;
2239 break;
2240 }
2241 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2242 if (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate))
2243 {
2244 same = rib;
2245 break;
2246 }
2247 if (same)
2248 break;
2249 }
paul718e3742002-12-13 20:15:29 +00002250 }
paul718e3742002-12-13 20:15:29 +00002251 /* If same type of route can't be found and this message is from
2252 kernel. */
2253 if (! same)
2254 {
2255 if (fib && type == ZEBRA_ROUTE_KERNEL)
2256 {
2257 /* Unset flags. */
2258 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2259 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2260
2261 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2262 }
2263 else
2264 {
2265 if (IS_ZEBRA_DEBUG_KERNEL)
2266 {
2267 if (gate)
ajsb6178002004-12-07 21:12:56 +00002268 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002269 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002270 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002271 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002272 ifindex,
2273 type);
2274 else
ajsb6178002004-12-07 21:12:56 +00002275 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002276 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002277 p->prefixlen,
2278 ifindex,
2279 type);
2280 }
2281 route_unlock_node (rn);
2282 return ZEBRA_ERR_RTNOEXIST;
2283 }
2284 }
paul4d38fdb2005-04-28 17:35:14 +00002285
paul718e3742002-12-13 20:15:29 +00002286 if (same)
2287 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002288
paul718e3742002-12-13 20:15:29 +00002289 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002290 return 0;
2291}
David Lamparter6b0655a2014-06-04 06:53:35 +02002292
paul718e3742002-12-13 20:15:29 +00002293/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002294static void
paul718e3742002-12-13 20:15:29 +00002295static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
2296{
2297 struct rib *rib;
2298 struct route_node *rn;
2299 struct route_table *table;
2300
2301 /* Lookup table. */
2302 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2303 if (! table)
2304 return;
2305
2306 /* Lookup existing route */
2307 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002308 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002309 {
2310 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2311 continue;
2312
2313 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2314 break;
2315 }
paul718e3742002-12-13 20:15:29 +00002316
2317 if (rib)
2318 {
2319 /* Same distance static route is there. Update it with new
2320 nexthop. */
paul718e3742002-12-13 20:15:29 +00002321 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002322 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002323 {
2324 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002325 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002326 break;
2327 case STATIC_IPV4_IFNAME:
2328 nexthop_ifname_add (rib, si->gate.ifname);
2329 break;
2330 case STATIC_IPV4_BLACKHOLE:
2331 nexthop_blackhole_add (rib);
2332 break;
paul4d38fdb2005-04-28 17:35:14 +00002333 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002334 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002335 }
2336 else
2337 {
2338 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002339 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2340
paul718e3742002-12-13 20:15:29 +00002341 rib->type = ZEBRA_ROUTE_STATIC;
2342 rib->distance = si->distance;
2343 rib->metric = 0;
Nolan Leakeb0145dd2012-09-13 17:17:31 +00002344 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002345 rib->nexthop_num = 0;
2346
2347 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002348 {
2349 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002350 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002351 break;
2352 case STATIC_IPV4_IFNAME:
2353 nexthop_ifname_add (rib, si->gate.ifname);
2354 break;
2355 case STATIC_IPV4_BLACKHOLE:
2356 nexthop_blackhole_add (rib);
2357 break;
2358 }
paul718e3742002-12-13 20:15:29 +00002359
hasso81dfcaa2003-05-25 19:21:25 +00002360 /* Save the flags of this static routes (reject, blackhole) */
2361 rib->flags = si->flags;
2362
paul718e3742002-12-13 20:15:29 +00002363 /* Link this rib to the tree. */
2364 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002365 }
2366}
2367
paula1ac18c2005-06-28 17:17:12 +00002368static int
paul718e3742002-12-13 20:15:29 +00002369static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2370{
2371 if (nexthop->type == NEXTHOP_TYPE_IPV4
2372 && si->type == STATIC_IPV4_GATEWAY
2373 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2374 return 1;
2375 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2376 && si->type == STATIC_IPV4_IFNAME
2377 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2378 return 1;
paul595db7f2003-05-25 21:35:06 +00002379 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2380 && si->type == STATIC_IPV4_BLACKHOLE)
2381 return 1;
paule8e19462006-01-19 20:16:55 +00002382 return 0;
paul718e3742002-12-13 20:15:29 +00002383}
2384
2385/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002386static void
paul718e3742002-12-13 20:15:29 +00002387static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
2388{
2389 struct route_node *rn;
2390 struct rib *rib;
2391 struct nexthop *nexthop;
2392 struct route_table *table;
2393
2394 /* Lookup table. */
2395 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2396 if (! table)
2397 return;
paul4d38fdb2005-04-28 17:35:14 +00002398
paul718e3742002-12-13 20:15:29 +00002399 /* Lookup existing route with type and distance. */
2400 rn = route_node_lookup (table, p);
2401 if (! rn)
2402 return;
2403
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002404 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002405 {
2406 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2407 continue;
2408
2409 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2410 break;
2411 }
paul718e3742002-12-13 20:15:29 +00002412
2413 if (! rib)
2414 {
2415 route_unlock_node (rn);
2416 return;
2417 }
2418
2419 /* Lookup nexthop. */
2420 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2421 if (static_ipv4_nexthop_same (nexthop, si))
2422 break;
2423
2424 /* Can't find nexthop. */
2425 if (! nexthop)
2426 {
2427 route_unlock_node (rn);
2428 return;
2429 }
2430
2431 /* Check nexthop. */
2432 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002433 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002434 else
2435 {
paul6baeb982003-10-28 03:47:15 +00002436 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2437 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002438 nexthop_delete (rib, nexthop);
2439 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002440 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002441 }
paul718e3742002-12-13 20:15:29 +00002442 /* Unlock node. */
2443 route_unlock_node (rn);
2444}
2445
2446/* Add static route into static route configuration. */
2447int
hasso39db97e2004-10-12 20:50:58 +00002448static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00002449 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002450{
2451 u_char type = 0;
2452 struct route_node *rn;
2453 struct static_ipv4 *si;
2454 struct static_ipv4 *pp;
2455 struct static_ipv4 *cp;
2456 struct static_ipv4 *update = NULL;
2457 struct route_table *stable;
2458
2459 /* Lookup table. */
2460 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2461 if (! stable)
2462 return -1;
2463
2464 /* Lookup static route prefix. */
2465 rn = route_node_get (stable, p);
2466
2467 /* Make flags. */
2468 if (gate)
2469 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002470 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002471 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002472 else
2473 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002474
2475 /* Do nothing if there is a same static route. */
2476 for (si = rn->info; si; si = si->next)
2477 {
2478 if (type == si->type
2479 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2480 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2481 {
2482 if (distance == si->distance)
2483 {
2484 route_unlock_node (rn);
2485 return 0;
2486 }
2487 else
2488 update = si;
2489 }
2490 }
2491
Paul Jakma3c0755d2006-12-08 00:53:14 +00002492 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002493 if (update)
2494 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
2495
2496 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002497 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
paul718e3742002-12-13 20:15:29 +00002498
2499 si->type = type;
2500 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002501 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002502
2503 if (gate)
2504 si->gate.ipv4 = *gate;
2505 if (ifname)
2506 si->gate.ifname = XSTRDUP (0, ifname);
2507
2508 /* Add new static route information to the tree with sort by
2509 distance value and gateway address. */
2510 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2511 {
2512 if (si->distance < cp->distance)
2513 break;
2514 if (si->distance > cp->distance)
2515 continue;
2516 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2517 {
2518 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2519 break;
2520 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2521 continue;
2522 }
2523 }
2524
2525 /* Make linked list. */
2526 if (pp)
2527 pp->next = si;
2528 else
2529 rn->info = si;
2530 if (cp)
2531 cp->prev = si;
2532 si->prev = pp;
2533 si->next = cp;
2534
2535 /* Install into rib. */
2536 static_install_ipv4 (p, si);
2537
2538 return 1;
2539}
2540
2541/* Delete static route from static route configuration. */
2542int
hasso39db97e2004-10-12 20:50:58 +00002543static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00002544 u_char distance, u_int32_t vrf_id)
2545{
2546 u_char type = 0;
2547 struct route_node *rn;
2548 struct static_ipv4 *si;
2549 struct route_table *stable;
2550
2551 /* Lookup table. */
2552 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2553 if (! stable)
2554 return -1;
2555
2556 /* Lookup static route prefix. */
2557 rn = route_node_lookup (stable, p);
2558 if (! rn)
2559 return 0;
2560
2561 /* Make flags. */
2562 if (gate)
2563 type = STATIC_IPV4_GATEWAY;
2564 else if (ifname)
2565 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002566 else
2567 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002568
2569 /* Find same static route is the tree */
2570 for (si = rn->info; si; si = si->next)
2571 if (type == si->type
2572 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2573 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2574 break;
2575
2576 /* Can't find static route. */
2577 if (! si)
2578 {
2579 route_unlock_node (rn);
2580 return 0;
2581 }
2582
2583 /* Install into rib. */
2584 static_uninstall_ipv4 (p, si);
2585
2586 /* Unlink static route from linked list. */
2587 if (si->prev)
2588 si->prev->next = si->next;
2589 else
2590 rn->info = si->next;
2591 if (si->next)
2592 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002593 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002594
2595 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002596 if (ifname)
2597 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002598 XFREE (MTYPE_STATIC_IPV4, si);
2599
paul143a3852003-09-29 20:06:13 +00002600 route_unlock_node (rn);
2601
paul718e3742002-12-13 20:15:29 +00002602 return 1;
2603}
2604
David Lamparter6b0655a2014-06-04 06:53:35 +02002605
paul718e3742002-12-13 20:15:29 +00002606#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00002607static int
paul718e3742002-12-13 20:15:29 +00002608rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2609 struct in6_addr *gate, unsigned int ifindex, int table)
2610{
hasso726f9b22003-05-25 21:04:54 +00002611 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2612#if defined (MUSICA) || defined (LINUX)
2613 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2614 if (p->prefixlen == 96)
2615 return 0;
2616#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00002617 return 1;
hasso726f9b22003-05-25 21:04:54 +00002618 }
paul718e3742002-12-13 20:15:29 +00002619 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
2620 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
2621 {
2622 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
2623 return 1;
2624 }
2625 return 0;
2626}
2627
2628int
2629rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00002630 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
G.Balajif768f362011-11-26 22:10:39 +04002631 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002632{
2633 struct rib *rib;
2634 struct rib *same = NULL;
2635 struct route_table *table;
2636 struct route_node *rn;
2637 struct nexthop *nexthop;
2638
paul718e3742002-12-13 20:15:29 +00002639 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002640 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002641 if (! table)
2642 return 0;
2643
2644 /* Make sure mask is applied. */
2645 apply_mask_ipv6 (p);
2646
2647 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002648 if (!distance)
2649 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002650
2651 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2652 distance = 200;
2653
2654 /* Filter bogus route. */
2655 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
2656 return 0;
2657
2658 /* Lookup route node.*/
2659 rn = route_node_get (table, (struct prefix *) p);
2660
2661 /* If same type of route are installed, treat it as a implicit
2662 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002663 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002664 {
Paul Jakma6d691122006-07-27 21:49:00 +00002665 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2666 continue;
2667
hassoebf1ead2005-09-21 14:58:20 +00002668 if (rib->type != type)
2669 continue;
2670 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002671 {
2672 same = rib;
paul718e3742002-12-13 20:15:29 +00002673 break;
2674 }
hassoebf1ead2005-09-21 14:58:20 +00002675 else if ((nexthop = rib->nexthop) &&
2676 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2677 nexthop->ifindex == ifindex)
2678 {
2679 rib->refcnt++;
2680 return 0;
2681 }
paul718e3742002-12-13 20:15:29 +00002682 }
2683
2684 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002685 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2686
paul718e3742002-12-13 20:15:29 +00002687 rib->type = type;
2688 rib->distance = distance;
2689 rib->flags = flags;
2690 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00002691 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00002692 rib->nexthop_num = 0;
2693 rib->uptime = time (NULL);
2694
2695 /* Nexthop settings. */
2696 if (gate)
2697 {
2698 if (ifindex)
2699 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2700 else
2701 nexthop_ipv6_add (rib, gate);
2702 }
2703 else
2704 nexthop_ifindex_add (rib, ifindex);
2705
2706 /* If this route is kernel route, set FIB flag to the route. */
2707 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2708 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2709 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2710
2711 /* Link new rib to node.*/
2712 rib_addnode (rn, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002713 if (IS_ZEBRA_DEBUG_RIB)
2714 {
2715 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
2716 __func__, rn, rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00002717 rib_dump (p, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002718 }
paul718e3742002-12-13 20:15:29 +00002719
paul718e3742002-12-13 20:15:29 +00002720 /* Free implicit route.*/
2721 if (same)
Vincent Bernatfed643f2012-10-23 16:00:42 +00002722 {
2723 if (IS_ZEBRA_DEBUG_RIB)
2724 {
2725 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
2726 __func__, rn, same);
David Lamparterf7bf4152013-10-22 17:10:21 +00002727 rib_dump (p, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002728 }
paul4d38fdb2005-04-28 17:35:14 +00002729 rib_delnode (rn, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002730 }
paul4d38fdb2005-04-28 17:35:14 +00002731
2732 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002733 return 0;
2734}
2735
hassoebf1ead2005-09-21 14:58:20 +00002736/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002737int
2738rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
G.Balajif768f362011-11-26 22:10:39 +04002739 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002740{
2741 struct route_table *table;
2742 struct route_node *rn;
2743 struct rib *rib;
2744 struct rib *fib = NULL;
2745 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002746 struct nexthop *nexthop, *tnexthop;
2747 int recursing;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002748 char buf1[INET6_ADDRSTRLEN];
2749 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002750
2751 /* Apply mask. */
2752 apply_mask_ipv6 (p);
2753
2754 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002755 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002756 if (! table)
2757 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002758
paul718e3742002-12-13 20:15:29 +00002759 /* Lookup route node. */
2760 rn = route_node_lookup (table, (struct prefix *) p);
2761 if (! rn)
2762 {
2763 if (IS_ZEBRA_DEBUG_KERNEL)
2764 {
2765 if (gate)
ajsb6178002004-12-07 21:12:56 +00002766 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002767 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002768 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002769 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002770 ifindex);
2771 else
ajsb6178002004-12-07 21:12:56 +00002772 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002773 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002774 p->prefixlen,
2775 ifindex);
2776 }
2777 return ZEBRA_ERR_RTNOEXIST;
2778 }
2779
2780 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002781 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002782 {
Paul Jakma6d691122006-07-27 21:49:00 +00002783 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2784 continue;
2785
paul718e3742002-12-13 20:15:29 +00002786 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2787 fib = rib;
2788
hassoebf1ead2005-09-21 14:58:20 +00002789 if (rib->type != type)
2790 continue;
2791 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002792 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002793 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002794 if (nexthop->ifindex != ifindex)
2795 continue;
hassoebf1ead2005-09-21 14:58:20 +00002796 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002797 {
hassoebf1ead2005-09-21 14:58:20 +00002798 rib->refcnt--;
2799 route_unlock_node (rn);
2800 route_unlock_node (rn);
2801 return 0;
paul718e3742002-12-13 20:15:29 +00002802 }
hassoebf1ead2005-09-21 14:58:20 +00002803 same = rib;
2804 break;
paul718e3742002-12-13 20:15:29 +00002805 }
hassoebf1ead2005-09-21 14:58:20 +00002806 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002807 else
2808 {
2809 if (gate == NULL)
2810 {
2811 same = rib;
2812 break;
2813 }
2814 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2815 if (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate))
2816 {
2817 same = rib;
2818 break;
2819 }
2820 if (same)
2821 break;
2822 }
paul718e3742002-12-13 20:15:29 +00002823 }
2824
2825 /* If same type of route can't be found and this message is from
2826 kernel. */
2827 if (! same)
2828 {
2829 if (fib && type == ZEBRA_ROUTE_KERNEL)
2830 {
2831 /* Unset flags. */
2832 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2833 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2834
2835 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2836 }
2837 else
2838 {
2839 if (IS_ZEBRA_DEBUG_KERNEL)
2840 {
2841 if (gate)
ajsb6178002004-12-07 21:12:56 +00002842 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002843 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002844 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002845 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002846 ifindex,
2847 type);
2848 else
ajsb6178002004-12-07 21:12:56 +00002849 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002850 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002851 p->prefixlen,
2852 ifindex,
2853 type);
2854 }
2855 route_unlock_node (rn);
2856 return ZEBRA_ERR_RTNOEXIST;
2857 }
2858 }
2859
2860 if (same)
2861 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002862
paul718e3742002-12-13 20:15:29 +00002863 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002864 return 0;
2865}
David Lamparter6b0655a2014-06-04 06:53:35 +02002866
paul718e3742002-12-13 20:15:29 +00002867/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002868static void
paul718e3742002-12-13 20:15:29 +00002869static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2870{
2871 struct rib *rib;
2872 struct route_table *table;
2873 struct route_node *rn;
2874
2875 /* Lookup table. */
2876 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2877 if (! table)
2878 return;
2879
2880 /* Lookup existing route */
2881 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002882 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002883 {
2884 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2885 continue;
2886
2887 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2888 break;
2889 }
paul718e3742002-12-13 20:15:29 +00002890
2891 if (rib)
2892 {
2893 /* Same distance static route is there. Update it with new
2894 nexthop. */
paul718e3742002-12-13 20:15:29 +00002895 route_unlock_node (rn);
2896
2897 switch (si->type)
2898 {
2899 case STATIC_IPV6_GATEWAY:
2900 nexthop_ipv6_add (rib, &si->ipv6);
2901 break;
2902 case STATIC_IPV6_IFNAME:
2903 nexthop_ifname_add (rib, si->ifname);
2904 break;
2905 case STATIC_IPV6_GATEWAY_IFNAME:
2906 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2907 break;
2908 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002909 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002910 }
2911 else
2912 {
2913 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002914 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2915
paul718e3742002-12-13 20:15:29 +00002916 rib->type = ZEBRA_ROUTE_STATIC;
2917 rib->distance = si->distance;
2918 rib->metric = 0;
Dinesh G Duttd1b09912014-09-30 12:54:13 -07002919 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002920 rib->nexthop_num = 0;
2921
2922 switch (si->type)
2923 {
2924 case STATIC_IPV6_GATEWAY:
2925 nexthop_ipv6_add (rib, &si->ipv6);
2926 break;
2927 case STATIC_IPV6_IFNAME:
2928 nexthop_ifname_add (rib, si->ifname);
2929 break;
2930 case STATIC_IPV6_GATEWAY_IFNAME:
2931 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2932 break;
2933 }
2934
hasso81dfcaa2003-05-25 19:21:25 +00002935 /* Save the flags of this static routes (reject, blackhole) */
2936 rib->flags = si->flags;
2937
paul718e3742002-12-13 20:15:29 +00002938 /* Link this rib to the tree. */
2939 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002940 }
2941}
2942
paula1ac18c2005-06-28 17:17:12 +00002943static int
paul718e3742002-12-13 20:15:29 +00002944static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2945{
2946 if (nexthop->type == NEXTHOP_TYPE_IPV6
2947 && si->type == STATIC_IPV6_GATEWAY
2948 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2949 return 1;
2950 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2951 && si->type == STATIC_IPV6_IFNAME
2952 && strcmp (nexthop->ifname, si->ifname) == 0)
2953 return 1;
2954 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2955 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2956 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2957 && strcmp (nexthop->ifname, si->ifname) == 0)
2958 return 1;
paule8e19462006-01-19 20:16:55 +00002959 return 0;
paul718e3742002-12-13 20:15:29 +00002960}
2961
paula1ac18c2005-06-28 17:17:12 +00002962static void
paul718e3742002-12-13 20:15:29 +00002963static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2964{
2965 struct route_table *table;
2966 struct route_node *rn;
2967 struct rib *rib;
2968 struct nexthop *nexthop;
2969
2970 /* Lookup table. */
2971 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2972 if (! table)
2973 return;
2974
2975 /* Lookup existing route with type and distance. */
2976 rn = route_node_lookup (table, (struct prefix *) p);
2977 if (! rn)
2978 return;
2979
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002980 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002981 {
2982 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2983 continue;
2984
2985 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2986 break;
2987 }
2988
paul718e3742002-12-13 20:15:29 +00002989 if (! rib)
2990 {
2991 route_unlock_node (rn);
2992 return;
2993 }
2994
2995 /* Lookup nexthop. */
2996 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2997 if (static_ipv6_nexthop_same (nexthop, si))
2998 break;
2999
3000 /* Can't find nexthop. */
3001 if (! nexthop)
3002 {
3003 route_unlock_node (rn);
3004 return;
3005 }
3006
3007 /* Check nexthop. */
3008 if (rib->nexthop_num == 1)
3009 {
3010 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003011 }
3012 else
3013 {
paul6baeb982003-10-28 03:47:15 +00003014 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
3015 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00003016 nexthop_delete (rib, nexthop);
3017 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00003018 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003019 }
paul718e3742002-12-13 20:15:29 +00003020 /* Unlock node. */
3021 route_unlock_node (rn);
3022}
3023
3024/* Add static route into static route configuration. */
3025int
3026static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00003027 const char *ifname, u_char flags, u_char distance,
3028 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00003029{
3030 struct route_node *rn;
3031 struct static_ipv6 *si;
3032 struct static_ipv6 *pp;
3033 struct static_ipv6 *cp;
3034 struct route_table *stable;
3035
3036 /* Lookup table. */
3037 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
3038 if (! stable)
3039 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00003040
3041 if (!gate &&
3042 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
3043 return -1;
3044
3045 if (!ifname &&
3046 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
3047 return -1;
paul718e3742002-12-13 20:15:29 +00003048
3049 /* Lookup static route prefix. */
3050 rn = route_node_get (stable, p);
3051
3052 /* Do nothing if there is a same static route. */
3053 for (si = rn->info; si; si = si->next)
3054 {
3055 if (distance == si->distance
3056 && type == si->type
3057 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
3058 && (! ifname || strcmp (ifname, si->ifname) == 0))
3059 {
3060 route_unlock_node (rn);
3061 return 0;
3062 }
3063 }
3064
3065 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07003066 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
paul718e3742002-12-13 20:15:29 +00003067
3068 si->type = type;
3069 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00003070 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00003071
3072 switch (type)
3073 {
3074 case STATIC_IPV6_GATEWAY:
3075 si->ipv6 = *gate;
3076 break;
3077 case STATIC_IPV6_IFNAME:
3078 si->ifname = XSTRDUP (0, ifname);
3079 break;
3080 case STATIC_IPV6_GATEWAY_IFNAME:
3081 si->ipv6 = *gate;
3082 si->ifname = XSTRDUP (0, ifname);
3083 break;
3084 }
3085
3086 /* Add new static route information to the tree with sort by
3087 distance value and gateway address. */
3088 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
3089 {
3090 if (si->distance < cp->distance)
3091 break;
3092 if (si->distance > cp->distance)
3093 continue;
3094 }
3095
3096 /* Make linked list. */
3097 if (pp)
3098 pp->next = si;
3099 else
3100 rn->info = si;
3101 if (cp)
3102 cp->prev = si;
3103 si->prev = pp;
3104 si->next = cp;
3105
3106 /* Install into rib. */
3107 static_install_ipv6 (p, si);
3108
3109 return 1;
3110}
3111
3112/* Delete static route from static route configuration. */
3113int
3114static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00003115 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00003116{
3117 struct route_node *rn;
3118 struct static_ipv6 *si;
3119 struct route_table *stable;
3120
3121 /* Lookup table. */
3122 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
3123 if (! stable)
3124 return -1;
3125
3126 /* Lookup static route prefix. */
3127 rn = route_node_lookup (stable, p);
3128 if (! rn)
3129 return 0;
3130
3131 /* Find same static route is the tree */
3132 for (si = rn->info; si; si = si->next)
3133 if (distance == si->distance
3134 && type == si->type
3135 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
3136 && (! ifname || strcmp (ifname, si->ifname) == 0))
3137 break;
3138
3139 /* Can't find static route. */
3140 if (! si)
3141 {
3142 route_unlock_node (rn);
3143 return 0;
3144 }
3145
3146 /* Install into rib. */
3147 static_uninstall_ipv6 (p, si);
3148
3149 /* Unlink static route from linked list. */
3150 if (si->prev)
3151 si->prev->next = si->next;
3152 else
3153 rn->info = si->next;
3154 if (si->next)
3155 si->next->prev = si->prev;
3156
3157 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00003158 if (ifname)
3159 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00003160 XFREE (MTYPE_STATIC_IPV6, si);
3161
3162 return 1;
3163}
3164#endif /* HAVE_IPV6 */
David Lamparter6b0655a2014-06-04 06:53:35 +02003165
paul718e3742002-12-13 20:15:29 +00003166/* RIB update function. */
3167void
paula1ac18c2005-06-28 17:17:12 +00003168rib_update (void)
paul718e3742002-12-13 20:15:29 +00003169{
3170 struct route_node *rn;
3171 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00003172
paul718e3742002-12-13 20:15:29 +00003173 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
3174 if (table)
3175 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003176 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003177 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003178
3179 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
3180 if (table)
3181 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003182 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003183 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003184}
3185
David Lamparter6b0655a2014-06-04 06:53:35 +02003186
paul718e3742002-12-13 20:15:29 +00003187/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00003188static void
paul718e3742002-12-13 20:15:29 +00003189rib_weed_table (struct route_table *table)
3190{
3191 struct route_node *rn;
3192 struct rib *rib;
3193 struct rib *next;
3194
3195 if (table)
3196 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003197 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003198 {
Paul Jakma6d691122006-07-27 21:49:00 +00003199 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3200 continue;
3201
paulb21b19c2003-06-15 01:28:29 +00003202 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00003203 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00003204 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003205 }
3206}
3207
3208/* Delete all routes from non main table. */
3209void
paula1ac18c2005-06-28 17:17:12 +00003210rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00003211{
3212 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3213 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3214}
David Lamparter6b0655a2014-06-04 06:53:35 +02003215
paul718e3742002-12-13 20:15:29 +00003216/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00003217static void
paul718e3742002-12-13 20:15:29 +00003218rib_sweep_table (struct route_table *table)
3219{
3220 struct route_node *rn;
3221 struct rib *rib;
3222 struct rib *next;
3223 int ret = 0;
3224
3225 if (table)
3226 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003227 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003228 {
Paul Jakma6d691122006-07-27 21:49:00 +00003229 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3230 continue;
3231
paul718e3742002-12-13 20:15:29 +00003232 if (rib->type == ZEBRA_ROUTE_KERNEL &&
3233 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
3234 {
3235 ret = rib_uninstall_kernel (rn, rib);
3236 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00003237 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003238 }
3239 }
3240}
3241
3242/* Sweep all RIB tables. */
3243void
paula1ac18c2005-06-28 17:17:12 +00003244rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00003245{
3246 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3247 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3248}
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003249
3250/* Remove specific by protocol routes from 'table'. */
3251static unsigned long
3252rib_score_proto_table (u_char proto, struct route_table *table)
3253{
3254 struct route_node *rn;
3255 struct rib *rib;
3256 struct rib *next;
3257 unsigned long n = 0;
3258
3259 if (table)
3260 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003261 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003262 {
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003263 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3264 continue;
3265 if (rib->type == proto)
3266 {
3267 rib_delnode (rn, rib);
3268 n++;
3269 }
3270 }
3271
3272 return n;
3273}
3274
3275/* Remove specific by protocol routes. */
3276unsigned long
3277rib_score_proto (u_char proto)
3278{
3279 return rib_score_proto_table (proto, vrf_table (AFI_IP, SAFI_UNICAST, 0))
3280 +rib_score_proto_table (proto, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3281}
3282
paul718e3742002-12-13 20:15:29 +00003283/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00003284static void
paul718e3742002-12-13 20:15:29 +00003285rib_close_table (struct route_table *table)
3286{
3287 struct route_node *rn;
3288 struct rib *rib;
3289
3290 if (table)
3291 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003292 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00003293 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003294 if (!CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
3295 continue;
3296
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00003297 zfpm_trigger_update (rn, NULL);
3298
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003299 if (! RIB_SYSTEM_ROUTE (rib))
3300 rib_uninstall_kernel (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00003301 }
paul718e3742002-12-13 20:15:29 +00003302}
3303
3304/* Close all RIB tables. */
3305void
paula1ac18c2005-06-28 17:17:12 +00003306rib_close (void)
paul718e3742002-12-13 20:15:29 +00003307{
3308 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3309 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3310}
David Lamparter6b0655a2014-06-04 06:53:35 +02003311
paul718e3742002-12-13 20:15:29 +00003312/* Routing information base initialize. */
3313void
paula1ac18c2005-06-28 17:17:12 +00003314rib_init (void)
paul718e3742002-12-13 20:15:29 +00003315{
paul4d38fdb2005-04-28 17:35:14 +00003316 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00003317 /* VRF initialization. */
3318 vrf_init ();
3319}
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003320
3321/*
3322 * vrf_id_get_next
3323 *
3324 * Get the first vrf id that is greater than the given vrf id if any.
3325 *
3326 * Returns TRUE if a vrf id was found, FALSE otherwise.
3327 */
3328static inline int
3329vrf_id_get_next (uint32_t id, uint32_t *next_id_p)
3330{
3331 while (++id < vector_active (vrf_vector))
3332 {
3333 if (vrf_lookup (id))
3334 {
3335 *next_id_p = id;
3336 return 1;
3337 }
3338 }
3339
3340 return 0;
3341}
3342
3343/*
3344 * rib_tables_iter_next
3345 *
3346 * Returns the next table in the iteration.
3347 */
3348struct route_table *
3349rib_tables_iter_next (rib_tables_iter_t *iter)
3350{
3351 struct route_table *table;
3352
3353 /*
3354 * Array that helps us go over all AFI/SAFI combinations via one
3355 * index.
3356 */
3357 static struct {
3358 afi_t afi;
3359 safi_t safi;
3360 } afi_safis[] = {
3361 { AFI_IP, SAFI_UNICAST },
3362 { AFI_IP, SAFI_MULTICAST },
3363 { AFI_IP6, SAFI_UNICAST },
3364 { AFI_IP6, SAFI_MULTICAST },
3365 };
3366
3367 table = NULL;
3368
3369 switch (iter->state)
3370 {
3371
3372 case RIB_TABLES_ITER_S_INIT:
3373 iter->vrf_id = 0;
3374 iter->afi_safi_ix = -1;
3375
3376 /* Fall through */
3377
3378 case RIB_TABLES_ITER_S_ITERATING:
3379 iter->afi_safi_ix++;
3380 while (1)
3381 {
3382
3383 while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
3384 {
3385 table = vrf_table (afi_safis[iter->afi_safi_ix].afi,
3386 afi_safis[iter->afi_safi_ix].safi,
3387 iter->vrf_id);
3388 if (table)
3389 break;
3390
3391 iter->afi_safi_ix++;
3392 }
3393
3394 /*
3395 * Found another table in this vrf.
3396 */
3397 if (table)
3398 break;
3399
3400 /*
3401 * Done with all tables in the current vrf, go to the next
3402 * one.
3403 */
3404 if (!vrf_id_get_next (iter->vrf_id, &iter->vrf_id))
3405 break;
3406
3407 iter->afi_safi_ix = 0;
3408 }
3409
3410 break;
3411
3412 case RIB_TABLES_ITER_S_DONE:
3413 return NULL;
3414 }
3415
3416 if (table)
3417 iter->state = RIB_TABLES_ITER_S_ITERATING;
3418 else
3419 iter->state = RIB_TABLES_ITER_S_DONE;
3420
3421 return table;
3422}