blob: 8835ef37f97c60dfeaea4de2d20c7d2a14976e9e [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* Routing Information Base.
2 * Copyright (C) 1997, 98, 99, 2001 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "prefix.h"
25#include "table.h"
26#include "memory.h"
27#include "str.h"
28#include "command.h"
29#include "if.h"
30#include "log.h"
31#include "sockunion.h"
paul4d38fdb2005-04-28 17:35:14 +000032#include "linklist.h"
33#include "thread.h"
34#include "workqueue.h"
Paul Jakma7514fb72007-05-02 16:05:35 +000035#include "prefix.h"
36#include "routemap.h"
paul718e3742002-12-13 20:15:29 +000037
38#include "zebra/rib.h"
39#include "zebra/rt.h"
40#include "zebra/zserv.h"
41#include "zebra/redistribute.h"
42#include "zebra/debug.h"
Avneesh Sachdev5adc2522012-11-13 22:48:59 +000043#include "zebra/zebra_fpm.h"
paul718e3742002-12-13 20:15:29 +000044
45/* Default rtm_table for all clients */
paulb21b19c2003-06-15 01:28:29 +000046extern struct zebra_t zebrad;
paul718e3742002-12-13 20:15:29 +000047
Paul Jakma457eb9a2006-07-27 19:59:58 +000048/* Hold time for RIB process, should be very minimal.
49 * it is useful to able to set it otherwise for testing, hence exported
50 * as global here for test-rig code.
51 */
52int rib_process_hold_time = 10;
53
paul718e3742002-12-13 20:15:29 +000054/* Each route type's string and default distance value. */
Stephen Hemmingerd145bc02008-08-17 17:41:37 +010055static const struct
paul718e3742002-12-13 20:15:29 +000056{
57 int key;
58 int distance;
Paul Jakma57345092011-12-25 17:52:09 +010059} route_info[ZEBRA_ROUTE_MAX] =
paul718e3742002-12-13 20:15:29 +000060{
Paul Jakma57345092011-12-25 17:52:09 +010061 [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0},
62 [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0},
63 [ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0},
64 [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1},
65 [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120},
66 [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120},
67 [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110},
68 [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110},
69 [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115},
70 [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */},
71 [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 95},
David Lamparter7052f222009-08-27 00:28:28 +020072 /* no entry/default: 150 */
paul718e3742002-12-13 20:15:29 +000073};
74
75/* Vector for routing table. */
Stephen Hemmingerd145bc02008-08-17 17:41:37 +010076static vector vrf_vector;
paul718e3742002-12-13 20:15:29 +000077
Avneesh Sachdev1b5ed1b2012-11-13 22:48:54 +000078/*
79 * vrf_table_create
80 */
81static void
82vrf_table_create (struct vrf *vrf, afi_t afi, safi_t safi)
83{
84 rib_table_info_t *info;
85 struct route_table *table;
86
87 assert (!vrf->table[afi][safi]);
88
89 table = route_table_init ();
90 vrf->table[afi][safi] = table;
91
92 info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
93 info->vrf = vrf;
94 info->afi = afi;
95 info->safi = safi;
96 table->info = info;
97}
98
paul718e3742002-12-13 20:15:29 +000099/* Allocate new VRF. */
paula1ac18c2005-06-28 17:17:12 +0000100static struct vrf *
hassofce954f2004-10-07 20:29:24 +0000101vrf_alloc (const char *name)
paul718e3742002-12-13 20:15:29 +0000102{
103 struct vrf *vrf;
104
105 vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
106
107 /* Put name. */
108 if (name)
109 vrf->name = XSTRDUP (MTYPE_VRF_NAME, name);
110
111 /* Allocate routing table and static table. */
Avneesh Sachdev1b5ed1b2012-11-13 22:48:54 +0000112 vrf_table_create (vrf, AFI_IP, SAFI_UNICAST);
113 vrf_table_create (vrf, AFI_IP6, SAFI_UNICAST);
paul718e3742002-12-13 20:15:29 +0000114 vrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
115 vrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
Avneesh Sachdev1b5ed1b2012-11-13 22:48:54 +0000116 vrf_table_create (vrf, AFI_IP, SAFI_MULTICAST);
117 vrf_table_create (vrf, AFI_IP6, SAFI_MULTICAST);
G.Balajicddf3912011-11-26 21:59:32 +0400118 vrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
119 vrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
120
paul718e3742002-12-13 20:15:29 +0000121
122 return vrf;
123}
124
paul718e3742002-12-13 20:15:29 +0000125/* Lookup VRF by identifier. */
126struct vrf *
127vrf_lookup (u_int32_t id)
128{
129 return vector_lookup (vrf_vector, id);
130}
131
paul718e3742002-12-13 20:15:29 +0000132/* Initialize VRF. */
paula1ac18c2005-06-28 17:17:12 +0000133static void
134vrf_init (void)
paul718e3742002-12-13 20:15:29 +0000135{
136 struct vrf *default_table;
137
138 /* Allocate VRF vector. */
139 vrf_vector = vector_init (1);
140
141 /* Allocate default main table. */
142 default_table = vrf_alloc ("Default-IP-Routing-Table");
143
144 /* Default table index must be 0. */
145 vector_set_index (vrf_vector, 0, default_table);
146}
147
148/* Lookup route table. */
149struct route_table *
150vrf_table (afi_t afi, safi_t safi, u_int32_t id)
151{
152 struct vrf *vrf;
153
154 vrf = vrf_lookup (id);
155 if (! vrf)
156 return NULL;
157
Leonid Rosenboim9499bf22012-12-06 20:17:41 +0000158 if( afi >= AFI_MAX || safi >= SAFI_MAX )
159 return NULL;
160
paul718e3742002-12-13 20:15:29 +0000161 return vrf->table[afi][safi];
162}
163
164/* Lookup static route table. */
165struct route_table *
166vrf_static_table (afi_t afi, safi_t safi, u_int32_t id)
167{
168 struct vrf *vrf;
169
170 vrf = vrf_lookup (id);
171 if (! vrf)
172 return NULL;
173
Leonid Rosenboim9499bf22012-12-06 20:17:41 +0000174 if( afi >= AFI_MAX || safi >= SAFI_MAX )
175 return NULL;
176
paul718e3742002-12-13 20:15:29 +0000177 return vrf->stable[afi][safi];
178}
179
Avneesh Sachdev78deec42012-11-13 22:48:56 +0000180/*
181 * nexthop_type_to_str
182 */
183const char *
184nexthop_type_to_str (enum nexthop_types_t nh_type)
185{
186 static const char *desc[] = {
187 "none",
188 "Directly connected",
189 "Interface route",
190 "IPv4 nexthop",
191 "IPv4 nexthop with ifindex",
192 "IPv4 nexthop with ifname",
193 "IPv6 nexthop",
194 "IPv6 nexthop with ifindex",
195 "IPv6 nexthop with ifname",
196 "Null0 nexthop",
197 };
198
199 if (nh_type >= ZEBRA_NUM_OF (desc))
200 return "<Invalid nh type>";
201
202 return desc[nh_type];
203}
204
Christian Frankefa713d92013-07-05 15:35:37 +0000205/* Add nexthop to the end of a nexthop list. */
paula1ac18c2005-06-28 17:17:12 +0000206static void
Christian Frankefa713d92013-07-05 15:35:37 +0000207_nexthop_add (struct nexthop **target, struct nexthop *nexthop)
paul718e3742002-12-13 20:15:29 +0000208{
209 struct nexthop *last;
210
Christian Frankefa713d92013-07-05 15:35:37 +0000211 for (last = *target; last && last->next; last = last->next)
paul718e3742002-12-13 20:15:29 +0000212 ;
213 if (last)
214 last->next = nexthop;
215 else
Christian Frankefa713d92013-07-05 15:35:37 +0000216 *target = nexthop;
paul718e3742002-12-13 20:15:29 +0000217 nexthop->prev = last;
Christian Frankefa713d92013-07-05 15:35:37 +0000218}
paul718e3742002-12-13 20:15:29 +0000219
Christian Frankefa713d92013-07-05 15:35:37 +0000220/* Add nexthop to the end of a rib node's nexthop list */
221static void
222nexthop_add (struct rib *rib, struct nexthop *nexthop)
223{
224 _nexthop_add(&rib->nexthop, nexthop);
paul718e3742002-12-13 20:15:29 +0000225 rib->nexthop_num++;
226}
227
228/* Delete specified nexthop from the list. */
paula1ac18c2005-06-28 17:17:12 +0000229static void
paul718e3742002-12-13 20:15:29 +0000230nexthop_delete (struct rib *rib, struct nexthop *nexthop)
231{
232 if (nexthop->next)
233 nexthop->next->prev = nexthop->prev;
234 if (nexthop->prev)
235 nexthop->prev->next = nexthop->next;
236 else
237 rib->nexthop = nexthop->next;
238 rib->nexthop_num--;
239}
240
Christian Frankefa713d92013-07-05 15:35:37 +0000241static void nexthops_free(struct nexthop *nexthop);
242
paul718e3742002-12-13 20:15:29 +0000243/* Free nexthop. */
paula1ac18c2005-06-28 17:17:12 +0000244static void
paul718e3742002-12-13 20:15:29 +0000245nexthop_free (struct nexthop *nexthop)
246{
paula4b70762003-05-16 17:19:48 +0000247 if (nexthop->ifname)
248 XFREE (0, nexthop->ifname);
Christian Frankefa713d92013-07-05 15:35:37 +0000249 if (nexthop->resolved)
250 nexthops_free(nexthop->resolved);
paul718e3742002-12-13 20:15:29 +0000251 XFREE (MTYPE_NEXTHOP, nexthop);
252}
253
Christian Frankefa713d92013-07-05 15:35:37 +0000254/* Frees a list of nexthops */
255static void
256nexthops_free (struct nexthop *nexthop)
257{
258 struct nexthop *nh, *next;
259
260 for (nh = nexthop; nh; nh = next)
261 {
262 next = nh->next;
263 nexthop_free (nh);
264 }
265}
266
paul718e3742002-12-13 20:15:29 +0000267struct nexthop *
268nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
269{
270 struct nexthop *nexthop;
271
Stephen Hemminger393deb92008-08-18 14:13:29 -0700272 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000273 nexthop->type = NEXTHOP_TYPE_IFINDEX;
274 nexthop->ifindex = ifindex;
275
276 nexthop_add (rib, nexthop);
277
278 return nexthop;
279}
280
281struct nexthop *
282nexthop_ifname_add (struct rib *rib, char *ifname)
283{
284 struct nexthop *nexthop;
285
Stephen Hemminger393deb92008-08-18 14:13:29 -0700286 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000287 nexthop->type = NEXTHOP_TYPE_IFNAME;
paula4b70762003-05-16 17:19:48 +0000288 nexthop->ifname = XSTRDUP (0, ifname);
paul718e3742002-12-13 20:15:29 +0000289
290 nexthop_add (rib, nexthop);
291
292 return nexthop;
293}
294
295struct nexthop *
Paul Jakma7514fb72007-05-02 16:05:35 +0000296nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src)
paul718e3742002-12-13 20:15:29 +0000297{
298 struct nexthop *nexthop;
299
Stephen Hemminger393deb92008-08-18 14:13:29 -0700300 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000301 nexthop->type = NEXTHOP_TYPE_IPV4;
302 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000303 if (src)
304 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000305
306 nexthop_add (rib, nexthop);
307
308 return nexthop;
309}
310
Josh Bailey26e2ae32012-03-22 01:09:21 -0700311struct nexthop *
paul718e3742002-12-13 20:15:29 +0000312nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
Paul Jakma7514fb72007-05-02 16:05:35 +0000313 struct in_addr *src, unsigned int ifindex)
paul718e3742002-12-13 20:15:29 +0000314{
315 struct nexthop *nexthop;
316
Stephen Hemminger393deb92008-08-18 14:13:29 -0700317 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000318 nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
319 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000320 if (src)
321 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000322 nexthop->ifindex = ifindex;
323
324 nexthop_add (rib, nexthop);
325
326 return nexthop;
327}
328
329#ifdef HAVE_IPV6
330struct nexthop *
331nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
332{
333 struct nexthop *nexthop;
334
Stephen Hemminger393deb92008-08-18 14:13:29 -0700335 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000336 nexthop->type = NEXTHOP_TYPE_IPV6;
337 nexthop->gate.ipv6 = *ipv6;
338
339 nexthop_add (rib, nexthop);
340
341 return nexthop;
342}
343
paula1ac18c2005-06-28 17:17:12 +0000344static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000345nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
346 char *ifname)
347{
348 struct nexthop *nexthop;
349
Stephen Hemminger393deb92008-08-18 14:13:29 -0700350 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000351 nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
352 nexthop->gate.ipv6 = *ipv6;
353 nexthop->ifname = XSTRDUP (0, ifname);
354
355 nexthop_add (rib, nexthop);
356
357 return nexthop;
358}
359
paula1ac18c2005-06-28 17:17:12 +0000360static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000361nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
362 unsigned int ifindex)
363{
364 struct nexthop *nexthop;
365
Stephen Hemminger393deb92008-08-18 14:13:29 -0700366 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000367 nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
368 nexthop->gate.ipv6 = *ipv6;
369 nexthop->ifindex = ifindex;
370
371 nexthop_add (rib, nexthop);
372
373 return nexthop;
374}
375#endif /* HAVE_IPV6 */
376
paul595db7f2003-05-25 21:35:06 +0000377struct nexthop *
378nexthop_blackhole_add (struct rib *rib)
379{
380 struct nexthop *nexthop;
381
Stephen Hemminger393deb92008-08-18 14:13:29 -0700382 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul595db7f2003-05-25 21:35:06 +0000383 nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
384 SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
385
386 nexthop_add (rib, nexthop);
387
388 return nexthop;
389}
390
Christian Frankefa713d92013-07-05 15:35:37 +0000391/* This method checks whether a recursive nexthop has at
392 * least one resolved nexthop in the fib.
393 */
394int
395nexthop_has_fib_child(struct nexthop *nexthop)
396{
397 struct nexthop *nh;
398
399 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
400 return 0;
401
402 for (nh = nexthop->resolved; nh; nh = nh->next)
403 if (CHECK_FLAG (nh->flags, NEXTHOP_FLAG_FIB))
404 return 1;
405
406 return 0;
407}
408
paul718e3742002-12-13 20:15:29 +0000409/* If force flag is not set, do not modify falgs at all for uninstall
410 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000411static int
paul718e3742002-12-13 20:15:29 +0000412nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
413 struct route_node *top)
414{
415 struct prefix_ipv4 p;
416 struct route_table *table;
417 struct route_node *rn;
418 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000419 int resolved;
paul718e3742002-12-13 20:15:29 +0000420 struct nexthop *newhop;
Christian Frankefa713d92013-07-05 15:35:37 +0000421 struct nexthop *resolved_hop;
paul718e3742002-12-13 20:15:29 +0000422
423 if (nexthop->type == NEXTHOP_TYPE_IPV4)
424 nexthop->ifindex = 0;
425
426 if (set)
Christian Frankefa713d92013-07-05 15:35:37 +0000427 {
428 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
429 nexthops_free(nexthop->resolved);
430 nexthop->resolved = NULL;
431 }
paul718e3742002-12-13 20:15:29 +0000432
433 /* Make lookup prefix. */
434 memset (&p, 0, sizeof (struct prefix_ipv4));
435 p.family = AF_INET;
436 p.prefixlen = IPV4_MAX_PREFIXLEN;
437 p.prefix = nexthop->gate.ipv4;
438
439 /* Lookup table. */
440 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
441 if (! table)
442 return 0;
443
444 rn = route_node_match (table, (struct prefix *) &p);
445 while (rn)
446 {
447 route_unlock_node (rn);
448
David Warda50c1072009-12-03 15:34:39 +0300449 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000450 if (rn == top)
451 return 0;
452
453 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000454 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100455 {
456 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
457 continue;
458 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
459 break;
460 }
paul718e3742002-12-13 20:15:29 +0000461
462 /* If there is no selected route or matched route is EGP, go up
463 tree. */
464 if (! match
465 || match->type == ZEBRA_ROUTE_BGP)
466 {
467 do {
468 rn = rn->parent;
469 } while (rn && rn->info == NULL);
470 if (rn)
471 route_lock_node (rn);
472 }
473 else
474 {
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
paul718e3742002-12-13 20:15:29 +00001093
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];
paul4d38fdb2005-04-28 17:35:14 +00001252
1253 assert (rn);
1254
Paul Jakma93bdada2007-08-06 19:25:11 +00001255 if (IS_ZEBRA_DEBUG_RIB || IS_ZEBRA_DEBUG_RIB_Q)
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001256 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001257
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001258 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00001259 {
paul718e3742002-12-13 20:15:29 +00001260 /* Currently installed rib. */
1261 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Paul Jakma6d691122006-07-27 21:49:00 +00001262 {
1263 assert (fib == NULL);
1264 fib = rib;
1265 }
1266
1267 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1268 * which we need to do do further work with below.
1269 */
1270 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1271 {
1272 if (rib != fib)
1273 {
1274 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001275 zlog_debug ("%s: %s/%d: rn %p, removing rib %p", __func__,
1276 buf, rn->p.prefixlen, rn, rib);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001277 rib_unlink (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001278 }
1279 else
1280 del = rib;
1281
1282 continue;
1283 }
paul4d38fdb2005-04-28 17:35:14 +00001284
paul718e3742002-12-13 20:15:29 +00001285 /* Skip unreachable nexthop. */
1286 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +00001287 continue;
paul718e3742002-12-13 20:15:29 +00001288
1289 /* Infinit distance. */
1290 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +00001291 continue;
paul718e3742002-12-13 20:15:29 +00001292
paulaf887b52006-01-18 14:52:52 +00001293 /* Newly selected rib, the common case. */
1294 if (!select)
1295 {
1296 select = rib;
1297 continue;
1298 }
1299
1300 /* filter route selection in following order:
paulaf887b52006-01-18 14:52:52 +00001301 * - connected beats other types
paula8d9c1f2006-01-25 06:31:04 +00001302 * - lower distance beats higher
paulaf887b52006-01-18 14:52:52 +00001303 * - lower metric beats higher for equal distance
1304 * - last, hence oldest, route wins tie break.
1305 */
paula1038a12006-01-30 14:08:51 +00001306
1307 /* Connected routes. Pick the last connected
1308 * route of the set of lowest metric connected routes.
1309 */
paula8d9c1f2006-01-25 06:31:04 +00001310 if (rib->type == ZEBRA_ROUTE_CONNECT)
1311 {
paula1038a12006-01-30 14:08:51 +00001312 if (select->type != ZEBRA_ROUTE_CONNECT
paula8d9c1f2006-01-25 06:31:04 +00001313 || rib->metric <= select->metric)
paula1038a12006-01-30 14:08:51 +00001314 select = rib;
1315 continue;
paula8d9c1f2006-01-25 06:31:04 +00001316 }
1317 else if (select->type == ZEBRA_ROUTE_CONNECT)
1318 continue;
1319
1320 /* higher distance loses */
1321 if (rib->distance > select->distance)
1322 continue;
1323
1324 /* lower wins */
1325 if (rib->distance < select->distance)
1326 {
paulaf887b52006-01-18 14:52:52 +00001327 select = rib;
paula8d9c1f2006-01-25 06:31:04 +00001328 continue;
1329 }
1330
1331 /* metric tie-breaks equal distance */
1332 if (rib->metric <= select->metric)
1333 select = rib;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001334 } /* RNODE_FOREACH_RIB_SAFE */
Denis Ovsienkodc958242007-08-13 16:03:06 +00001335
1336 /* After the cycle is finished, the following pointers will be set:
1337 * select --- the winner RIB entry, if any was found, otherwise NULL
1338 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1339 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1340 * rib --- NULL
1341 */
1342
1343 /* Same RIB entry is selected. Update FIB and finish. */
paul718e3742002-12-13 20:15:29 +00001344 if (select && select == fib)
1345 {
Paul Jakma6d691122006-07-27 21:49:00 +00001346 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001347 zlog_debug ("%s: %s/%d: Updating existing route, select %p, fib %p",
1348 __func__, buf, rn->p.prefixlen, select, fib);
paul718e3742002-12-13 20:15:29 +00001349 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +00001350 {
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001351 zfpm_trigger_update (rn, "updating existing route");
1352
paul4d38fdb2005-04-28 17:35:14 +00001353 redistribute_delete (&rn->p, select);
1354 if (! RIB_SYSTEM_ROUTE (select))
1355 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001356
paul4d38fdb2005-04-28 17:35:14 +00001357 /* Set real nexthop. */
1358 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +00001359
paul4d38fdb2005-04-28 17:35:14 +00001360 if (! RIB_SYSTEM_ROUTE (select))
1361 rib_install_kernel (rn, select);
1362 redistribute_add (&rn->p, select);
1363 }
pauld753e9e2003-01-22 19:45:50 +00001364 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001365 {
1366 /* Housekeeping code to deal with
1367 race conditions in kernel with linux
1368 netlink reporting interface up before IPv4 or IPv6 protocol
1369 is ready to add routes.
1370 This makes sure the routes are IN the kernel.
1371 */
pauld753e9e2003-01-22 19:45:50 +00001372
Christian Frankefa713d92013-07-05 15:35:37 +00001373 for (ALL_NEXTHOPS_RO(select->nexthop, nexthop, tnexthop, recursing))
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001374 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
paul4d38fdb2005-04-28 17:35:14 +00001375 {
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001376 installed = 1;
1377 break;
paul4d38fdb2005-04-28 17:35:14 +00001378 }
1379 if (! installed)
1380 rib_install_kernel (rn, select);
1381 }
Paul Jakma6d691122006-07-27 21:49:00 +00001382 goto end;
paul718e3742002-12-13 20:15:29 +00001383 }
1384
Denis Ovsienkodc958242007-08-13 16:03:06 +00001385 /* At this point we either haven't found the best RIB entry or it is
1386 * different from what we currently intend to flag with SELECTED. In both
1387 * cases, if a RIB block is present in FIB, it should be withdrawn.
1388 */
paul718e3742002-12-13 20:15:29 +00001389 if (fib)
1390 {
Paul Jakma6d691122006-07-27 21:49:00 +00001391 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001392 zlog_debug ("%s: %s/%d: Removing existing route, fib %p", __func__,
1393 buf, rn->p.prefixlen, fib);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001394
1395 zfpm_trigger_update (rn, "removing existing route");
1396
paul718e3742002-12-13 20:15:29 +00001397 redistribute_delete (&rn->p, fib);
1398 if (! RIB_SYSTEM_ROUTE (fib))
1399 rib_uninstall_kernel (rn, fib);
1400 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1401
1402 /* Set real nexthop. */
1403 nexthop_active_update (rn, fib, 1);
1404 }
1405
Denis Ovsienkodc958242007-08-13 16:03:06 +00001406 /* Regardless of some RIB entry being SELECTED or not before, now we can
1407 * tell, that if a new winner exists, FIB is still not updated with this
1408 * data, but ready to be.
1409 */
paul718e3742002-12-13 20:15:29 +00001410 if (select)
1411 {
Paul Jakma6d691122006-07-27 21:49:00 +00001412 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001413 zlog_debug ("%s: %s/%d: Adding route, select %p", __func__, buf,
1414 rn->p.prefixlen, select);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001415
1416 zfpm_trigger_update (rn, "new route selected");
1417
paul718e3742002-12-13 20:15:29 +00001418 /* Set real nexthop. */
1419 nexthop_active_update (rn, select, 1);
1420
1421 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001422 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001423 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1424 redistribute_add (&rn->p, select);
1425 }
paul4d38fdb2005-04-28 17:35:14 +00001426
Paul Jakma6d691122006-07-27 21:49:00 +00001427 /* FIB route was removed, should be deleted */
1428 if (del)
1429 {
1430 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001431 zlog_debug ("%s: %s/%d: Deleting fib %p, rn %p", __func__, buf,
1432 rn->p.prefixlen, del, rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001433 rib_unlink (rn, del);
1434 }
paul4d38fdb2005-04-28 17:35:14 +00001435
Paul Jakma6d691122006-07-27 21:49:00 +00001436end:
1437 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma93bdada2007-08-06 19:25:11 +00001438 zlog_debug ("%s: %s/%d: rn %p dequeued", __func__, buf, rn->p.prefixlen, rn);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001439
1440 /*
1441 * Check if the dest can be deleted now.
1442 */
1443 rib_gc_dest (rn);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001444}
1445
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001446/* Take a list of route_node structs and return 1, if there was a record
1447 * picked from it and processed by rib_process(). Don't process more,
1448 * than one RN record; operate only in the specified sub-queue.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001449 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001450static unsigned int
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001451process_subq (struct list * subq, u_char qindex)
1452{
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001453 struct listnode *lnode = listhead (subq);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001454 struct route_node *rnode;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001455
1456 if (!lnode)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001457 return 0;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001458
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001459 rnode = listgetdata (lnode);
1460 rib_process (rnode);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001461
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001462 if (rnode->info)
1463 UNSET_FLAG (rib_dest_from_rnode (rnode)->flags, RIB_ROUTE_QUEUED (qindex));
1464
Chris Caputo67b94672009-07-18 04:02:26 +00001465#if 0
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001466 else
1467 {
1468 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1469 __func__, rnode, rnode->lock);
1470 zlog_backtrace(LOG_DEBUG);
1471 }
Chris Caputo67b94672009-07-18 04:02:26 +00001472#endif
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001473 route_unlock_node (rnode);
1474 list_delete_node (subq, lnode);
1475 return 1;
1476}
1477
1478/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1479 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1480 * is pointed to the meta queue structure.
1481 */
1482static wq_item_status
1483meta_queue_process (struct work_queue *dummy, void *data)
1484{
1485 struct meta_queue * mq = data;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001486 unsigned i;
1487
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001488 for (i = 0; i < MQ_SIZE; i++)
1489 if (process_subq (mq->subq[i], i))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001490 {
1491 mq->size--;
1492 break;
1493 }
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001494 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1495}
1496
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001497/*
1498 * Map from rib types to queue type (priority) in meta queue
1499 */
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001500static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
1501 [ZEBRA_ROUTE_SYSTEM] = 4,
1502 [ZEBRA_ROUTE_KERNEL] = 0,
1503 [ZEBRA_ROUTE_CONNECT] = 0,
1504 [ZEBRA_ROUTE_STATIC] = 1,
1505 [ZEBRA_ROUTE_RIP] = 2,
1506 [ZEBRA_ROUTE_RIPNG] = 2,
1507 [ZEBRA_ROUTE_OSPF] = 2,
1508 [ZEBRA_ROUTE_OSPF6] = 2,
1509 [ZEBRA_ROUTE_ISIS] = 2,
1510 [ZEBRA_ROUTE_BGP] = 3,
1511 [ZEBRA_ROUTE_HSLS] = 4,
Paul Jakma57345092011-12-25 17:52:09 +01001512 [ZEBRA_ROUTE_BABEL] = 2,
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001513};
1514
1515/* Look into the RN and queue it into one or more priority queues,
1516 * increasing the size for each data push done.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001517 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001518static void
1519rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001520{
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001521 struct rib *rib;
1522 char buf[INET6_ADDRSTRLEN];
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001523
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001524 if (IS_ZEBRA_DEBUG_RIB_Q)
1525 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001526
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001527 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001528 {
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001529 u_char qindex = meta_queue_map[rib->type];
1530
1531 /* Invariant: at this point we always have rn->info set. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001532 if (CHECK_FLAG (rib_dest_from_rnode (rn)->flags,
1533 RIB_ROUTE_QUEUED (qindex)))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001534 {
1535 if (IS_ZEBRA_DEBUG_RIB_Q)
1536 zlog_debug ("%s: %s/%d: rn %p is already queued in sub-queue %u",
1537 __func__, buf, rn->p.prefixlen, rn, qindex);
1538 continue;
1539 }
1540
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001541 SET_FLAG (rib_dest_from_rnode (rn)->flags, RIB_ROUTE_QUEUED (qindex));
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001542 listnode_add (mq->subq[qindex], rn);
1543 route_lock_node (rn);
1544 mq->size++;
1545
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001546 if (IS_ZEBRA_DEBUG_RIB_Q)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001547 zlog_debug ("%s: %s/%d: queued rn %p into sub-queue %u",
1548 __func__, buf, rn->p.prefixlen, rn, qindex);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001549 }
paul4d38fdb2005-04-28 17:35:14 +00001550}
1551
Paul Jakma6d691122006-07-27 21:49:00 +00001552/* Add route_node to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001553static void
Paul Jakma6d691122006-07-27 21:49:00 +00001554rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
paul4d38fdb2005-04-28 17:35:14 +00001555{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001556 char buf[INET_ADDRSTRLEN];
1557 assert (zebra && rn);
paul4d38fdb2005-04-28 17:35:14 +00001558
Paul Jakma93bdada2007-08-06 19:25:11 +00001559 if (IS_ZEBRA_DEBUG_RIB_Q)
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001560 inet_ntop (AF_INET, &rn->p.u.prefix, buf, INET_ADDRSTRLEN);
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001561
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001562 /* Pointless to queue a route_node with no RIB entries to add or remove */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001563 if (!rnode_to_ribs (rn))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001564 {
1565 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1566 __func__, rn, rn->lock);
1567 zlog_backtrace(LOG_DEBUG);
1568 return;
1569 }
1570
1571 if (IS_ZEBRA_DEBUG_RIB_Q)
1572 zlog_info ("%s: %s/%d: work queue added", __func__, buf, rn->p.prefixlen);
1573
1574 assert (zebra);
1575
1576 if (zebra->ribq == NULL)
1577 {
1578 zlog_err ("%s: work_queue does not exist!", __func__);
1579 return;
Paul Jakma6d691122006-07-27 21:49:00 +00001580 }
paul4d38fdb2005-04-28 17:35:14 +00001581
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001582 /*
1583 * The RIB queue should normally be either empty or holding the only
1584 * work_queue_item element. In the latter case this element would
1585 * hold a pointer to the meta queue structure, which must be used to
1586 * actually queue the route nodes to process. So create the MQ
1587 * holder, if necessary, then push the work into it in any case.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001588 * This semantics was introduced after 0.99.9 release.
1589 */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001590 if (!zebra->ribq->items->count)
1591 work_queue_add (zebra->ribq, zebra->mq);
1592
1593 rib_meta_queue_add (zebra->mq, rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001594
1595 if (IS_ZEBRA_DEBUG_RIB_Q)
1596 zlog_debug ("%s: %s/%d: rn %p queued", __func__, buf, rn->p.prefixlen, rn);
1597
1598 return;
paul4d38fdb2005-04-28 17:35:14 +00001599}
1600
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001601/* Create new meta queue.
1602 A destructor function doesn't seem to be necessary here.
1603 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001604static struct meta_queue *
1605meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001606{
1607 struct meta_queue *new;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001608 unsigned i;
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001609
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001610 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1611 assert(new);
1612
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001613 for (i = 0; i < MQ_SIZE; i++)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001614 {
1615 new->subq[i] = list_new ();
1616 assert(new->subq[i]);
1617 }
1618
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001619 return new;
1620}
1621
paul4d38fdb2005-04-28 17:35:14 +00001622/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001623static void
paul4d38fdb2005-04-28 17:35:14 +00001624rib_queue_init (struct zebra_t *zebra)
1625{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001626 assert (zebra);
1627
paul4d38fdb2005-04-28 17:35:14 +00001628 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001629 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001630 {
Paul Jakma6d691122006-07-27 21:49:00 +00001631 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001632 return;
1633 }
1634
1635 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001636 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001637 zebra->ribq->spec.errorfunc = NULL;
paul4d38fdb2005-04-28 17:35:14 +00001638 /* XXX: TODO: These should be runtime configurable via vty */
1639 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001640 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001641
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001642 if (!(zebra->mq = meta_queue_new ()))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001643 {
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001644 zlog_err ("%s: could not initialise meta queue!", __func__);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001645 return;
1646 }
1647 return;
paul718e3742002-12-13 20:15:29 +00001648}
1649
Paul Jakma6d691122006-07-27 21:49:00 +00001650/* RIB updates are processed via a queue of pointers to route_nodes.
1651 *
1652 * The queue length is bounded by the maximal size of the routing table,
1653 * as a route_node will not be requeued, if already queued.
1654 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001655 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1656 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1657 * and then submit route_node to queue for best-path selection later.
1658 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001659 *
1660 * Deleted RIBs are reaped during best-path selection.
1661 *
1662 * rib_addnode
1663 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001664 * |-------->| | best RIB, if required
1665 * | |
1666 * static_install->|->rib_addqueue...... -> rib_process
1667 * | |
1668 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001669 * |-> set RIB_ENTRY_REMOVE |
1670 * rib_delnode (RIB freed)
1671 *
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001672 * The 'info' pointer of a route_node points to a rib_dest_t
1673 * ('dest'). Queueing state for a route_node is kept on the dest. The
1674 * dest is created on-demand by rib_link() and is kept around at least
1675 * as long as there are ribs hanging off it (@see rib_gc_dest()).
Paul Jakma6d691122006-07-27 21:49:00 +00001676 *
1677 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1678 *
1679 * - route_nodes: refcounted by:
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001680 * - dest attached to route_node:
1681 * - managed by: rib_link/rib_gc_dest
Paul Jakma6d691122006-07-27 21:49:00 +00001682 * - route_node processing queue
1683 * - managed by: rib_addqueue, rib_process.
1684 *
1685 */
1686
paul718e3742002-12-13 20:15:29 +00001687/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001688static void
Paul Jakma6d691122006-07-27 21:49:00 +00001689rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001690{
1691 struct rib *head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001692 rib_dest_t *dest;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001693 char buf[INET6_ADDRSTRLEN];
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001694
paul4d38fdb2005-04-28 17:35:14 +00001695 assert (rib && rn);
1696
Paul Jakma6d691122006-07-27 21:49:00 +00001697 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001698 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001699 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001700 zlog_debug ("%s: %s/%d: rn %p, rib %p", __func__,
1701 buf, rn->p.prefixlen, rn, rib);
1702 }
Paul Jakma6d691122006-07-27 21:49:00 +00001703
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001704 dest = rib_dest_from_rnode (rn);
1705 if (!dest)
Paul Jakma6d691122006-07-27 21:49:00 +00001706 {
1707 if (IS_ZEBRA_DEBUG_RIB)
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001708 {
1709 zlog_debug ("%s: %s/%d: adding dest to table", __func__,
1710 buf, rn->p.prefixlen);
1711 }
1712
1713 dest = XCALLOC (MTYPE_RIB_DEST, sizeof (rib_dest_t));
1714 route_lock_node (rn); /* rn route table reference */
1715 rn->info = dest;
1716 dest->rnode = rn;
1717 }
1718
1719 head = dest->routes;
1720 if (head)
1721 {
Paul Jakma6d691122006-07-27 21:49:00 +00001722 head->prev = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001723 }
paul718e3742002-12-13 20:15:29 +00001724 rib->next = head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001725 dest->routes = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001726 rib_queue_add (&zebrad, rn);
1727}
1728
1729static void
1730rib_addnode (struct route_node *rn, struct rib *rib)
1731{
1732 /* RIB node has been un-removed before route-node is processed.
1733 * route_node must hence already be on the queue for processing..
1734 */
1735 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1736 {
1737 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001738 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001739 char buf[INET6_ADDRSTRLEN];
1740 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001741 zlog_debug ("%s: %s/%d: rn %p, un-removed rib %p",
1742 __func__, buf, rn->p.prefixlen, rn, rib);
1743 }
Paul Jakma6d691122006-07-27 21:49:00 +00001744 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1745 return;
1746 }
1747 rib_link (rn, rib);
1748}
1749
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001750/*
1751 * rib_unlink
1752 *
1753 * Detach a rib structure from a route_node.
1754 *
1755 * Note that a call to rib_unlink() should be followed by a call to
1756 * rib_gc_dest() at some point. This allows a rib_dest_t that is no
1757 * longer required to be deleted.
1758 */
Paul Jakma6d691122006-07-27 21:49:00 +00001759static void
1760rib_unlink (struct route_node *rn, struct rib *rib)
1761{
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001762 char buf[INET6_ADDRSTRLEN];
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001763 rib_dest_t *dest;
Paul Jakma6d691122006-07-27 21:49:00 +00001764
1765 assert (rn && rib);
1766
1767 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001768 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001769 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001770 zlog_debug ("%s: %s/%d: rn %p, rib %p",
1771 __func__, buf, rn->p.prefixlen, rn, rib);
1772 }
Paul Jakma6d691122006-07-27 21:49:00 +00001773
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001774 dest = rib_dest_from_rnode (rn);
1775
Paul Jakma6d691122006-07-27 21:49:00 +00001776 if (rib->next)
1777 rib->next->prev = rib->prev;
1778
1779 if (rib->prev)
1780 rib->prev->next = rib->next;
1781 else
1782 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001783 dest->routes = rib->next;
Paul Jakma6d691122006-07-27 21:49:00 +00001784 }
1785
1786 /* free RIB and nexthops */
Christian Frankefa713d92013-07-05 15:35:37 +00001787 nexthops_free(rib->nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00001788 XFREE (MTYPE_RIB, rib);
1789
paul718e3742002-12-13 20:15:29 +00001790}
1791
paula1ac18c2005-06-28 17:17:12 +00001792static void
paul718e3742002-12-13 20:15:29 +00001793rib_delnode (struct route_node *rn, struct rib *rib)
1794{
Paul Jakma6d691122006-07-27 21:49:00 +00001795 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001796 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001797 char buf[INET6_ADDRSTRLEN];
1798 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001799 zlog_debug ("%s: %s/%d: rn %p, rib %p, removing", __func__,
1800 buf, rn->p.prefixlen, rn, rib);
1801 }
Paul Jakma6d691122006-07-27 21:49:00 +00001802 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1803 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001804}
1805
1806int
1807rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001808 struct in_addr *gate, struct in_addr *src,
1809 unsigned int ifindex, u_int32_t vrf_id,
G.Balajicddf3912011-11-26 21:59:32 +04001810 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001811{
1812 struct rib *rib;
1813 struct rib *same = NULL;
1814 struct route_table *table;
1815 struct route_node *rn;
1816 struct nexthop *nexthop;
1817
1818 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04001819 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00001820 if (! table)
1821 return 0;
1822
1823 /* Make it sure prefixlen is applied to the prefix. */
1824 apply_mask_ipv4 (p);
1825
1826 /* Set default distance by route type. */
1827 if (distance == 0)
1828 {
Balaji.G837d16c2012-09-26 14:09:10 +05301829 if ((unsigned)type >= array_size(route_info))
David Lamparter7052f222009-08-27 00:28:28 +02001830 distance = 150;
1831 else
1832 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00001833
1834 /* iBGP distance is 200. */
1835 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1836 distance = 200;
1837 }
1838
1839 /* Lookup route node.*/
1840 rn = route_node_get (table, (struct prefix *) p);
1841
1842 /* If same type of route are installed, treat it as a implicit
1843 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001844 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00001845 {
Paul Jakma6d691122006-07-27 21:49:00 +00001846 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1847 continue;
1848
hassoebf1ead2005-09-21 14:58:20 +00001849 if (rib->type != type)
1850 continue;
1851 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001852 {
1853 same = rib;
1854 break;
1855 }
hassoebf1ead2005-09-21 14:58:20 +00001856 /* Duplicate connected route comes in. */
1857 else if ((nexthop = rib->nexthop) &&
1858 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001859 nexthop->ifindex == ifindex &&
1860 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001861 {
1862 rib->refcnt++;
1863 return 0 ;
1864 }
paul718e3742002-12-13 20:15:29 +00001865 }
1866
1867 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001868 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001869 rib->type = type;
1870 rib->distance = distance;
1871 rib->flags = flags;
1872 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001873 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001874 rib->nexthop_num = 0;
1875 rib->uptime = time (NULL);
1876
1877 /* Nexthop settings. */
1878 if (gate)
1879 {
1880 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001881 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001882 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001883 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001884 }
1885 else
1886 nexthop_ifindex_add (rib, ifindex);
1887
1888 /* If this route is kernel route, set FIB flag to the route. */
1889 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1890 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1891 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1892
1893 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001894 if (IS_ZEBRA_DEBUG_RIB)
1895 zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
paul718e3742002-12-13 20:15:29 +00001896 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001897
paul718e3742002-12-13 20:15:29 +00001898 /* Free implicit route.*/
1899 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001900 {
1901 if (IS_ZEBRA_DEBUG_RIB)
1902 zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001903 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001904 }
paul4d38fdb2005-04-28 17:35:14 +00001905
1906 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001907 return 0;
1908}
1909
Denis Ovsienkodc958242007-08-13 16:03:06 +00001910/* This function dumps the contents of a given RIB entry into
1911 * standard debug log. Calling function name and IP prefix in
1912 * question are passed as 1st and 2nd arguments.
1913 */
1914
David Lamparterf7bf4152013-10-22 17:10:21 +00001915void _rib_dump (const char * func,
1916 union prefix46constptr pp, const struct rib * rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001917{
David Lamparterf7bf4152013-10-22 17:10:21 +00001918 const struct prefix *p = pp.p;
Vincent Bernatfed643f2012-10-23 16:00:42 +00001919 char straddr[INET6_ADDRSTRLEN];
Christian Frankefa713d92013-07-05 15:35:37 +00001920 struct nexthop *nexthop, *tnexthop;
1921 int recursing;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001922
Vincent Bernatfed643f2012-10-23 16:00:42 +00001923 inet_ntop (p->family, &p->u.prefix, straddr, INET6_ADDRSTRLEN);
Christian Frankefa713d92013-07-05 15:35:37 +00001924 zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr, p->prefixlen);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001925 zlog_debug
1926 (
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001927 "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
Denis Ovsienkodc958242007-08-13 16:03:06 +00001928 func,
1929 rib->refcnt,
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001930 (unsigned long) rib->uptime,
Denis Ovsienkodc958242007-08-13 16:03:06 +00001931 rib->type,
1932 rib->table
1933 );
1934 zlog_debug
1935 (
1936 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1937 func,
1938 rib->metric,
1939 rib->distance,
1940 rib->flags,
1941 rib->status
1942 );
1943 zlog_debug
1944 (
1945 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1946 func,
1947 rib->nexthop_num,
1948 rib->nexthop_active_num,
1949 rib->nexthop_fib_num
1950 );
Vincent Bernatfed643f2012-10-23 16:00:42 +00001951
Christian Frankefa713d92013-07-05 15:35:37 +00001952 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1953 {
Vincent Bernatfed643f2012-10-23 16:00:42 +00001954 inet_ntop (p->family, &nexthop->gate, straddr, INET6_ADDRSTRLEN);
Christian Frankefa713d92013-07-05 15:35:37 +00001955 zlog_debug
1956 (
1957 "%s: %s %s with flags %s%s%s",
1958 func,
1959 (recursing ? " NH" : "NH"),
1960 straddr,
1961 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1962 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1963 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1964 );
1965 }
Denis Ovsienkodc958242007-08-13 16:03:06 +00001966 zlog_debug ("%s: dump complete", func);
1967}
1968
1969/* This is an exported helper to rtm_read() to dump the strange
1970 * RIB entry found by rib_lookup_ipv4_route()
1971 */
1972
1973void rib_lookup_and_dump (struct prefix_ipv4 * p)
1974{
1975 struct route_table *table;
1976 struct route_node *rn;
1977 struct rib *rib;
1978 char prefix_buf[INET_ADDRSTRLEN];
1979
1980 /* Lookup table. */
1981 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1982 if (! table)
1983 {
1984 zlog_err ("%s: vrf_table() returned NULL", __func__);
1985 return;
1986 }
1987
1988 inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
1989 /* Scan the RIB table for exactly matching RIB entry. */
1990 rn = route_node_lookup (table, (struct prefix *) p);
1991
1992 /* No route for this prefix. */
1993 if (! rn)
1994 {
1995 zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
1996 return;
1997 }
1998
1999 /* Unlock node. */
2000 route_unlock_node (rn);
2001
2002 /* let's go */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002003 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00002004 {
2005 zlog_debug
2006 (
2007 "%s: rn %p, rib %p: %s, %s",
2008 __func__,
2009 rn,
2010 rib,
2011 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
2012 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
2013 );
David Lamparterf7bf4152013-10-22 17:10:21 +00002014 rib_dump (p, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002015 }
2016}
2017
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002018/* Check if requested address assignment will fail due to another
2019 * route being installed by zebra in FIB already. Take necessary
2020 * actions, if needed: remove such a route from FIB and deSELECT
2021 * corresponding RIB entry. Then put affected RN into RIBQ head.
2022 */
2023void rib_lookup_and_pushup (struct prefix_ipv4 * p)
2024{
2025 struct route_table *table;
2026 struct route_node *rn;
2027 struct rib *rib;
2028 unsigned changed = 0;
2029
2030 if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
2031 {
2032 zlog_err ("%s: vrf_table() returned NULL", __func__);
2033 return;
2034 }
2035
2036 /* No matches would be the simplest case. */
2037 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
2038 return;
2039
2040 /* Unlock node. */
2041 route_unlock_node (rn);
2042
2043 /* Check all RIB entries. In case any changes have to be done, requeue
2044 * the RN into RIBQ head. If the routing message about the new connected
2045 * route (generated by the IP address we are going to assign very soon)
2046 * comes before the RIBQ is processed, the new RIB entry will join
2047 * RIBQ record already on head. This is necessary for proper revalidation
2048 * of the rest of the RIB.
2049 */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002050 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002051 {
2052 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
2053 ! RIB_SYSTEM_ROUTE (rib))
2054 {
2055 changed = 1;
2056 if (IS_ZEBRA_DEBUG_RIB)
2057 {
2058 char buf[INET_ADDRSTRLEN];
2059 inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
2060 zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
David Lamparterf7bf4152013-10-22 17:10:21 +00002061 rib_dump (&rn->p, rib);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002062 }
2063 rib_uninstall (rn, rib);
2064 }
2065 }
2066 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002067 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002068}
2069
paul718e3742002-12-13 20:15:29 +00002070int
G.Balajicddf3912011-11-26 21:59:32 +04002071rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002072{
2073 struct route_table *table;
2074 struct route_node *rn;
2075 struct rib *same;
2076 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00002077
paul718e3742002-12-13 20:15:29 +00002078 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04002079 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00002080 if (! table)
2081 return 0;
G.Balajicddf3912011-11-26 21:59:32 +04002082
paul718e3742002-12-13 20:15:29 +00002083 /* Make it sure prefixlen is applied to the prefix. */
2084 apply_mask_ipv4 (p);
2085
2086 /* Set default distance by route type. */
2087 if (rib->distance == 0)
2088 {
2089 rib->distance = route_info[rib->type].distance;
2090
2091 /* iBGP distance is 200. */
2092 if (rib->type == ZEBRA_ROUTE_BGP
2093 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
2094 rib->distance = 200;
2095 }
2096
2097 /* Lookup route node.*/
2098 rn = route_node_get (table, (struct prefix *) p);
2099
2100 /* If same type of route are installed, treat it as a implicit
2101 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002102 RNODE_FOREACH_RIB (rn, same)
paul718e3742002-12-13 20:15:29 +00002103 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00002104 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00002105 continue;
2106
paul718e3742002-12-13 20:15:29 +00002107 if (same->type == rib->type && same->table == rib->table
2108 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00002109 break;
paul718e3742002-12-13 20:15:29 +00002110 }
paul4d38fdb2005-04-28 17:35:14 +00002111
paul718e3742002-12-13 20:15:29 +00002112 /* If this route is kernel route, set FIB flag to the route. */
2113 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
2114 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2115 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2116
2117 /* Link new rib to node.*/
2118 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002119 if (IS_ZEBRA_DEBUG_RIB)
2120 {
2121 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
2122 __func__, rn, rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00002123 rib_dump (p, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002124 }
paul718e3742002-12-13 20:15:29 +00002125
paul718e3742002-12-13 20:15:29 +00002126 /* Free implicit route.*/
2127 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00002128 {
2129 if (IS_ZEBRA_DEBUG_RIB)
2130 {
2131 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
2132 __func__, rn, same);
David Lamparterf7bf4152013-10-22 17:10:21 +00002133 rib_dump (p, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002134 }
paul4d38fdb2005-04-28 17:35:14 +00002135 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002136 }
paul4d38fdb2005-04-28 17:35:14 +00002137
2138 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002139 return 0;
2140}
2141
hassoebf1ead2005-09-21 14:58:20 +00002142/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002143int
2144rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
G.Balajicddf3912011-11-26 21:59:32 +04002145 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002146{
2147 struct route_table *table;
2148 struct route_node *rn;
2149 struct rib *rib;
2150 struct rib *fib = NULL;
2151 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002152 struct nexthop *nexthop, *tnexthop;
2153 int recursing;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002154 char buf1[INET_ADDRSTRLEN];
2155 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002156
2157 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04002158 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00002159 if (! table)
2160 return 0;
2161
2162 /* Apply mask. */
2163 apply_mask_ipv4 (p);
2164
Christian Frankeb52aef12013-11-27 17:06:15 +00002165 if (IS_ZEBRA_DEBUG_KERNEL)
2166 {
2167 if (gate)
2168 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
2169 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
2170 p->prefixlen,
2171 inet_ntoa (*gate),
2172 ifindex);
2173 else
2174 zlog_debug ("rib_delete_ipv4(): route delete %s/%d ifindex %d",
2175 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
2176 p->prefixlen,
2177 ifindex);
2178 }
paul5ec90d22003-06-19 01:41:37 +00002179
paul718e3742002-12-13 20:15:29 +00002180 /* Lookup route node. */
2181 rn = route_node_lookup (table, (struct prefix *) p);
2182 if (! rn)
2183 {
2184 if (IS_ZEBRA_DEBUG_KERNEL)
2185 {
2186 if (gate)
ajsb6178002004-12-07 21:12:56 +00002187 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002188 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002189 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002190 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002191 ifindex);
2192 else
ajsb6178002004-12-07 21:12:56 +00002193 zlog_debug ("route %s/%d 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,
2196 ifindex);
2197 }
2198 return ZEBRA_ERR_RTNOEXIST;
2199 }
2200
2201 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002202 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002203 {
Paul Jakma6d691122006-07-27 21:49:00 +00002204 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2205 continue;
2206
paul718e3742002-12-13 20:15:29 +00002207 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2208 fib = rib;
2209
hassoebf1ead2005-09-21 14:58:20 +00002210 if (rib->type != type)
2211 continue;
2212 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002213 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002214 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002215 if (nexthop->ifindex != ifindex)
2216 continue;
hassoebf1ead2005-09-21 14:58:20 +00002217 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002218 {
hassoebf1ead2005-09-21 14:58:20 +00002219 rib->refcnt--;
2220 route_unlock_node (rn);
2221 route_unlock_node (rn);
2222 return 0;
paul718e3742002-12-13 20:15:29 +00002223 }
hassoebf1ead2005-09-21 14:58:20 +00002224 same = rib;
2225 break;
paul718e3742002-12-13 20:15:29 +00002226 }
hassoebf1ead2005-09-21 14:58:20 +00002227 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002228 else
paul5ec90d22003-06-19 01:41:37 +00002229 {
Christian Frankefa713d92013-07-05 15:35:37 +00002230 if (gate == NULL)
2231 {
2232 same = rib;
2233 break;
2234 }
2235 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2236 if (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate))
2237 {
2238 same = rib;
2239 break;
2240 }
2241 if (same)
2242 break;
2243 }
paul718e3742002-12-13 20:15:29 +00002244 }
paul718e3742002-12-13 20:15:29 +00002245 /* If same type of route can't be found and this message is from
2246 kernel. */
2247 if (! same)
2248 {
2249 if (fib && type == ZEBRA_ROUTE_KERNEL)
2250 {
2251 /* Unset flags. */
2252 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2253 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2254
2255 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2256 }
2257 else
2258 {
2259 if (IS_ZEBRA_DEBUG_KERNEL)
2260 {
2261 if (gate)
ajsb6178002004-12-07 21:12:56 +00002262 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002263 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002264 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002265 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002266 ifindex,
2267 type);
2268 else
ajsb6178002004-12-07 21:12:56 +00002269 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002270 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002271 p->prefixlen,
2272 ifindex,
2273 type);
2274 }
2275 route_unlock_node (rn);
2276 return ZEBRA_ERR_RTNOEXIST;
2277 }
2278 }
paul4d38fdb2005-04-28 17:35:14 +00002279
paul718e3742002-12-13 20:15:29 +00002280 if (same)
2281 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002282
paul718e3742002-12-13 20:15:29 +00002283 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002284 return 0;
2285}
2286
2287/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002288static void
paul718e3742002-12-13 20:15:29 +00002289static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
2290{
2291 struct rib *rib;
2292 struct route_node *rn;
2293 struct route_table *table;
2294
2295 /* Lookup table. */
2296 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2297 if (! table)
2298 return;
2299
2300 /* Lookup existing route */
2301 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002302 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002303 {
2304 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2305 continue;
2306
2307 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2308 break;
2309 }
paul718e3742002-12-13 20:15:29 +00002310
2311 if (rib)
2312 {
2313 /* Same distance static route is there. Update it with new
2314 nexthop. */
paul718e3742002-12-13 20:15:29 +00002315 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002316 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002317 {
2318 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002319 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002320 break;
2321 case STATIC_IPV4_IFNAME:
2322 nexthop_ifname_add (rib, si->gate.ifname);
2323 break;
2324 case STATIC_IPV4_BLACKHOLE:
2325 nexthop_blackhole_add (rib);
2326 break;
paul4d38fdb2005-04-28 17:35:14 +00002327 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002328 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002329 }
2330 else
2331 {
2332 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002333 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2334
paul718e3742002-12-13 20:15:29 +00002335 rib->type = ZEBRA_ROUTE_STATIC;
2336 rib->distance = si->distance;
2337 rib->metric = 0;
Nolan Leakeb0145dd2012-09-13 17:17:31 +00002338 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002339 rib->nexthop_num = 0;
2340
2341 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002342 {
2343 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002344 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002345 break;
2346 case STATIC_IPV4_IFNAME:
2347 nexthop_ifname_add (rib, si->gate.ifname);
2348 break;
2349 case STATIC_IPV4_BLACKHOLE:
2350 nexthop_blackhole_add (rib);
2351 break;
2352 }
paul718e3742002-12-13 20:15:29 +00002353
hasso81dfcaa2003-05-25 19:21:25 +00002354 /* Save the flags of this static routes (reject, blackhole) */
2355 rib->flags = si->flags;
2356
paul718e3742002-12-13 20:15:29 +00002357 /* Link this rib to the tree. */
2358 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002359 }
2360}
2361
paula1ac18c2005-06-28 17:17:12 +00002362static int
paul718e3742002-12-13 20:15:29 +00002363static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2364{
2365 if (nexthop->type == NEXTHOP_TYPE_IPV4
2366 && si->type == STATIC_IPV4_GATEWAY
2367 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2368 return 1;
2369 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2370 && si->type == STATIC_IPV4_IFNAME
2371 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2372 return 1;
paul595db7f2003-05-25 21:35:06 +00002373 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2374 && si->type == STATIC_IPV4_BLACKHOLE)
2375 return 1;
paule8e19462006-01-19 20:16:55 +00002376 return 0;
paul718e3742002-12-13 20:15:29 +00002377}
2378
2379/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002380static void
paul718e3742002-12-13 20:15:29 +00002381static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
2382{
2383 struct route_node *rn;
2384 struct rib *rib;
2385 struct nexthop *nexthop;
2386 struct route_table *table;
2387
2388 /* Lookup table. */
2389 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2390 if (! table)
2391 return;
paul4d38fdb2005-04-28 17:35:14 +00002392
paul718e3742002-12-13 20:15:29 +00002393 /* Lookup existing route with type and distance. */
2394 rn = route_node_lookup (table, p);
2395 if (! rn)
2396 return;
2397
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002398 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002399 {
2400 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2401 continue;
2402
2403 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2404 break;
2405 }
paul718e3742002-12-13 20:15:29 +00002406
2407 if (! rib)
2408 {
2409 route_unlock_node (rn);
2410 return;
2411 }
2412
2413 /* Lookup nexthop. */
2414 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2415 if (static_ipv4_nexthop_same (nexthop, si))
2416 break;
2417
2418 /* Can't find nexthop. */
2419 if (! nexthop)
2420 {
2421 route_unlock_node (rn);
2422 return;
2423 }
2424
2425 /* Check nexthop. */
2426 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002427 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002428 else
2429 {
paul6baeb982003-10-28 03:47:15 +00002430 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2431 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002432 nexthop_delete (rib, nexthop);
2433 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002434 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002435 }
paul718e3742002-12-13 20:15:29 +00002436 /* Unlock node. */
2437 route_unlock_node (rn);
2438}
2439
2440/* Add static route into static route configuration. */
2441int
hasso39db97e2004-10-12 20:50:58 +00002442static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00002443 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002444{
2445 u_char type = 0;
2446 struct route_node *rn;
2447 struct static_ipv4 *si;
2448 struct static_ipv4 *pp;
2449 struct static_ipv4 *cp;
2450 struct static_ipv4 *update = NULL;
2451 struct route_table *stable;
2452
2453 /* Lookup table. */
2454 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2455 if (! stable)
2456 return -1;
2457
2458 /* Lookup static route prefix. */
2459 rn = route_node_get (stable, p);
2460
2461 /* Make flags. */
2462 if (gate)
2463 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002464 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002465 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002466 else
2467 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002468
2469 /* Do nothing if there is a same static route. */
2470 for (si = rn->info; si; si = si->next)
2471 {
2472 if (type == si->type
2473 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2474 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2475 {
2476 if (distance == si->distance)
2477 {
2478 route_unlock_node (rn);
2479 return 0;
2480 }
2481 else
2482 update = si;
2483 }
2484 }
2485
Paul Jakma3c0755d2006-12-08 00:53:14 +00002486 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002487 if (update)
2488 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
2489
2490 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002491 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
paul718e3742002-12-13 20:15:29 +00002492
2493 si->type = type;
2494 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002495 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002496
2497 if (gate)
2498 si->gate.ipv4 = *gate;
2499 if (ifname)
2500 si->gate.ifname = XSTRDUP (0, ifname);
2501
2502 /* Add new static route information to the tree with sort by
2503 distance value and gateway address. */
2504 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2505 {
2506 if (si->distance < cp->distance)
2507 break;
2508 if (si->distance > cp->distance)
2509 continue;
2510 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2511 {
2512 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2513 break;
2514 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2515 continue;
2516 }
2517 }
2518
2519 /* Make linked list. */
2520 if (pp)
2521 pp->next = si;
2522 else
2523 rn->info = si;
2524 if (cp)
2525 cp->prev = si;
2526 si->prev = pp;
2527 si->next = cp;
2528
2529 /* Install into rib. */
2530 static_install_ipv4 (p, si);
2531
2532 return 1;
2533}
2534
2535/* Delete static route from static route configuration. */
2536int
hasso39db97e2004-10-12 20:50:58 +00002537static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00002538 u_char distance, u_int32_t vrf_id)
2539{
2540 u_char type = 0;
2541 struct route_node *rn;
2542 struct static_ipv4 *si;
2543 struct route_table *stable;
2544
2545 /* Lookup table. */
2546 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2547 if (! stable)
2548 return -1;
2549
2550 /* Lookup static route prefix. */
2551 rn = route_node_lookup (stable, p);
2552 if (! rn)
2553 return 0;
2554
2555 /* Make flags. */
2556 if (gate)
2557 type = STATIC_IPV4_GATEWAY;
2558 else if (ifname)
2559 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002560 else
2561 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002562
2563 /* Find same static route is the tree */
2564 for (si = rn->info; si; si = si->next)
2565 if (type == si->type
2566 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2567 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2568 break;
2569
2570 /* Can't find static route. */
2571 if (! si)
2572 {
2573 route_unlock_node (rn);
2574 return 0;
2575 }
2576
2577 /* Install into rib. */
2578 static_uninstall_ipv4 (p, si);
2579
2580 /* Unlink static route from linked list. */
2581 if (si->prev)
2582 si->prev->next = si->next;
2583 else
2584 rn->info = si->next;
2585 if (si->next)
2586 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002587 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002588
2589 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002590 if (ifname)
2591 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002592 XFREE (MTYPE_STATIC_IPV4, si);
2593
paul143a3852003-09-29 20:06:13 +00002594 route_unlock_node (rn);
2595
paul718e3742002-12-13 20:15:29 +00002596 return 1;
2597}
2598
2599
2600#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00002601static int
paul718e3742002-12-13 20:15:29 +00002602rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2603 struct in6_addr *gate, unsigned int ifindex, int table)
2604{
hasso726f9b22003-05-25 21:04:54 +00002605 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2606#if defined (MUSICA) || defined (LINUX)
2607 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2608 if (p->prefixlen == 96)
2609 return 0;
2610#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00002611 return 1;
hasso726f9b22003-05-25 21:04:54 +00002612 }
paul718e3742002-12-13 20:15:29 +00002613 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
2614 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
2615 {
2616 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
2617 return 1;
2618 }
2619 return 0;
2620}
2621
2622int
2623rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00002624 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
G.Balajif768f362011-11-26 22:10:39 +04002625 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002626{
2627 struct rib *rib;
2628 struct rib *same = NULL;
2629 struct route_table *table;
2630 struct route_node *rn;
2631 struct nexthop *nexthop;
2632
paul718e3742002-12-13 20:15:29 +00002633 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002634 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002635 if (! table)
2636 return 0;
2637
2638 /* Make sure mask is applied. */
2639 apply_mask_ipv6 (p);
2640
2641 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002642 if (!distance)
2643 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002644
2645 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2646 distance = 200;
2647
2648 /* Filter bogus route. */
2649 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
2650 return 0;
2651
2652 /* Lookup route node.*/
2653 rn = route_node_get (table, (struct prefix *) p);
2654
2655 /* If same type of route are installed, treat it as a implicit
2656 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002657 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002658 {
Paul Jakma6d691122006-07-27 21:49:00 +00002659 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2660 continue;
2661
hassoebf1ead2005-09-21 14:58:20 +00002662 if (rib->type != type)
2663 continue;
2664 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002665 {
2666 same = rib;
paul718e3742002-12-13 20:15:29 +00002667 break;
2668 }
hassoebf1ead2005-09-21 14:58:20 +00002669 else if ((nexthop = rib->nexthop) &&
2670 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2671 nexthop->ifindex == ifindex)
2672 {
2673 rib->refcnt++;
2674 return 0;
2675 }
paul718e3742002-12-13 20:15:29 +00002676 }
2677
2678 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002679 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2680
paul718e3742002-12-13 20:15:29 +00002681 rib->type = type;
2682 rib->distance = distance;
2683 rib->flags = flags;
2684 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00002685 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00002686 rib->nexthop_num = 0;
2687 rib->uptime = time (NULL);
2688
2689 /* Nexthop settings. */
2690 if (gate)
2691 {
2692 if (ifindex)
2693 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2694 else
2695 nexthop_ipv6_add (rib, gate);
2696 }
2697 else
2698 nexthop_ifindex_add (rib, ifindex);
2699
2700 /* If this route is kernel route, set FIB flag to the route. */
2701 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2702 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2703 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2704
2705 /* Link new rib to node.*/
2706 rib_addnode (rn, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002707 if (IS_ZEBRA_DEBUG_RIB)
2708 {
2709 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
2710 __func__, rn, rib);
David Lamparterf7bf4152013-10-22 17:10:21 +00002711 rib_dump (p, rib);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002712 }
paul718e3742002-12-13 20:15:29 +00002713
paul718e3742002-12-13 20:15:29 +00002714 /* Free implicit route.*/
2715 if (same)
Vincent Bernatfed643f2012-10-23 16:00:42 +00002716 {
2717 if (IS_ZEBRA_DEBUG_RIB)
2718 {
2719 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
2720 __func__, rn, same);
David Lamparterf7bf4152013-10-22 17:10:21 +00002721 rib_dump (p, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002722 }
paul4d38fdb2005-04-28 17:35:14 +00002723 rib_delnode (rn, same);
Vincent Bernatfed643f2012-10-23 16:00:42 +00002724 }
paul4d38fdb2005-04-28 17:35:14 +00002725
2726 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002727 return 0;
2728}
2729
hassoebf1ead2005-09-21 14:58:20 +00002730/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002731int
2732rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
G.Balajif768f362011-11-26 22:10:39 +04002733 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002734{
2735 struct route_table *table;
2736 struct route_node *rn;
2737 struct rib *rib;
2738 struct rib *fib = NULL;
2739 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002740 struct nexthop *nexthop, *tnexthop;
2741 int recursing;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002742 char buf1[INET6_ADDRSTRLEN];
2743 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002744
2745 /* Apply mask. */
2746 apply_mask_ipv6 (p);
2747
2748 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002749 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002750 if (! table)
2751 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002752
paul718e3742002-12-13 20:15:29 +00002753 /* Lookup route node. */
2754 rn = route_node_lookup (table, (struct prefix *) p);
2755 if (! rn)
2756 {
2757 if (IS_ZEBRA_DEBUG_KERNEL)
2758 {
2759 if (gate)
ajsb6178002004-12-07 21:12:56 +00002760 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002761 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002762 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002763 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002764 ifindex);
2765 else
ajsb6178002004-12-07 21:12:56 +00002766 zlog_debug ("route %s/%d 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,
2769 ifindex);
2770 }
2771 return ZEBRA_ERR_RTNOEXIST;
2772 }
2773
2774 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002775 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002776 {
Paul Jakma6d691122006-07-27 21:49:00 +00002777 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2778 continue;
2779
paul718e3742002-12-13 20:15:29 +00002780 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2781 fib = rib;
2782
hassoebf1ead2005-09-21 14:58:20 +00002783 if (rib->type != type)
2784 continue;
2785 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002786 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002787 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002788 if (nexthop->ifindex != ifindex)
2789 continue;
hassoebf1ead2005-09-21 14:58:20 +00002790 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002791 {
hassoebf1ead2005-09-21 14:58:20 +00002792 rib->refcnt--;
2793 route_unlock_node (rn);
2794 route_unlock_node (rn);
2795 return 0;
paul718e3742002-12-13 20:15:29 +00002796 }
hassoebf1ead2005-09-21 14:58:20 +00002797 same = rib;
2798 break;
paul718e3742002-12-13 20:15:29 +00002799 }
hassoebf1ead2005-09-21 14:58:20 +00002800 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002801 else
2802 {
2803 if (gate == NULL)
2804 {
2805 same = rib;
2806 break;
2807 }
2808 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2809 if (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate))
2810 {
2811 same = rib;
2812 break;
2813 }
2814 if (same)
2815 break;
2816 }
paul718e3742002-12-13 20:15:29 +00002817 }
2818
2819 /* If same type of route can't be found and this message is from
2820 kernel. */
2821 if (! same)
2822 {
2823 if (fib && type == ZEBRA_ROUTE_KERNEL)
2824 {
2825 /* Unset flags. */
2826 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2827 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2828
2829 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2830 }
2831 else
2832 {
2833 if (IS_ZEBRA_DEBUG_KERNEL)
2834 {
2835 if (gate)
ajsb6178002004-12-07 21:12:56 +00002836 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002837 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002838 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002839 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002840 ifindex,
2841 type);
2842 else
ajsb6178002004-12-07 21:12:56 +00002843 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002844 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002845 p->prefixlen,
2846 ifindex,
2847 type);
2848 }
2849 route_unlock_node (rn);
2850 return ZEBRA_ERR_RTNOEXIST;
2851 }
2852 }
2853
2854 if (same)
2855 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002856
paul718e3742002-12-13 20:15:29 +00002857 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002858 return 0;
2859}
2860
2861/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002862static void
paul718e3742002-12-13 20:15:29 +00002863static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2864{
2865 struct rib *rib;
2866 struct route_table *table;
2867 struct route_node *rn;
2868
2869 /* Lookup table. */
2870 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2871 if (! table)
2872 return;
2873
2874 /* Lookup existing route */
2875 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002876 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002877 {
2878 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2879 continue;
2880
2881 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2882 break;
2883 }
paul718e3742002-12-13 20:15:29 +00002884
2885 if (rib)
2886 {
2887 /* Same distance static route is there. Update it with new
2888 nexthop. */
paul718e3742002-12-13 20:15:29 +00002889 route_unlock_node (rn);
2890
2891 switch (si->type)
2892 {
2893 case STATIC_IPV6_GATEWAY:
2894 nexthop_ipv6_add (rib, &si->ipv6);
2895 break;
2896 case STATIC_IPV6_IFNAME:
2897 nexthop_ifname_add (rib, si->ifname);
2898 break;
2899 case STATIC_IPV6_GATEWAY_IFNAME:
2900 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2901 break;
2902 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002903 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002904 }
2905 else
2906 {
2907 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002908 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2909
paul718e3742002-12-13 20:15:29 +00002910 rib->type = ZEBRA_ROUTE_STATIC;
2911 rib->distance = si->distance;
2912 rib->metric = 0;
2913 rib->nexthop_num = 0;
2914
2915 switch (si->type)
2916 {
2917 case STATIC_IPV6_GATEWAY:
2918 nexthop_ipv6_add (rib, &si->ipv6);
2919 break;
2920 case STATIC_IPV6_IFNAME:
2921 nexthop_ifname_add (rib, si->ifname);
2922 break;
2923 case STATIC_IPV6_GATEWAY_IFNAME:
2924 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2925 break;
2926 }
2927
hasso81dfcaa2003-05-25 19:21:25 +00002928 /* Save the flags of this static routes (reject, blackhole) */
2929 rib->flags = si->flags;
2930
paul718e3742002-12-13 20:15:29 +00002931 /* Link this rib to the tree. */
2932 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002933 }
2934}
2935
paula1ac18c2005-06-28 17:17:12 +00002936static int
paul718e3742002-12-13 20:15:29 +00002937static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2938{
2939 if (nexthop->type == NEXTHOP_TYPE_IPV6
2940 && si->type == STATIC_IPV6_GATEWAY
2941 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2942 return 1;
2943 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2944 && si->type == STATIC_IPV6_IFNAME
2945 && strcmp (nexthop->ifname, si->ifname) == 0)
2946 return 1;
2947 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2948 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2949 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2950 && strcmp (nexthop->ifname, si->ifname) == 0)
2951 return 1;
paule8e19462006-01-19 20:16:55 +00002952 return 0;
paul718e3742002-12-13 20:15:29 +00002953}
2954
paula1ac18c2005-06-28 17:17:12 +00002955static void
paul718e3742002-12-13 20:15:29 +00002956static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2957{
2958 struct route_table *table;
2959 struct route_node *rn;
2960 struct rib *rib;
2961 struct nexthop *nexthop;
2962
2963 /* Lookup table. */
2964 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2965 if (! table)
2966 return;
2967
2968 /* Lookup existing route with type and distance. */
2969 rn = route_node_lookup (table, (struct prefix *) p);
2970 if (! rn)
2971 return;
2972
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002973 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002974 {
2975 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2976 continue;
2977
2978 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2979 break;
2980 }
2981
paul718e3742002-12-13 20:15:29 +00002982 if (! rib)
2983 {
2984 route_unlock_node (rn);
2985 return;
2986 }
2987
2988 /* Lookup nexthop. */
2989 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2990 if (static_ipv6_nexthop_same (nexthop, si))
2991 break;
2992
2993 /* Can't find nexthop. */
2994 if (! nexthop)
2995 {
2996 route_unlock_node (rn);
2997 return;
2998 }
2999
3000 /* Check nexthop. */
3001 if (rib->nexthop_num == 1)
3002 {
3003 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003004 }
3005 else
3006 {
paul6baeb982003-10-28 03:47:15 +00003007 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
3008 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00003009 nexthop_delete (rib, nexthop);
3010 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00003011 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003012 }
paul718e3742002-12-13 20:15:29 +00003013 /* Unlock node. */
3014 route_unlock_node (rn);
3015}
3016
3017/* Add static route into static route configuration. */
3018int
3019static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00003020 const char *ifname, u_char flags, u_char distance,
3021 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00003022{
3023 struct route_node *rn;
3024 struct static_ipv6 *si;
3025 struct static_ipv6 *pp;
3026 struct static_ipv6 *cp;
3027 struct route_table *stable;
3028
3029 /* Lookup table. */
3030 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
3031 if (! stable)
3032 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00003033
3034 if (!gate &&
3035 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
3036 return -1;
3037
3038 if (!ifname &&
3039 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
3040 return -1;
paul718e3742002-12-13 20:15:29 +00003041
3042 /* Lookup static route prefix. */
3043 rn = route_node_get (stable, p);
3044
3045 /* Do nothing if there is a same static route. */
3046 for (si = rn->info; si; si = si->next)
3047 {
3048 if (distance == si->distance
3049 && type == si->type
3050 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
3051 && (! ifname || strcmp (ifname, si->ifname) == 0))
3052 {
3053 route_unlock_node (rn);
3054 return 0;
3055 }
3056 }
3057
3058 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07003059 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
paul718e3742002-12-13 20:15:29 +00003060
3061 si->type = type;
3062 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00003063 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00003064
3065 switch (type)
3066 {
3067 case STATIC_IPV6_GATEWAY:
3068 si->ipv6 = *gate;
3069 break;
3070 case STATIC_IPV6_IFNAME:
3071 si->ifname = XSTRDUP (0, ifname);
3072 break;
3073 case STATIC_IPV6_GATEWAY_IFNAME:
3074 si->ipv6 = *gate;
3075 si->ifname = XSTRDUP (0, ifname);
3076 break;
3077 }
3078
3079 /* Add new static route information to the tree with sort by
3080 distance value and gateway address. */
3081 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
3082 {
3083 if (si->distance < cp->distance)
3084 break;
3085 if (si->distance > cp->distance)
3086 continue;
3087 }
3088
3089 /* Make linked list. */
3090 if (pp)
3091 pp->next = si;
3092 else
3093 rn->info = si;
3094 if (cp)
3095 cp->prev = si;
3096 si->prev = pp;
3097 si->next = cp;
3098
3099 /* Install into rib. */
3100 static_install_ipv6 (p, si);
3101
3102 return 1;
3103}
3104
3105/* Delete static route from static route configuration. */
3106int
3107static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00003108 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00003109{
3110 struct route_node *rn;
3111 struct static_ipv6 *si;
3112 struct route_table *stable;
3113
3114 /* Lookup table. */
3115 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
3116 if (! stable)
3117 return -1;
3118
3119 /* Lookup static route prefix. */
3120 rn = route_node_lookup (stable, p);
3121 if (! rn)
3122 return 0;
3123
3124 /* Find same static route is the tree */
3125 for (si = rn->info; si; si = si->next)
3126 if (distance == si->distance
3127 && type == si->type
3128 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
3129 && (! ifname || strcmp (ifname, si->ifname) == 0))
3130 break;
3131
3132 /* Can't find static route. */
3133 if (! si)
3134 {
3135 route_unlock_node (rn);
3136 return 0;
3137 }
3138
3139 /* Install into rib. */
3140 static_uninstall_ipv6 (p, si);
3141
3142 /* Unlink static route from linked list. */
3143 if (si->prev)
3144 si->prev->next = si->next;
3145 else
3146 rn->info = si->next;
3147 if (si->next)
3148 si->next->prev = si->prev;
3149
3150 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00003151 if (ifname)
3152 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00003153 XFREE (MTYPE_STATIC_IPV6, si);
3154
3155 return 1;
3156}
3157#endif /* HAVE_IPV6 */
3158
3159/* RIB update function. */
3160void
paula1ac18c2005-06-28 17:17:12 +00003161rib_update (void)
paul718e3742002-12-13 20:15:29 +00003162{
3163 struct route_node *rn;
3164 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00003165
paul718e3742002-12-13 20:15:29 +00003166 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
3167 if (table)
3168 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003169 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003170 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003171
3172 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
3173 if (table)
3174 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003175 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003176 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003177}
3178
paul718e3742002-12-13 20:15:29 +00003179
3180/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00003181static void
paul718e3742002-12-13 20:15:29 +00003182rib_weed_table (struct route_table *table)
3183{
3184 struct route_node *rn;
3185 struct rib *rib;
3186 struct rib *next;
3187
3188 if (table)
3189 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003190 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003191 {
Paul Jakma6d691122006-07-27 21:49:00 +00003192 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3193 continue;
3194
paulb21b19c2003-06-15 01:28:29 +00003195 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00003196 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00003197 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003198 }
3199}
3200
3201/* Delete all routes from non main table. */
3202void
paula1ac18c2005-06-28 17:17:12 +00003203rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00003204{
3205 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3206 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3207}
3208
3209/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00003210static void
paul718e3742002-12-13 20:15:29 +00003211rib_sweep_table (struct route_table *table)
3212{
3213 struct route_node *rn;
3214 struct rib *rib;
3215 struct rib *next;
3216 int ret = 0;
3217
3218 if (table)
3219 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003220 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003221 {
Paul Jakma6d691122006-07-27 21:49:00 +00003222 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3223 continue;
3224
paul718e3742002-12-13 20:15:29 +00003225 if (rib->type == ZEBRA_ROUTE_KERNEL &&
3226 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
3227 {
3228 ret = rib_uninstall_kernel (rn, rib);
3229 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00003230 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003231 }
3232 }
3233}
3234
3235/* Sweep all RIB tables. */
3236void
paula1ac18c2005-06-28 17:17:12 +00003237rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00003238{
3239 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3240 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3241}
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003242
3243/* Remove specific by protocol routes from 'table'. */
3244static unsigned long
3245rib_score_proto_table (u_char proto, struct route_table *table)
3246{
3247 struct route_node *rn;
3248 struct rib *rib;
3249 struct rib *next;
3250 unsigned long n = 0;
3251
3252 if (table)
3253 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003254 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003255 {
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003256 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3257 continue;
3258 if (rib->type == proto)
3259 {
3260 rib_delnode (rn, rib);
3261 n++;
3262 }
3263 }
3264
3265 return n;
3266}
3267
3268/* Remove specific by protocol routes. */
3269unsigned long
3270rib_score_proto (u_char proto)
3271{
3272 return rib_score_proto_table (proto, vrf_table (AFI_IP, SAFI_UNICAST, 0))
3273 +rib_score_proto_table (proto, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3274}
3275
paul718e3742002-12-13 20:15:29 +00003276/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00003277static void
paul718e3742002-12-13 20:15:29 +00003278rib_close_table (struct route_table *table)
3279{
3280 struct route_node *rn;
3281 struct rib *rib;
3282
3283 if (table)
3284 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003285 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00003286 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003287 if (!CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
3288 continue;
3289
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00003290 zfpm_trigger_update (rn, NULL);
3291
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003292 if (! RIB_SYSTEM_ROUTE (rib))
3293 rib_uninstall_kernel (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00003294 }
paul718e3742002-12-13 20:15:29 +00003295}
3296
3297/* Close all RIB tables. */
3298void
paula1ac18c2005-06-28 17:17:12 +00003299rib_close (void)
paul718e3742002-12-13 20:15:29 +00003300{
3301 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3302 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3303}
3304
3305/* Routing information base initialize. */
3306void
paula1ac18c2005-06-28 17:17:12 +00003307rib_init (void)
paul718e3742002-12-13 20:15:29 +00003308{
paul4d38fdb2005-04-28 17:35:14 +00003309 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00003310 /* VRF initialization. */
3311 vrf_init ();
3312}
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003313
3314/*
3315 * vrf_id_get_next
3316 *
3317 * Get the first vrf id that is greater than the given vrf id if any.
3318 *
3319 * Returns TRUE if a vrf id was found, FALSE otherwise.
3320 */
3321static inline int
3322vrf_id_get_next (uint32_t id, uint32_t *next_id_p)
3323{
3324 while (++id < vector_active (vrf_vector))
3325 {
3326 if (vrf_lookup (id))
3327 {
3328 *next_id_p = id;
3329 return 1;
3330 }
3331 }
3332
3333 return 0;
3334}
3335
3336/*
3337 * rib_tables_iter_next
3338 *
3339 * Returns the next table in the iteration.
3340 */
3341struct route_table *
3342rib_tables_iter_next (rib_tables_iter_t *iter)
3343{
3344 struct route_table *table;
3345
3346 /*
3347 * Array that helps us go over all AFI/SAFI combinations via one
3348 * index.
3349 */
3350 static struct {
3351 afi_t afi;
3352 safi_t safi;
3353 } afi_safis[] = {
3354 { AFI_IP, SAFI_UNICAST },
3355 { AFI_IP, SAFI_MULTICAST },
3356 { AFI_IP6, SAFI_UNICAST },
3357 { AFI_IP6, SAFI_MULTICAST },
3358 };
3359
3360 table = NULL;
3361
3362 switch (iter->state)
3363 {
3364
3365 case RIB_TABLES_ITER_S_INIT:
3366 iter->vrf_id = 0;
3367 iter->afi_safi_ix = -1;
3368
3369 /* Fall through */
3370
3371 case RIB_TABLES_ITER_S_ITERATING:
3372 iter->afi_safi_ix++;
3373 while (1)
3374 {
3375
3376 while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
3377 {
3378 table = vrf_table (afi_safis[iter->afi_safi_ix].afi,
3379 afi_safis[iter->afi_safi_ix].safi,
3380 iter->vrf_id);
3381 if (table)
3382 break;
3383
3384 iter->afi_safi_ix++;
3385 }
3386
3387 /*
3388 * Found another table in this vrf.
3389 */
3390 if (table)
3391 break;
3392
3393 /*
3394 * Done with all tables in the current vrf, go to the next
3395 * one.
3396 */
3397 if (!vrf_id_get_next (iter->vrf_id, &iter->vrf_id))
3398 break;
3399
3400 iter->afi_safi_ix = 0;
3401 }
3402
3403 break;
3404
3405 case RIB_TABLES_ITER_S_DONE:
3406 return NULL;
3407 }
3408
3409 if (table)
3410 iter->state = RIB_TABLES_ITER_S_ITERATING;
3411 else
3412 iter->state = RIB_TABLES_ITER_S_DONE;
3413
3414 return table;
3415}