blob: 3106523d03026ebba4c0aa946e95668f20baff8c [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{
953 struct interface *ifp;
Paul Jakma7514fb72007-05-02 16:05:35 +0000954 route_map_result_t ret = RMAP_MATCH;
955 extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
956 struct route_map *rmap;
957 int family;
paul718e3742002-12-13 20:15:29 +0000958
Paul Jakma7514fb72007-05-02 16:05:35 +0000959 family = 0;
paul718e3742002-12-13 20:15:29 +0000960 switch (nexthop->type)
961 {
962 case NEXTHOP_TYPE_IFINDEX:
963 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000964 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000965 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
966 else
967 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
968 break;
paul718e3742002-12-13 20:15:29 +0000969 case NEXTHOP_TYPE_IPV6_IFNAME:
Paul Jakma7514fb72007-05-02 16:05:35 +0000970 family = AFI_IP6;
971 case NEXTHOP_TYPE_IFNAME:
paul718e3742002-12-13 20:15:29 +0000972 ifp = if_lookup_by_name (nexthop->ifname);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000973 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000974 {
975 if (set)
976 nexthop->ifindex = ifp->ifindex;
977 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
978 }
979 else
980 {
981 if (set)
982 nexthop->ifindex = 0;
983 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
984 }
985 break;
986 case NEXTHOP_TYPE_IPV4:
987 case NEXTHOP_TYPE_IPV4_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000988 family = AFI_IP;
paul718e3742002-12-13 20:15:29 +0000989 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
990 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
991 else
992 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
993 break;
994#ifdef HAVE_IPV6
995 case NEXTHOP_TYPE_IPV6:
Paul Jakma7514fb72007-05-02 16:05:35 +0000996 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000997 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
998 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
999 else
1000 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1001 break;
1002 case NEXTHOP_TYPE_IPV6_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +00001003 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +00001004 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
1005 {
1006 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +00001007 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001008 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1009 else
1010 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1011 }
1012 else
1013 {
1014 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
1015 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1016 else
1017 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1018 }
1019 break;
1020#endif /* HAVE_IPV6 */
paul595db7f2003-05-25 21:35:06 +00001021 case NEXTHOP_TYPE_BLACKHOLE:
1022 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1023 break;
paul718e3742002-12-13 20:15:29 +00001024 default:
1025 break;
1026 }
Paul Jakma7514fb72007-05-02 16:05:35 +00001027 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1028 return 0;
1029
1030 if (RIB_SYSTEM_ROUTE(rib) ||
1031 (family == AFI_IP && rn->p.family != AF_INET) ||
1032 (family == AFI_IP6 && rn->p.family != AF_INET6))
1033 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1034
1035 rmap = 0;
1036 if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
1037 proto_rm[family][rib->type])
1038 rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
1039 if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
1040 rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
1041 if (rmap) {
1042 ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, nexthop);
1043 }
1044
1045 if (ret == RMAP_DENYMATCH)
1046 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
paul718e3742002-12-13 20:15:29 +00001047 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1048}
1049
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001050/* Iterate over all nexthops of the given RIB entry and refresh their
1051 * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
1052 * nexthop is found to toggle the ACTIVE flag, the whole rib structure
1053 * is flagged with ZEBRA_FLAG_CHANGED. The 4th 'set' argument is
1054 * transparently passed to nexthop_active_check().
1055 *
1056 * Return value is the new number of active nexthops.
1057 */
1058
paula1ac18c2005-06-28 17:17:12 +00001059static int
paul718e3742002-12-13 20:15:29 +00001060nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
1061{
1062 struct nexthop *nexthop;
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001063 unsigned int prev_active, prev_index, new_active;
paul718e3742002-12-13 20:15:29 +00001064
1065 rib->nexthop_active_num = 0;
1066 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1067
1068 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001069 {
1070 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001071 prev_index = nexthop->ifindex;
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001072 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
1073 rib->nexthop_active_num++;
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001074 if (prev_active != new_active ||
1075 prev_index != nexthop->ifindex)
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001076 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1077 }
paul718e3742002-12-13 20:15:29 +00001078 return rib->nexthop_active_num;
1079}
paul6baeb982003-10-28 03:47:15 +00001080
paul718e3742002-12-13 20:15:29 +00001081
paul718e3742002-12-13 20:15:29 +00001082
paula1ac18c2005-06-28 17:17:12 +00001083static void
paul718e3742002-12-13 20:15:29 +00001084rib_install_kernel (struct route_node *rn, struct rib *rib)
1085{
1086 int ret = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001087 struct nexthop *nexthop, *tnexthop;
1088 int recursing;
paul718e3742002-12-13 20:15:29 +00001089
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001090 /*
1091 * Make sure we update the FPM any time we send new information to
1092 * the kernel.
1093 */
1094 zfpm_trigger_update (rn, "installing in kernel");
paul718e3742002-12-13 20:15:29 +00001095 switch (PREFIX_FAMILY (&rn->p))
1096 {
1097 case AF_INET:
1098 ret = kernel_add_ipv4 (&rn->p, rib);
1099 break;
1100#ifdef HAVE_IPV6
1101 case AF_INET6:
1102 ret = kernel_add_ipv6 (&rn->p, rib);
1103 break;
1104#endif /* HAVE_IPV6 */
1105 }
1106
Denis Ovsienkodc958242007-08-13 16:03:06 +00001107 /* This condition is never met, if we are using rt_socket.c */
paul718e3742002-12-13 20:15:29 +00001108 if (ret < 0)
1109 {
Christian Frankefa713d92013-07-05 15:35:37 +00001110 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +00001111 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1112 }
1113}
1114
1115/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001116static int
paul718e3742002-12-13 20:15:29 +00001117rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
1118{
1119 int ret = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001120 struct nexthop *nexthop, *tnexthop;
1121 int recursing;
paul718e3742002-12-13 20:15:29 +00001122
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001123 /*
1124 * Make sure we update the FPM any time we send new information to
1125 * the kernel.
1126 */
1127 zfpm_trigger_update (rn, "uninstalling from kernel");
1128
paul718e3742002-12-13 20:15:29 +00001129 switch (PREFIX_FAMILY (&rn->p))
1130 {
1131 case AF_INET:
1132 ret = kernel_delete_ipv4 (&rn->p, rib);
1133 break;
1134#ifdef HAVE_IPV6
1135 case AF_INET6:
1136 ret = kernel_delete_ipv6 (&rn->p, rib);
1137 break;
1138#endif /* HAVE_IPV6 */
1139 }
1140
Christian Frankefa713d92013-07-05 15:35:37 +00001141 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +00001142 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1143
1144 return ret;
1145}
1146
1147/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001148static void
paul718e3742002-12-13 20:15:29 +00001149rib_uninstall (struct route_node *rn, struct rib *rib)
1150{
1151 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1152 {
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001153 zfpm_trigger_update (rn, "rib_uninstall");
1154
paul718e3742002-12-13 20:15:29 +00001155 redistribute_delete (&rn->p, rib);
1156 if (! RIB_SYSTEM_ROUTE (rib))
1157 rib_uninstall_kernel (rn, rib);
1158 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
1159 }
1160}
1161
Paul Jakma6d691122006-07-27 21:49:00 +00001162static void rib_unlink (struct route_node *, struct rib *);
1163
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001164/*
1165 * rib_can_delete_dest
1166 *
1167 * Returns TRUE if the given dest can be deleted from the table.
1168 */
1169static int
1170rib_can_delete_dest (rib_dest_t *dest)
1171{
1172 if (dest->routes)
1173 {
1174 return 0;
1175 }
1176
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001177 /*
1178 * Don't delete the dest if we have to update the FPM about this
1179 * prefix.
1180 */
1181 if (CHECK_FLAG (dest->flags, RIB_DEST_UPDATE_FPM) ||
1182 CHECK_FLAG (dest->flags, RIB_DEST_SENT_TO_FPM))
1183 return 0;
1184
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001185 return 1;
1186}
1187
1188/*
1189 * rib_gc_dest
1190 *
1191 * Garbage collect the rib dest corresponding to the given route node
1192 * if appropriate.
1193 *
1194 * Returns TRUE if the dest was deleted, FALSE otherwise.
1195 */
1196int
1197rib_gc_dest (struct route_node *rn)
1198{
1199 rib_dest_t *dest;
1200 char buf[INET6_ADDRSTRLEN];
1201
1202 dest = rib_dest_from_rnode (rn);
1203 if (!dest)
1204 return 0;
1205
1206 if (!rib_can_delete_dest (dest))
1207 return 0;
1208
1209 if (IS_ZEBRA_DEBUG_RIB)
1210 {
1211 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, sizeof (buf));
1212 zlog_debug ("%s: %s/%d: removing dest from table", __func__,
1213 buf, rn->p.prefixlen);
1214 }
1215
1216 dest->rnode = NULL;
1217 XFREE (MTYPE_RIB_DEST, dest);
1218 rn->info = NULL;
1219
1220 /*
1221 * Release the one reference that we keep on the route node.
1222 */
1223 route_unlock_node (rn);
1224 return 1;
1225}
1226
paul718e3742002-12-13 20:15:29 +00001227/* Core function for processing routing information base. */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001228static void
1229rib_process (struct route_node *rn)
paul718e3742002-12-13 20:15:29 +00001230{
1231 struct rib *rib;
1232 struct rib *next;
1233 struct rib *fib = NULL;
1234 struct rib *select = NULL;
Paul Jakma6d691122006-07-27 21:49:00 +00001235 struct rib *del = NULL;
pauld753e9e2003-01-22 19:45:50 +00001236 int installed = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001237 struct nexthop *nexthop = NULL, *tnexthop;
1238 int recursing;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001239 char buf[INET6_ADDRSTRLEN];
paul4d38fdb2005-04-28 17:35:14 +00001240
1241 assert (rn);
1242
Paul Jakma93bdada2007-08-06 19:25:11 +00001243 if (IS_ZEBRA_DEBUG_RIB || IS_ZEBRA_DEBUG_RIB_Q)
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001244 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001245
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001246 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00001247 {
paul718e3742002-12-13 20:15:29 +00001248 /* Currently installed rib. */
1249 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Paul Jakma6d691122006-07-27 21:49:00 +00001250 {
1251 assert (fib == NULL);
1252 fib = rib;
1253 }
1254
1255 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1256 * which we need to do do further work with below.
1257 */
1258 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1259 {
1260 if (rib != fib)
1261 {
1262 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001263 zlog_debug ("%s: %s/%d: rn %p, removing rib %p", __func__,
1264 buf, rn->p.prefixlen, rn, rib);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001265 rib_unlink (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001266 }
1267 else
1268 del = rib;
1269
1270 continue;
1271 }
paul4d38fdb2005-04-28 17:35:14 +00001272
paul718e3742002-12-13 20:15:29 +00001273 /* Skip unreachable nexthop. */
1274 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +00001275 continue;
paul718e3742002-12-13 20:15:29 +00001276
1277 /* Infinit distance. */
1278 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +00001279 continue;
paul718e3742002-12-13 20:15:29 +00001280
paulaf887b52006-01-18 14:52:52 +00001281 /* Newly selected rib, the common case. */
1282 if (!select)
1283 {
1284 select = rib;
1285 continue;
1286 }
1287
1288 /* filter route selection in following order:
paulaf887b52006-01-18 14:52:52 +00001289 * - connected beats other types
paula8d9c1f2006-01-25 06:31:04 +00001290 * - lower distance beats higher
paulaf887b52006-01-18 14:52:52 +00001291 * - lower metric beats higher for equal distance
1292 * - last, hence oldest, route wins tie break.
1293 */
paula1038a12006-01-30 14:08:51 +00001294
1295 /* Connected routes. Pick the last connected
1296 * route of the set of lowest metric connected routes.
1297 */
paula8d9c1f2006-01-25 06:31:04 +00001298 if (rib->type == ZEBRA_ROUTE_CONNECT)
1299 {
paula1038a12006-01-30 14:08:51 +00001300 if (select->type != ZEBRA_ROUTE_CONNECT
paula8d9c1f2006-01-25 06:31:04 +00001301 || rib->metric <= select->metric)
paula1038a12006-01-30 14:08:51 +00001302 select = rib;
1303 continue;
paula8d9c1f2006-01-25 06:31:04 +00001304 }
1305 else if (select->type == ZEBRA_ROUTE_CONNECT)
1306 continue;
1307
1308 /* higher distance loses */
1309 if (rib->distance > select->distance)
1310 continue;
1311
1312 /* lower wins */
1313 if (rib->distance < select->distance)
1314 {
paulaf887b52006-01-18 14:52:52 +00001315 select = rib;
paula8d9c1f2006-01-25 06:31:04 +00001316 continue;
1317 }
1318
1319 /* metric tie-breaks equal distance */
1320 if (rib->metric <= select->metric)
1321 select = rib;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001322 } /* RNODE_FOREACH_RIB_SAFE */
Denis Ovsienkodc958242007-08-13 16:03:06 +00001323
1324 /* After the cycle is finished, the following pointers will be set:
1325 * select --- the winner RIB entry, if any was found, otherwise NULL
1326 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1327 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1328 * rib --- NULL
1329 */
1330
1331 /* Same RIB entry is selected. Update FIB and finish. */
paul718e3742002-12-13 20:15:29 +00001332 if (select && select == fib)
1333 {
Paul Jakma6d691122006-07-27 21:49:00 +00001334 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001335 zlog_debug ("%s: %s/%d: Updating existing route, select %p, fib %p",
1336 __func__, buf, rn->p.prefixlen, select, fib);
paul718e3742002-12-13 20:15:29 +00001337 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +00001338 {
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001339 zfpm_trigger_update (rn, "updating existing route");
1340
paul4d38fdb2005-04-28 17:35:14 +00001341 redistribute_delete (&rn->p, select);
1342 if (! RIB_SYSTEM_ROUTE (select))
1343 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001344
paul4d38fdb2005-04-28 17:35:14 +00001345 /* Set real nexthop. */
1346 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +00001347
paul4d38fdb2005-04-28 17:35:14 +00001348 if (! RIB_SYSTEM_ROUTE (select))
1349 rib_install_kernel (rn, select);
1350 redistribute_add (&rn->p, select);
1351 }
pauld753e9e2003-01-22 19:45:50 +00001352 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001353 {
1354 /* Housekeeping code to deal with
1355 race conditions in kernel with linux
1356 netlink reporting interface up before IPv4 or IPv6 protocol
1357 is ready to add routes.
1358 This makes sure the routes are IN the kernel.
1359 */
pauld753e9e2003-01-22 19:45:50 +00001360
Christian Frankefa713d92013-07-05 15:35:37 +00001361 for (ALL_NEXTHOPS_RO(select->nexthop, nexthop, tnexthop, recursing))
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001362 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
paul4d38fdb2005-04-28 17:35:14 +00001363 {
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001364 installed = 1;
1365 break;
paul4d38fdb2005-04-28 17:35:14 +00001366 }
1367 if (! installed)
1368 rib_install_kernel (rn, select);
1369 }
Paul Jakma6d691122006-07-27 21:49:00 +00001370 goto end;
paul718e3742002-12-13 20:15:29 +00001371 }
1372
Denis Ovsienkodc958242007-08-13 16:03:06 +00001373 /* At this point we either haven't found the best RIB entry or it is
1374 * different from what we currently intend to flag with SELECTED. In both
1375 * cases, if a RIB block is present in FIB, it should be withdrawn.
1376 */
paul718e3742002-12-13 20:15:29 +00001377 if (fib)
1378 {
Paul Jakma6d691122006-07-27 21:49:00 +00001379 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001380 zlog_debug ("%s: %s/%d: Removing existing route, fib %p", __func__,
1381 buf, rn->p.prefixlen, fib);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001382
1383 zfpm_trigger_update (rn, "removing existing route");
1384
paul718e3742002-12-13 20:15:29 +00001385 redistribute_delete (&rn->p, fib);
1386 if (! RIB_SYSTEM_ROUTE (fib))
1387 rib_uninstall_kernel (rn, fib);
1388 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1389
1390 /* Set real nexthop. */
1391 nexthop_active_update (rn, fib, 1);
1392 }
1393
Denis Ovsienkodc958242007-08-13 16:03:06 +00001394 /* Regardless of some RIB entry being SELECTED or not before, now we can
1395 * tell, that if a new winner exists, FIB is still not updated with this
1396 * data, but ready to be.
1397 */
paul718e3742002-12-13 20:15:29 +00001398 if (select)
1399 {
Paul Jakma6d691122006-07-27 21:49:00 +00001400 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001401 zlog_debug ("%s: %s/%d: Adding route, select %p", __func__, buf,
1402 rn->p.prefixlen, select);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001403
1404 zfpm_trigger_update (rn, "new route selected");
1405
paul718e3742002-12-13 20:15:29 +00001406 /* Set real nexthop. */
1407 nexthop_active_update (rn, select, 1);
1408
1409 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001410 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001411 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1412 redistribute_add (&rn->p, select);
1413 }
paul4d38fdb2005-04-28 17:35:14 +00001414
Paul Jakma6d691122006-07-27 21:49:00 +00001415 /* FIB route was removed, should be deleted */
1416 if (del)
1417 {
1418 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001419 zlog_debug ("%s: %s/%d: Deleting fib %p, rn %p", __func__, buf,
1420 rn->p.prefixlen, del, rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001421 rib_unlink (rn, del);
1422 }
paul4d38fdb2005-04-28 17:35:14 +00001423
Paul Jakma6d691122006-07-27 21:49:00 +00001424end:
1425 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma93bdada2007-08-06 19:25:11 +00001426 zlog_debug ("%s: %s/%d: rn %p dequeued", __func__, buf, rn->p.prefixlen, rn);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001427
1428 /*
1429 * Check if the dest can be deleted now.
1430 */
1431 rib_gc_dest (rn);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001432}
1433
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001434/* Take a list of route_node structs and return 1, if there was a record
1435 * picked from it and processed by rib_process(). Don't process more,
1436 * than one RN record; operate only in the specified sub-queue.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001437 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001438static unsigned int
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001439process_subq (struct list * subq, u_char qindex)
1440{
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001441 struct listnode *lnode = listhead (subq);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001442 struct route_node *rnode;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001443
1444 if (!lnode)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001445 return 0;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001446
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001447 rnode = listgetdata (lnode);
1448 rib_process (rnode);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001449
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001450 if (rnode->info)
1451 UNSET_FLAG (rib_dest_from_rnode (rnode)->flags, RIB_ROUTE_QUEUED (qindex));
1452
Chris Caputo67b94672009-07-18 04:02:26 +00001453#if 0
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001454 else
1455 {
1456 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1457 __func__, rnode, rnode->lock);
1458 zlog_backtrace(LOG_DEBUG);
1459 }
Chris Caputo67b94672009-07-18 04:02:26 +00001460#endif
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001461 route_unlock_node (rnode);
1462 list_delete_node (subq, lnode);
1463 return 1;
1464}
1465
1466/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1467 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1468 * is pointed to the meta queue structure.
1469 */
1470static wq_item_status
1471meta_queue_process (struct work_queue *dummy, void *data)
1472{
1473 struct meta_queue * mq = data;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001474 unsigned i;
1475
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001476 for (i = 0; i < MQ_SIZE; i++)
1477 if (process_subq (mq->subq[i], i))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001478 {
1479 mq->size--;
1480 break;
1481 }
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001482 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1483}
1484
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001485/*
1486 * Map from rib types to queue type (priority) in meta queue
1487 */
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001488static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
1489 [ZEBRA_ROUTE_SYSTEM] = 4,
1490 [ZEBRA_ROUTE_KERNEL] = 0,
1491 [ZEBRA_ROUTE_CONNECT] = 0,
1492 [ZEBRA_ROUTE_STATIC] = 1,
1493 [ZEBRA_ROUTE_RIP] = 2,
1494 [ZEBRA_ROUTE_RIPNG] = 2,
1495 [ZEBRA_ROUTE_OSPF] = 2,
1496 [ZEBRA_ROUTE_OSPF6] = 2,
1497 [ZEBRA_ROUTE_ISIS] = 2,
1498 [ZEBRA_ROUTE_BGP] = 3,
1499 [ZEBRA_ROUTE_HSLS] = 4,
Paul Jakma57345092011-12-25 17:52:09 +01001500 [ZEBRA_ROUTE_BABEL] = 2,
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001501};
1502
1503/* Look into the RN and queue it into one or more priority queues,
1504 * increasing the size for each data push done.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001505 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001506static void
1507rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001508{
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001509 struct rib *rib;
1510 char buf[INET6_ADDRSTRLEN];
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001511
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001512 if (IS_ZEBRA_DEBUG_RIB_Q)
1513 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001514
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001515 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001516 {
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001517 u_char qindex = meta_queue_map[rib->type];
1518
1519 /* Invariant: at this point we always have rn->info set. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001520 if (CHECK_FLAG (rib_dest_from_rnode (rn)->flags,
1521 RIB_ROUTE_QUEUED (qindex)))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001522 {
1523 if (IS_ZEBRA_DEBUG_RIB_Q)
1524 zlog_debug ("%s: %s/%d: rn %p is already queued in sub-queue %u",
1525 __func__, buf, rn->p.prefixlen, rn, qindex);
1526 continue;
1527 }
1528
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001529 SET_FLAG (rib_dest_from_rnode (rn)->flags, RIB_ROUTE_QUEUED (qindex));
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001530 listnode_add (mq->subq[qindex], rn);
1531 route_lock_node (rn);
1532 mq->size++;
1533
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001534 if (IS_ZEBRA_DEBUG_RIB_Q)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001535 zlog_debug ("%s: %s/%d: queued rn %p into sub-queue %u",
1536 __func__, buf, rn->p.prefixlen, rn, qindex);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001537 }
paul4d38fdb2005-04-28 17:35:14 +00001538}
1539
Paul Jakma6d691122006-07-27 21:49:00 +00001540/* Add route_node to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001541static void
Paul Jakma6d691122006-07-27 21:49:00 +00001542rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
paul4d38fdb2005-04-28 17:35:14 +00001543{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001544 char buf[INET_ADDRSTRLEN];
1545 assert (zebra && rn);
paul4d38fdb2005-04-28 17:35:14 +00001546
Paul Jakma93bdada2007-08-06 19:25:11 +00001547 if (IS_ZEBRA_DEBUG_RIB_Q)
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001548 inet_ntop (AF_INET, &rn->p.u.prefix, buf, INET_ADDRSTRLEN);
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001549
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001550 /* Pointless to queue a route_node with no RIB entries to add or remove */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001551 if (!rnode_to_ribs (rn))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001552 {
1553 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1554 __func__, rn, rn->lock);
1555 zlog_backtrace(LOG_DEBUG);
1556 return;
1557 }
1558
1559 if (IS_ZEBRA_DEBUG_RIB_Q)
1560 zlog_info ("%s: %s/%d: work queue added", __func__, buf, rn->p.prefixlen);
1561
1562 assert (zebra);
1563
1564 if (zebra->ribq == NULL)
1565 {
1566 zlog_err ("%s: work_queue does not exist!", __func__);
1567 return;
Paul Jakma6d691122006-07-27 21:49:00 +00001568 }
paul4d38fdb2005-04-28 17:35:14 +00001569
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001570 /*
1571 * The RIB queue should normally be either empty or holding the only
1572 * work_queue_item element. In the latter case this element would
1573 * hold a pointer to the meta queue structure, which must be used to
1574 * actually queue the route nodes to process. So create the MQ
1575 * holder, if necessary, then push the work into it in any case.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001576 * This semantics was introduced after 0.99.9 release.
1577 */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001578 if (!zebra->ribq->items->count)
1579 work_queue_add (zebra->ribq, zebra->mq);
1580
1581 rib_meta_queue_add (zebra->mq, rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001582
1583 if (IS_ZEBRA_DEBUG_RIB_Q)
1584 zlog_debug ("%s: %s/%d: rn %p queued", __func__, buf, rn->p.prefixlen, rn);
1585
1586 return;
paul4d38fdb2005-04-28 17:35:14 +00001587}
1588
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001589/* Create new meta queue.
1590 A destructor function doesn't seem to be necessary here.
1591 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001592static struct meta_queue *
1593meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001594{
1595 struct meta_queue *new;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001596 unsigned i;
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001597
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001598 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1599 assert(new);
1600
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001601 for (i = 0; i < MQ_SIZE; i++)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001602 {
1603 new->subq[i] = list_new ();
1604 assert(new->subq[i]);
1605 }
1606
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001607 return new;
1608}
1609
paul4d38fdb2005-04-28 17:35:14 +00001610/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001611static void
paul4d38fdb2005-04-28 17:35:14 +00001612rib_queue_init (struct zebra_t *zebra)
1613{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001614 assert (zebra);
1615
paul4d38fdb2005-04-28 17:35:14 +00001616 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001617 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001618 {
Paul Jakma6d691122006-07-27 21:49:00 +00001619 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001620 return;
1621 }
1622
1623 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001624 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001625 zebra->ribq->spec.errorfunc = NULL;
paul4d38fdb2005-04-28 17:35:14 +00001626 /* XXX: TODO: These should be runtime configurable via vty */
1627 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001628 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001629
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001630 if (!(zebra->mq = meta_queue_new ()))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001631 {
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001632 zlog_err ("%s: could not initialise meta queue!", __func__);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001633 return;
1634 }
1635 return;
paul718e3742002-12-13 20:15:29 +00001636}
1637
Paul Jakma6d691122006-07-27 21:49:00 +00001638/* RIB updates are processed via a queue of pointers to route_nodes.
1639 *
1640 * The queue length is bounded by the maximal size of the routing table,
1641 * as a route_node will not be requeued, if already queued.
1642 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001643 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1644 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1645 * and then submit route_node to queue for best-path selection later.
1646 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001647 *
1648 * Deleted RIBs are reaped during best-path selection.
1649 *
1650 * rib_addnode
1651 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001652 * |-------->| | best RIB, if required
1653 * | |
1654 * static_install->|->rib_addqueue...... -> rib_process
1655 * | |
1656 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001657 * |-> set RIB_ENTRY_REMOVE |
1658 * rib_delnode (RIB freed)
1659 *
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001660 * The 'info' pointer of a route_node points to a rib_dest_t
1661 * ('dest'). Queueing state for a route_node is kept on the dest. The
1662 * dest is created on-demand by rib_link() and is kept around at least
1663 * as long as there are ribs hanging off it (@see rib_gc_dest()).
Paul Jakma6d691122006-07-27 21:49:00 +00001664 *
1665 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1666 *
1667 * - route_nodes: refcounted by:
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001668 * - dest attached to route_node:
1669 * - managed by: rib_link/rib_gc_dest
Paul Jakma6d691122006-07-27 21:49:00 +00001670 * - route_node processing queue
1671 * - managed by: rib_addqueue, rib_process.
1672 *
1673 */
1674
paul718e3742002-12-13 20:15:29 +00001675/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001676static void
Paul Jakma6d691122006-07-27 21:49:00 +00001677rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001678{
1679 struct rib *head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001680 rib_dest_t *dest;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001681 char buf[INET6_ADDRSTRLEN];
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001682
paul4d38fdb2005-04-28 17:35:14 +00001683 assert (rib && rn);
1684
Paul Jakma6d691122006-07-27 21:49:00 +00001685 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001686 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001687 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001688 zlog_debug ("%s: %s/%d: rn %p, rib %p", __func__,
1689 buf, rn->p.prefixlen, rn, rib);
1690 }
Paul Jakma6d691122006-07-27 21:49:00 +00001691
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001692 dest = rib_dest_from_rnode (rn);
1693 if (!dest)
Paul Jakma6d691122006-07-27 21:49:00 +00001694 {
1695 if (IS_ZEBRA_DEBUG_RIB)
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001696 {
1697 zlog_debug ("%s: %s/%d: adding dest to table", __func__,
1698 buf, rn->p.prefixlen);
1699 }
1700
1701 dest = XCALLOC (MTYPE_RIB_DEST, sizeof (rib_dest_t));
1702 route_lock_node (rn); /* rn route table reference */
1703 rn->info = dest;
1704 dest->rnode = rn;
1705 }
1706
1707 head = dest->routes;
1708 if (head)
1709 {
Paul Jakma6d691122006-07-27 21:49:00 +00001710 head->prev = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001711 }
paul718e3742002-12-13 20:15:29 +00001712 rib->next = head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001713 dest->routes = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001714 rib_queue_add (&zebrad, rn);
1715}
1716
1717static void
1718rib_addnode (struct route_node *rn, struct rib *rib)
1719{
1720 /* RIB node has been un-removed before route-node is processed.
1721 * route_node must hence already be on the queue for processing..
1722 */
1723 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1724 {
1725 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001726 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001727 char buf[INET6_ADDRSTRLEN];
1728 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001729 zlog_debug ("%s: %s/%d: rn %p, un-removed rib %p",
1730 __func__, buf, rn->p.prefixlen, rn, rib);
1731 }
Paul Jakma6d691122006-07-27 21:49:00 +00001732 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1733 return;
1734 }
1735 rib_link (rn, rib);
1736}
1737
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001738/*
1739 * rib_unlink
1740 *
1741 * Detach a rib structure from a route_node.
1742 *
1743 * Note that a call to rib_unlink() should be followed by a call to
1744 * rib_gc_dest() at some point. This allows a rib_dest_t that is no
1745 * longer required to be deleted.
1746 */
Paul Jakma6d691122006-07-27 21:49:00 +00001747static void
1748rib_unlink (struct route_node *rn, struct rib *rib)
1749{
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001750 char buf[INET6_ADDRSTRLEN];
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001751 rib_dest_t *dest;
Paul Jakma6d691122006-07-27 21:49:00 +00001752
1753 assert (rn && rib);
1754
1755 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001756 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001757 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001758 zlog_debug ("%s: %s/%d: rn %p, rib %p",
1759 __func__, buf, rn->p.prefixlen, rn, rib);
1760 }
Paul Jakma6d691122006-07-27 21:49:00 +00001761
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001762 dest = rib_dest_from_rnode (rn);
1763
Paul Jakma6d691122006-07-27 21:49:00 +00001764 if (rib->next)
1765 rib->next->prev = rib->prev;
1766
1767 if (rib->prev)
1768 rib->prev->next = rib->next;
1769 else
1770 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001771 dest->routes = rib->next;
Paul Jakma6d691122006-07-27 21:49:00 +00001772 }
1773
1774 /* free RIB and nexthops */
Christian Frankefa713d92013-07-05 15:35:37 +00001775 nexthops_free(rib->nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00001776 XFREE (MTYPE_RIB, rib);
1777
paul718e3742002-12-13 20:15:29 +00001778}
1779
paula1ac18c2005-06-28 17:17:12 +00001780static void
paul718e3742002-12-13 20:15:29 +00001781rib_delnode (struct route_node *rn, struct rib *rib)
1782{
Paul Jakma6d691122006-07-27 21:49:00 +00001783 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001784 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001785 char buf[INET6_ADDRSTRLEN];
1786 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001787 zlog_debug ("%s: %s/%d: rn %p, rib %p, removing", __func__,
1788 buf, rn->p.prefixlen, rn, rib);
1789 }
Paul Jakma6d691122006-07-27 21:49:00 +00001790 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1791 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001792}
1793
1794int
1795rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001796 struct in_addr *gate, struct in_addr *src,
1797 unsigned int ifindex, u_int32_t vrf_id,
G.Balajicddf3912011-11-26 21:59:32 +04001798 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001799{
1800 struct rib *rib;
1801 struct rib *same = NULL;
1802 struct route_table *table;
1803 struct route_node *rn;
1804 struct nexthop *nexthop;
1805
1806 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04001807 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00001808 if (! table)
1809 return 0;
1810
1811 /* Make it sure prefixlen is applied to the prefix. */
1812 apply_mask_ipv4 (p);
1813
1814 /* Set default distance by route type. */
1815 if (distance == 0)
1816 {
Balaji.G837d16c2012-09-26 14:09:10 +05301817 if ((unsigned)type >= array_size(route_info))
David Lamparter7052f222009-08-27 00:28:28 +02001818 distance = 150;
1819 else
1820 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00001821
1822 /* iBGP distance is 200. */
1823 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1824 distance = 200;
1825 }
1826
1827 /* Lookup route node.*/
1828 rn = route_node_get (table, (struct prefix *) p);
1829
1830 /* If same type of route are installed, treat it as a implicit
1831 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001832 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00001833 {
Paul Jakma6d691122006-07-27 21:49:00 +00001834 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1835 continue;
1836
hassoebf1ead2005-09-21 14:58:20 +00001837 if (rib->type != type)
1838 continue;
1839 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001840 {
1841 same = rib;
1842 break;
1843 }
hassoebf1ead2005-09-21 14:58:20 +00001844 /* Duplicate connected route comes in. */
1845 else if ((nexthop = rib->nexthop) &&
1846 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001847 nexthop->ifindex == ifindex &&
1848 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001849 {
1850 rib->refcnt++;
1851 return 0 ;
1852 }
paul718e3742002-12-13 20:15:29 +00001853 }
1854
1855 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001856 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001857 rib->type = type;
1858 rib->distance = distance;
1859 rib->flags = flags;
1860 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001861 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001862 rib->nexthop_num = 0;
1863 rib->uptime = time (NULL);
1864
1865 /* Nexthop settings. */
1866 if (gate)
1867 {
1868 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001869 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001870 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001871 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001872 }
1873 else
1874 nexthop_ifindex_add (rib, ifindex);
1875
1876 /* If this route is kernel route, set FIB flag to the route. */
1877 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1878 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1879 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1880
1881 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001882 if (IS_ZEBRA_DEBUG_RIB)
1883 zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
paul718e3742002-12-13 20:15:29 +00001884 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001885
paul718e3742002-12-13 20:15:29 +00001886 /* Free implicit route.*/
1887 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001888 {
1889 if (IS_ZEBRA_DEBUG_RIB)
1890 zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001891 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001892 }
paul4d38fdb2005-04-28 17:35:14 +00001893
1894 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001895 return 0;
1896}
1897
Denis Ovsienkodc958242007-08-13 16:03:06 +00001898/* This function dumps the contents of a given RIB entry into
1899 * standard debug log. Calling function name and IP prefix in
1900 * question are passed as 1st and 2nd arguments.
1901 */
1902
1903void rib_dump (const char * func, const struct prefix_ipv4 * p, const struct rib * rib)
1904{
Christian Frankefa713d92013-07-05 15:35:37 +00001905 char straddr[INET_ADDRSTRLEN];
1906 struct nexthop *nexthop, *tnexthop;
1907 int recursing;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001908
Christian Frankefa713d92013-07-05 15:35:37 +00001909 inet_ntop (AF_INET, &p->prefix, straddr, INET_ADDRSTRLEN);
1910 zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr, p->prefixlen);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001911 zlog_debug
1912 (
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001913 "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
Denis Ovsienkodc958242007-08-13 16:03:06 +00001914 func,
1915 rib->refcnt,
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001916 (unsigned long) rib->uptime,
Denis Ovsienkodc958242007-08-13 16:03:06 +00001917 rib->type,
1918 rib->table
1919 );
1920 zlog_debug
1921 (
1922 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1923 func,
1924 rib->metric,
1925 rib->distance,
1926 rib->flags,
1927 rib->status
1928 );
1929 zlog_debug
1930 (
1931 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1932 func,
1933 rib->nexthop_num,
1934 rib->nexthop_active_num,
1935 rib->nexthop_fib_num
1936 );
Christian Frankefa713d92013-07-05 15:35:37 +00001937 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1938 {
1939 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, straddr, INET_ADDRSTRLEN);
1940 zlog_debug
1941 (
1942 "%s: %s %s with flags %s%s%s",
1943 func,
1944 (recursing ? " NH" : "NH"),
1945 straddr,
1946 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1947 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1948 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1949 );
1950 }
Denis Ovsienkodc958242007-08-13 16:03:06 +00001951 zlog_debug ("%s: dump complete", func);
1952}
1953
1954/* This is an exported helper to rtm_read() to dump the strange
1955 * RIB entry found by rib_lookup_ipv4_route()
1956 */
1957
1958void rib_lookup_and_dump (struct prefix_ipv4 * p)
1959{
1960 struct route_table *table;
1961 struct route_node *rn;
1962 struct rib *rib;
1963 char prefix_buf[INET_ADDRSTRLEN];
1964
1965 /* Lookup table. */
1966 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1967 if (! table)
1968 {
1969 zlog_err ("%s: vrf_table() returned NULL", __func__);
1970 return;
1971 }
1972
1973 inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
1974 /* Scan the RIB table for exactly matching RIB entry. */
1975 rn = route_node_lookup (table, (struct prefix *) p);
1976
1977 /* No route for this prefix. */
1978 if (! rn)
1979 {
1980 zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
1981 return;
1982 }
1983
1984 /* Unlock node. */
1985 route_unlock_node (rn);
1986
1987 /* let's go */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001988 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001989 {
1990 zlog_debug
1991 (
1992 "%s: rn %p, rib %p: %s, %s",
1993 __func__,
1994 rn,
1995 rib,
1996 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
1997 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
1998 );
1999 rib_dump (__func__, p, rib);
2000 }
2001}
2002
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002003/* Check if requested address assignment will fail due to another
2004 * route being installed by zebra in FIB already. Take necessary
2005 * actions, if needed: remove such a route from FIB and deSELECT
2006 * corresponding RIB entry. Then put affected RN into RIBQ head.
2007 */
2008void rib_lookup_and_pushup (struct prefix_ipv4 * p)
2009{
2010 struct route_table *table;
2011 struct route_node *rn;
2012 struct rib *rib;
2013 unsigned changed = 0;
2014
2015 if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
2016 {
2017 zlog_err ("%s: vrf_table() returned NULL", __func__);
2018 return;
2019 }
2020
2021 /* No matches would be the simplest case. */
2022 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
2023 return;
2024
2025 /* Unlock node. */
2026 route_unlock_node (rn);
2027
2028 /* Check all RIB entries. In case any changes have to be done, requeue
2029 * the RN into RIBQ head. If the routing message about the new connected
2030 * route (generated by the IP address we are going to assign very soon)
2031 * comes before the RIBQ is processed, the new RIB entry will join
2032 * RIBQ record already on head. This is necessary for proper revalidation
2033 * of the rest of the RIB.
2034 */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002035 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002036 {
2037 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
2038 ! RIB_SYSTEM_ROUTE (rib))
2039 {
2040 changed = 1;
2041 if (IS_ZEBRA_DEBUG_RIB)
2042 {
2043 char buf[INET_ADDRSTRLEN];
2044 inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
2045 zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
2046 rib_dump (__func__, (struct prefix_ipv4 *)&rn->p, rib);
2047 }
2048 rib_uninstall (rn, rib);
2049 }
2050 }
2051 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002052 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002053}
2054
paul718e3742002-12-13 20:15:29 +00002055int
G.Balajicddf3912011-11-26 21:59:32 +04002056rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002057{
2058 struct route_table *table;
2059 struct route_node *rn;
2060 struct rib *same;
2061 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00002062
paul718e3742002-12-13 20:15:29 +00002063 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04002064 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00002065 if (! table)
2066 return 0;
G.Balajicddf3912011-11-26 21:59:32 +04002067
paul718e3742002-12-13 20:15:29 +00002068 /* Make it sure prefixlen is applied to the prefix. */
2069 apply_mask_ipv4 (p);
2070
2071 /* Set default distance by route type. */
2072 if (rib->distance == 0)
2073 {
2074 rib->distance = route_info[rib->type].distance;
2075
2076 /* iBGP distance is 200. */
2077 if (rib->type == ZEBRA_ROUTE_BGP
2078 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
2079 rib->distance = 200;
2080 }
2081
2082 /* Lookup route node.*/
2083 rn = route_node_get (table, (struct prefix *) p);
2084
2085 /* If same type of route are installed, treat it as a implicit
2086 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002087 RNODE_FOREACH_RIB (rn, same)
paul718e3742002-12-13 20:15:29 +00002088 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00002089 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00002090 continue;
2091
paul718e3742002-12-13 20:15:29 +00002092 if (same->type == rib->type && same->table == rib->table
2093 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00002094 break;
paul718e3742002-12-13 20:15:29 +00002095 }
paul4d38fdb2005-04-28 17:35:14 +00002096
paul718e3742002-12-13 20:15:29 +00002097 /* If this route is kernel route, set FIB flag to the route. */
2098 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
2099 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2100 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2101
2102 /* Link new rib to node.*/
2103 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002104 if (IS_ZEBRA_DEBUG_RIB)
2105 {
2106 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
2107 __func__, rn, rib);
2108 rib_dump (__func__, p, rib);
2109 }
paul718e3742002-12-13 20:15:29 +00002110
paul718e3742002-12-13 20:15:29 +00002111 /* Free implicit route.*/
2112 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00002113 {
2114 if (IS_ZEBRA_DEBUG_RIB)
2115 {
2116 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
2117 __func__, rn, same);
2118 rib_dump (__func__, p, same);
2119 }
paul4d38fdb2005-04-28 17:35:14 +00002120 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002121 }
paul4d38fdb2005-04-28 17:35:14 +00002122
2123 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002124 return 0;
2125}
2126
hassoebf1ead2005-09-21 14:58:20 +00002127/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002128int
2129rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
G.Balajicddf3912011-11-26 21:59:32 +04002130 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002131{
2132 struct route_table *table;
2133 struct route_node *rn;
2134 struct rib *rib;
2135 struct rib *fib = NULL;
2136 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002137 struct nexthop *nexthop, *tnexthop;
2138 int recursing;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002139 char buf1[INET_ADDRSTRLEN];
2140 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002141
2142 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04002143 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00002144 if (! table)
2145 return 0;
2146
2147 /* Apply mask. */
2148 apply_mask_ipv4 (p);
2149
paul5ec90d22003-06-19 01:41:37 +00002150 if (IS_ZEBRA_DEBUG_KERNEL && gate)
ajsb6178002004-12-07 21:12:56 +00002151 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002152 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul5ec90d22003-06-19 01:41:37 +00002153 p->prefixlen,
2154 inet_ntoa (*gate),
2155 ifindex);
2156
paul718e3742002-12-13 20:15:29 +00002157 /* Lookup route node. */
2158 rn = route_node_lookup (table, (struct prefix *) p);
2159 if (! rn)
2160 {
2161 if (IS_ZEBRA_DEBUG_KERNEL)
2162 {
2163 if (gate)
ajsb6178002004-12-07 21:12:56 +00002164 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002165 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002166 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002167 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002168 ifindex);
2169 else
ajsb6178002004-12-07 21:12:56 +00002170 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002171 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002172 p->prefixlen,
2173 ifindex);
2174 }
2175 return ZEBRA_ERR_RTNOEXIST;
2176 }
2177
2178 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002179 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002180 {
Paul Jakma6d691122006-07-27 21:49:00 +00002181 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2182 continue;
2183
paul718e3742002-12-13 20:15:29 +00002184 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2185 fib = rib;
2186
hassoebf1ead2005-09-21 14:58:20 +00002187 if (rib->type != type)
2188 continue;
2189 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002190 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002191 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002192 if (nexthop->ifindex != ifindex)
2193 continue;
hassoebf1ead2005-09-21 14:58:20 +00002194 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002195 {
hassoebf1ead2005-09-21 14:58:20 +00002196 rib->refcnt--;
2197 route_unlock_node (rn);
2198 route_unlock_node (rn);
2199 return 0;
paul718e3742002-12-13 20:15:29 +00002200 }
hassoebf1ead2005-09-21 14:58:20 +00002201 same = rib;
2202 break;
paul718e3742002-12-13 20:15:29 +00002203 }
hassoebf1ead2005-09-21 14:58:20 +00002204 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002205 else
paul5ec90d22003-06-19 01:41:37 +00002206 {
Christian Frankefa713d92013-07-05 15:35:37 +00002207 if (gate == NULL)
2208 {
2209 same = rib;
2210 break;
2211 }
2212 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2213 if (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate))
2214 {
2215 same = rib;
2216 break;
2217 }
2218 if (same)
2219 break;
2220 }
paul718e3742002-12-13 20:15:29 +00002221 }
paul718e3742002-12-13 20:15:29 +00002222 /* If same type of route can't be found and this message is from
2223 kernel. */
2224 if (! same)
2225 {
2226 if (fib && type == ZEBRA_ROUTE_KERNEL)
2227 {
2228 /* Unset flags. */
2229 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2230 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2231
2232 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2233 }
2234 else
2235 {
2236 if (IS_ZEBRA_DEBUG_KERNEL)
2237 {
2238 if (gate)
ajsb6178002004-12-07 21:12:56 +00002239 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002240 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002241 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002242 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002243 ifindex,
2244 type);
2245 else
ajsb6178002004-12-07 21:12:56 +00002246 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002247 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002248 p->prefixlen,
2249 ifindex,
2250 type);
2251 }
2252 route_unlock_node (rn);
2253 return ZEBRA_ERR_RTNOEXIST;
2254 }
2255 }
paul4d38fdb2005-04-28 17:35:14 +00002256
paul718e3742002-12-13 20:15:29 +00002257 if (same)
2258 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002259
paul718e3742002-12-13 20:15:29 +00002260 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002261 return 0;
2262}
2263
2264/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002265static void
paul718e3742002-12-13 20:15:29 +00002266static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
2267{
2268 struct rib *rib;
2269 struct route_node *rn;
2270 struct route_table *table;
2271
2272 /* Lookup table. */
2273 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2274 if (! table)
2275 return;
2276
2277 /* Lookup existing route */
2278 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002279 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002280 {
2281 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2282 continue;
2283
2284 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2285 break;
2286 }
paul718e3742002-12-13 20:15:29 +00002287
2288 if (rib)
2289 {
2290 /* Same distance static route is there. Update it with new
2291 nexthop. */
paul718e3742002-12-13 20:15:29 +00002292 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002293 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002294 {
2295 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002296 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002297 break;
2298 case STATIC_IPV4_IFNAME:
2299 nexthop_ifname_add (rib, si->gate.ifname);
2300 break;
2301 case STATIC_IPV4_BLACKHOLE:
2302 nexthop_blackhole_add (rib);
2303 break;
paul4d38fdb2005-04-28 17:35:14 +00002304 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002305 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002306 }
2307 else
2308 {
2309 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002310 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2311
paul718e3742002-12-13 20:15:29 +00002312 rib->type = ZEBRA_ROUTE_STATIC;
2313 rib->distance = si->distance;
2314 rib->metric = 0;
Nolan Leakeb0145dd2012-09-13 17:17:31 +00002315 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002316 rib->nexthop_num = 0;
2317
2318 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002319 {
2320 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002321 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002322 break;
2323 case STATIC_IPV4_IFNAME:
2324 nexthop_ifname_add (rib, si->gate.ifname);
2325 break;
2326 case STATIC_IPV4_BLACKHOLE:
2327 nexthop_blackhole_add (rib);
2328 break;
2329 }
paul718e3742002-12-13 20:15:29 +00002330
hasso81dfcaa2003-05-25 19:21:25 +00002331 /* Save the flags of this static routes (reject, blackhole) */
2332 rib->flags = si->flags;
2333
paul718e3742002-12-13 20:15:29 +00002334 /* Link this rib to the tree. */
2335 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002336 }
2337}
2338
paula1ac18c2005-06-28 17:17:12 +00002339static int
paul718e3742002-12-13 20:15:29 +00002340static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2341{
2342 if (nexthop->type == NEXTHOP_TYPE_IPV4
2343 && si->type == STATIC_IPV4_GATEWAY
2344 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2345 return 1;
2346 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2347 && si->type == STATIC_IPV4_IFNAME
2348 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2349 return 1;
paul595db7f2003-05-25 21:35:06 +00002350 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2351 && si->type == STATIC_IPV4_BLACKHOLE)
2352 return 1;
paule8e19462006-01-19 20:16:55 +00002353 return 0;
paul718e3742002-12-13 20:15:29 +00002354}
2355
2356/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002357static void
paul718e3742002-12-13 20:15:29 +00002358static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
2359{
2360 struct route_node *rn;
2361 struct rib *rib;
2362 struct nexthop *nexthop;
2363 struct route_table *table;
2364
2365 /* Lookup table. */
2366 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2367 if (! table)
2368 return;
paul4d38fdb2005-04-28 17:35:14 +00002369
paul718e3742002-12-13 20:15:29 +00002370 /* Lookup existing route with type and distance. */
2371 rn = route_node_lookup (table, p);
2372 if (! rn)
2373 return;
2374
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002375 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002376 {
2377 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2378 continue;
2379
2380 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2381 break;
2382 }
paul718e3742002-12-13 20:15:29 +00002383
2384 if (! rib)
2385 {
2386 route_unlock_node (rn);
2387 return;
2388 }
2389
2390 /* Lookup nexthop. */
2391 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2392 if (static_ipv4_nexthop_same (nexthop, si))
2393 break;
2394
2395 /* Can't find nexthop. */
2396 if (! nexthop)
2397 {
2398 route_unlock_node (rn);
2399 return;
2400 }
2401
2402 /* Check nexthop. */
2403 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002404 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002405 else
2406 {
paul6baeb982003-10-28 03:47:15 +00002407 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2408 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002409 nexthop_delete (rib, nexthop);
2410 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002411 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002412 }
paul718e3742002-12-13 20:15:29 +00002413 /* Unlock node. */
2414 route_unlock_node (rn);
2415}
2416
2417/* Add static route into static route configuration. */
2418int
hasso39db97e2004-10-12 20:50:58 +00002419static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00002420 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002421{
2422 u_char type = 0;
2423 struct route_node *rn;
2424 struct static_ipv4 *si;
2425 struct static_ipv4 *pp;
2426 struct static_ipv4 *cp;
2427 struct static_ipv4 *update = NULL;
2428 struct route_table *stable;
2429
2430 /* Lookup table. */
2431 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2432 if (! stable)
2433 return -1;
2434
2435 /* Lookup static route prefix. */
2436 rn = route_node_get (stable, p);
2437
2438 /* Make flags. */
2439 if (gate)
2440 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002441 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002442 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002443 else
2444 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002445
2446 /* Do nothing if there is a same static route. */
2447 for (si = rn->info; si; si = si->next)
2448 {
2449 if (type == si->type
2450 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2451 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2452 {
2453 if (distance == si->distance)
2454 {
2455 route_unlock_node (rn);
2456 return 0;
2457 }
2458 else
2459 update = si;
2460 }
2461 }
2462
Paul Jakma3c0755d2006-12-08 00:53:14 +00002463 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002464 if (update)
2465 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
2466
2467 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002468 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
paul718e3742002-12-13 20:15:29 +00002469
2470 si->type = type;
2471 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002472 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002473
2474 if (gate)
2475 si->gate.ipv4 = *gate;
2476 if (ifname)
2477 si->gate.ifname = XSTRDUP (0, ifname);
2478
2479 /* Add new static route information to the tree with sort by
2480 distance value and gateway address. */
2481 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2482 {
2483 if (si->distance < cp->distance)
2484 break;
2485 if (si->distance > cp->distance)
2486 continue;
2487 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2488 {
2489 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2490 break;
2491 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2492 continue;
2493 }
2494 }
2495
2496 /* Make linked list. */
2497 if (pp)
2498 pp->next = si;
2499 else
2500 rn->info = si;
2501 if (cp)
2502 cp->prev = si;
2503 si->prev = pp;
2504 si->next = cp;
2505
2506 /* Install into rib. */
2507 static_install_ipv4 (p, si);
2508
2509 return 1;
2510}
2511
2512/* Delete static route from static route configuration. */
2513int
hasso39db97e2004-10-12 20:50:58 +00002514static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00002515 u_char distance, u_int32_t vrf_id)
2516{
2517 u_char type = 0;
2518 struct route_node *rn;
2519 struct static_ipv4 *si;
2520 struct route_table *stable;
2521
2522 /* Lookup table. */
2523 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2524 if (! stable)
2525 return -1;
2526
2527 /* Lookup static route prefix. */
2528 rn = route_node_lookup (stable, p);
2529 if (! rn)
2530 return 0;
2531
2532 /* Make flags. */
2533 if (gate)
2534 type = STATIC_IPV4_GATEWAY;
2535 else if (ifname)
2536 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002537 else
2538 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002539
2540 /* Find same static route is the tree */
2541 for (si = rn->info; si; si = si->next)
2542 if (type == si->type
2543 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2544 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2545 break;
2546
2547 /* Can't find static route. */
2548 if (! si)
2549 {
2550 route_unlock_node (rn);
2551 return 0;
2552 }
2553
2554 /* Install into rib. */
2555 static_uninstall_ipv4 (p, si);
2556
2557 /* Unlink static route from linked list. */
2558 if (si->prev)
2559 si->prev->next = si->next;
2560 else
2561 rn->info = si->next;
2562 if (si->next)
2563 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002564 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002565
2566 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002567 if (ifname)
2568 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002569 XFREE (MTYPE_STATIC_IPV4, si);
2570
paul143a3852003-09-29 20:06:13 +00002571 route_unlock_node (rn);
2572
paul718e3742002-12-13 20:15:29 +00002573 return 1;
2574}
2575
2576
2577#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00002578static int
paul718e3742002-12-13 20:15:29 +00002579rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2580 struct in6_addr *gate, unsigned int ifindex, int table)
2581{
hasso726f9b22003-05-25 21:04:54 +00002582 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2583#if defined (MUSICA) || defined (LINUX)
2584 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2585 if (p->prefixlen == 96)
2586 return 0;
2587#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00002588 return 1;
hasso726f9b22003-05-25 21:04:54 +00002589 }
paul718e3742002-12-13 20:15:29 +00002590 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
2591 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
2592 {
2593 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
2594 return 1;
2595 }
2596 return 0;
2597}
2598
2599int
2600rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00002601 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
G.Balajif768f362011-11-26 22:10:39 +04002602 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002603{
2604 struct rib *rib;
2605 struct rib *same = NULL;
2606 struct route_table *table;
2607 struct route_node *rn;
2608 struct nexthop *nexthop;
2609
paul718e3742002-12-13 20:15:29 +00002610 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002611 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002612 if (! table)
2613 return 0;
2614
2615 /* Make sure mask is applied. */
2616 apply_mask_ipv6 (p);
2617
2618 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002619 if (!distance)
2620 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002621
2622 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2623 distance = 200;
2624
2625 /* Filter bogus route. */
2626 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
2627 return 0;
2628
2629 /* Lookup route node.*/
2630 rn = route_node_get (table, (struct prefix *) p);
2631
2632 /* If same type of route are installed, treat it as a implicit
2633 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002634 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002635 {
Paul Jakma6d691122006-07-27 21:49:00 +00002636 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2637 continue;
2638
hassoebf1ead2005-09-21 14:58:20 +00002639 if (rib->type != type)
2640 continue;
2641 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002642 {
2643 same = rib;
paul718e3742002-12-13 20:15:29 +00002644 break;
2645 }
hassoebf1ead2005-09-21 14:58:20 +00002646 else if ((nexthop = rib->nexthop) &&
2647 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2648 nexthop->ifindex == ifindex)
2649 {
2650 rib->refcnt++;
2651 return 0;
2652 }
paul718e3742002-12-13 20:15:29 +00002653 }
2654
2655 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002656 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2657
paul718e3742002-12-13 20:15:29 +00002658 rib->type = type;
2659 rib->distance = distance;
2660 rib->flags = flags;
2661 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00002662 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00002663 rib->nexthop_num = 0;
2664 rib->uptime = time (NULL);
2665
2666 /* Nexthop settings. */
2667 if (gate)
2668 {
2669 if (ifindex)
2670 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2671 else
2672 nexthop_ipv6_add (rib, gate);
2673 }
2674 else
2675 nexthop_ifindex_add (rib, ifindex);
2676
2677 /* If this route is kernel route, set FIB flag to the route. */
2678 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2679 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2680 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2681
2682 /* Link new rib to node.*/
2683 rib_addnode (rn, rib);
2684
paul718e3742002-12-13 20:15:29 +00002685 /* Free implicit route.*/
2686 if (same)
paul4d38fdb2005-04-28 17:35:14 +00002687 rib_delnode (rn, same);
2688
2689 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002690 return 0;
2691}
2692
hassoebf1ead2005-09-21 14:58:20 +00002693/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002694int
2695rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
G.Balajif768f362011-11-26 22:10:39 +04002696 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002697{
2698 struct route_table *table;
2699 struct route_node *rn;
2700 struct rib *rib;
2701 struct rib *fib = NULL;
2702 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002703 struct nexthop *nexthop, *tnexthop;
2704 int recursing;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002705 char buf1[INET6_ADDRSTRLEN];
2706 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002707
2708 /* Apply mask. */
2709 apply_mask_ipv6 (p);
2710
2711 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002712 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002713 if (! table)
2714 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002715
paul718e3742002-12-13 20:15:29 +00002716 /* Lookup route node. */
2717 rn = route_node_lookup (table, (struct prefix *) p);
2718 if (! rn)
2719 {
2720 if (IS_ZEBRA_DEBUG_KERNEL)
2721 {
2722 if (gate)
ajsb6178002004-12-07 21:12:56 +00002723 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002724 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002725 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002726 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002727 ifindex);
2728 else
ajsb6178002004-12-07 21:12:56 +00002729 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002730 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002731 p->prefixlen,
2732 ifindex);
2733 }
2734 return ZEBRA_ERR_RTNOEXIST;
2735 }
2736
2737 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002738 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002739 {
Paul Jakma6d691122006-07-27 21:49:00 +00002740 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2741 continue;
2742
paul718e3742002-12-13 20:15:29 +00002743 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2744 fib = rib;
2745
hassoebf1ead2005-09-21 14:58:20 +00002746 if (rib->type != type)
2747 continue;
2748 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002749 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002750 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002751 if (nexthop->ifindex != ifindex)
2752 continue;
hassoebf1ead2005-09-21 14:58:20 +00002753 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002754 {
hassoebf1ead2005-09-21 14:58:20 +00002755 rib->refcnt--;
2756 route_unlock_node (rn);
2757 route_unlock_node (rn);
2758 return 0;
paul718e3742002-12-13 20:15:29 +00002759 }
hassoebf1ead2005-09-21 14:58:20 +00002760 same = rib;
2761 break;
paul718e3742002-12-13 20:15:29 +00002762 }
hassoebf1ead2005-09-21 14:58:20 +00002763 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002764 else
2765 {
2766 if (gate == NULL)
2767 {
2768 same = rib;
2769 break;
2770 }
2771 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2772 if (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate))
2773 {
2774 same = rib;
2775 break;
2776 }
2777 if (same)
2778 break;
2779 }
paul718e3742002-12-13 20:15:29 +00002780 }
2781
2782 /* If same type of route can't be found and this message is from
2783 kernel. */
2784 if (! same)
2785 {
2786 if (fib && type == ZEBRA_ROUTE_KERNEL)
2787 {
2788 /* Unset flags. */
2789 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2790 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2791
2792 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2793 }
2794 else
2795 {
2796 if (IS_ZEBRA_DEBUG_KERNEL)
2797 {
2798 if (gate)
ajsb6178002004-12-07 21:12:56 +00002799 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002800 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002801 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002802 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002803 ifindex,
2804 type);
2805 else
ajsb6178002004-12-07 21:12:56 +00002806 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002807 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002808 p->prefixlen,
2809 ifindex,
2810 type);
2811 }
2812 route_unlock_node (rn);
2813 return ZEBRA_ERR_RTNOEXIST;
2814 }
2815 }
2816
2817 if (same)
2818 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002819
paul718e3742002-12-13 20:15:29 +00002820 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002821 return 0;
2822}
2823
2824/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002825static void
paul718e3742002-12-13 20:15:29 +00002826static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2827{
2828 struct rib *rib;
2829 struct route_table *table;
2830 struct route_node *rn;
2831
2832 /* Lookup table. */
2833 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2834 if (! table)
2835 return;
2836
2837 /* Lookup existing route */
2838 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002839 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002840 {
2841 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2842 continue;
2843
2844 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2845 break;
2846 }
paul718e3742002-12-13 20:15:29 +00002847
2848 if (rib)
2849 {
2850 /* Same distance static route is there. Update it with new
2851 nexthop. */
paul718e3742002-12-13 20:15:29 +00002852 route_unlock_node (rn);
2853
2854 switch (si->type)
2855 {
2856 case STATIC_IPV6_GATEWAY:
2857 nexthop_ipv6_add (rib, &si->ipv6);
2858 break;
2859 case STATIC_IPV6_IFNAME:
2860 nexthop_ifname_add (rib, si->ifname);
2861 break;
2862 case STATIC_IPV6_GATEWAY_IFNAME:
2863 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2864 break;
2865 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002866 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002867 }
2868 else
2869 {
2870 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002871 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2872
paul718e3742002-12-13 20:15:29 +00002873 rib->type = ZEBRA_ROUTE_STATIC;
2874 rib->distance = si->distance;
2875 rib->metric = 0;
2876 rib->nexthop_num = 0;
2877
2878 switch (si->type)
2879 {
2880 case STATIC_IPV6_GATEWAY:
2881 nexthop_ipv6_add (rib, &si->ipv6);
2882 break;
2883 case STATIC_IPV6_IFNAME:
2884 nexthop_ifname_add (rib, si->ifname);
2885 break;
2886 case STATIC_IPV6_GATEWAY_IFNAME:
2887 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2888 break;
2889 }
2890
hasso81dfcaa2003-05-25 19:21:25 +00002891 /* Save the flags of this static routes (reject, blackhole) */
2892 rib->flags = si->flags;
2893
paul718e3742002-12-13 20:15:29 +00002894 /* Link this rib to the tree. */
2895 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002896 }
2897}
2898
paula1ac18c2005-06-28 17:17:12 +00002899static int
paul718e3742002-12-13 20:15:29 +00002900static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2901{
2902 if (nexthop->type == NEXTHOP_TYPE_IPV6
2903 && si->type == STATIC_IPV6_GATEWAY
2904 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2905 return 1;
2906 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2907 && si->type == STATIC_IPV6_IFNAME
2908 && strcmp (nexthop->ifname, si->ifname) == 0)
2909 return 1;
2910 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2911 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2912 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2913 && strcmp (nexthop->ifname, si->ifname) == 0)
2914 return 1;
paule8e19462006-01-19 20:16:55 +00002915 return 0;
paul718e3742002-12-13 20:15:29 +00002916}
2917
paula1ac18c2005-06-28 17:17:12 +00002918static void
paul718e3742002-12-13 20:15:29 +00002919static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2920{
2921 struct route_table *table;
2922 struct route_node *rn;
2923 struct rib *rib;
2924 struct nexthop *nexthop;
2925
2926 /* Lookup table. */
2927 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2928 if (! table)
2929 return;
2930
2931 /* Lookup existing route with type and distance. */
2932 rn = route_node_lookup (table, (struct prefix *) p);
2933 if (! rn)
2934 return;
2935
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002936 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002937 {
2938 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2939 continue;
2940
2941 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2942 break;
2943 }
2944
paul718e3742002-12-13 20:15:29 +00002945 if (! rib)
2946 {
2947 route_unlock_node (rn);
2948 return;
2949 }
2950
2951 /* Lookup nexthop. */
2952 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2953 if (static_ipv6_nexthop_same (nexthop, si))
2954 break;
2955
2956 /* Can't find nexthop. */
2957 if (! nexthop)
2958 {
2959 route_unlock_node (rn);
2960 return;
2961 }
2962
2963 /* Check nexthop. */
2964 if (rib->nexthop_num == 1)
2965 {
2966 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002967 }
2968 else
2969 {
paul6baeb982003-10-28 03:47:15 +00002970 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2971 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002972 nexthop_delete (rib, nexthop);
2973 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002974 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002975 }
paul718e3742002-12-13 20:15:29 +00002976 /* Unlock node. */
2977 route_unlock_node (rn);
2978}
2979
2980/* Add static route into static route configuration. */
2981int
2982static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002983 const char *ifname, u_char flags, u_char distance,
2984 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002985{
2986 struct route_node *rn;
2987 struct static_ipv6 *si;
2988 struct static_ipv6 *pp;
2989 struct static_ipv6 *cp;
2990 struct route_table *stable;
2991
2992 /* Lookup table. */
2993 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2994 if (! stable)
2995 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00002996
2997 if (!gate &&
2998 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
2999 return -1;
3000
3001 if (!ifname &&
3002 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
3003 return -1;
paul718e3742002-12-13 20:15:29 +00003004
3005 /* Lookup static route prefix. */
3006 rn = route_node_get (stable, p);
3007
3008 /* Do nothing if there is a same static route. */
3009 for (si = rn->info; si; si = si->next)
3010 {
3011 if (distance == si->distance
3012 && type == si->type
3013 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
3014 && (! ifname || strcmp (ifname, si->ifname) == 0))
3015 {
3016 route_unlock_node (rn);
3017 return 0;
3018 }
3019 }
3020
3021 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07003022 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
paul718e3742002-12-13 20:15:29 +00003023
3024 si->type = type;
3025 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00003026 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00003027
3028 switch (type)
3029 {
3030 case STATIC_IPV6_GATEWAY:
3031 si->ipv6 = *gate;
3032 break;
3033 case STATIC_IPV6_IFNAME:
3034 si->ifname = XSTRDUP (0, ifname);
3035 break;
3036 case STATIC_IPV6_GATEWAY_IFNAME:
3037 si->ipv6 = *gate;
3038 si->ifname = XSTRDUP (0, ifname);
3039 break;
3040 }
3041
3042 /* Add new static route information to the tree with sort by
3043 distance value and gateway address. */
3044 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
3045 {
3046 if (si->distance < cp->distance)
3047 break;
3048 if (si->distance > cp->distance)
3049 continue;
3050 }
3051
3052 /* Make linked list. */
3053 if (pp)
3054 pp->next = si;
3055 else
3056 rn->info = si;
3057 if (cp)
3058 cp->prev = si;
3059 si->prev = pp;
3060 si->next = cp;
3061
3062 /* Install into rib. */
3063 static_install_ipv6 (p, si);
3064
3065 return 1;
3066}
3067
3068/* Delete static route from static route configuration. */
3069int
3070static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00003071 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00003072{
3073 struct route_node *rn;
3074 struct static_ipv6 *si;
3075 struct route_table *stable;
3076
3077 /* Lookup table. */
3078 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
3079 if (! stable)
3080 return -1;
3081
3082 /* Lookup static route prefix. */
3083 rn = route_node_lookup (stable, p);
3084 if (! rn)
3085 return 0;
3086
3087 /* Find same static route is the tree */
3088 for (si = rn->info; si; si = si->next)
3089 if (distance == si->distance
3090 && type == si->type
3091 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
3092 && (! ifname || strcmp (ifname, si->ifname) == 0))
3093 break;
3094
3095 /* Can't find static route. */
3096 if (! si)
3097 {
3098 route_unlock_node (rn);
3099 return 0;
3100 }
3101
3102 /* Install into rib. */
3103 static_uninstall_ipv6 (p, si);
3104
3105 /* Unlink static route from linked list. */
3106 if (si->prev)
3107 si->prev->next = si->next;
3108 else
3109 rn->info = si->next;
3110 if (si->next)
3111 si->next->prev = si->prev;
3112
3113 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00003114 if (ifname)
3115 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00003116 XFREE (MTYPE_STATIC_IPV6, si);
3117
3118 return 1;
3119}
3120#endif /* HAVE_IPV6 */
3121
3122/* RIB update function. */
3123void
paula1ac18c2005-06-28 17:17:12 +00003124rib_update (void)
paul718e3742002-12-13 20:15:29 +00003125{
3126 struct route_node *rn;
3127 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00003128
paul718e3742002-12-13 20:15:29 +00003129 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
3130 if (table)
3131 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003132 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003133 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003134
3135 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
3136 if (table)
3137 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003138 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003139 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003140}
3141
paul718e3742002-12-13 20:15:29 +00003142
3143/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00003144static void
paul718e3742002-12-13 20:15:29 +00003145rib_weed_table (struct route_table *table)
3146{
3147 struct route_node *rn;
3148 struct rib *rib;
3149 struct rib *next;
3150
3151 if (table)
3152 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003153 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003154 {
Paul Jakma6d691122006-07-27 21:49:00 +00003155 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3156 continue;
3157
paulb21b19c2003-06-15 01:28:29 +00003158 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00003159 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00003160 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003161 }
3162}
3163
3164/* Delete all routes from non main table. */
3165void
paula1ac18c2005-06-28 17:17:12 +00003166rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00003167{
3168 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3169 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3170}
3171
3172/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00003173static void
paul718e3742002-12-13 20:15:29 +00003174rib_sweep_table (struct route_table *table)
3175{
3176 struct route_node *rn;
3177 struct rib *rib;
3178 struct rib *next;
3179 int ret = 0;
3180
3181 if (table)
3182 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003183 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003184 {
Paul Jakma6d691122006-07-27 21:49:00 +00003185 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3186 continue;
3187
paul718e3742002-12-13 20:15:29 +00003188 if (rib->type == ZEBRA_ROUTE_KERNEL &&
3189 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
3190 {
3191 ret = rib_uninstall_kernel (rn, rib);
3192 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00003193 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003194 }
3195 }
3196}
3197
3198/* Sweep all RIB tables. */
3199void
paula1ac18c2005-06-28 17:17:12 +00003200rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00003201{
3202 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3203 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3204}
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003205
3206/* Remove specific by protocol routes from 'table'. */
3207static unsigned long
3208rib_score_proto_table (u_char proto, struct route_table *table)
3209{
3210 struct route_node *rn;
3211 struct rib *rib;
3212 struct rib *next;
3213 unsigned long n = 0;
3214
3215 if (table)
3216 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003217 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003218 {
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003219 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3220 continue;
3221 if (rib->type == proto)
3222 {
3223 rib_delnode (rn, rib);
3224 n++;
3225 }
3226 }
3227
3228 return n;
3229}
3230
3231/* Remove specific by protocol routes. */
3232unsigned long
3233rib_score_proto (u_char proto)
3234{
3235 return rib_score_proto_table (proto, vrf_table (AFI_IP, SAFI_UNICAST, 0))
3236 +rib_score_proto_table (proto, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3237}
3238
paul718e3742002-12-13 20:15:29 +00003239/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00003240static void
paul718e3742002-12-13 20:15:29 +00003241rib_close_table (struct route_table *table)
3242{
3243 struct route_node *rn;
3244 struct rib *rib;
3245
3246 if (table)
3247 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003248 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00003249 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003250 if (!CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
3251 continue;
3252
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00003253 zfpm_trigger_update (rn, NULL);
3254
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003255 if (! RIB_SYSTEM_ROUTE (rib))
3256 rib_uninstall_kernel (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00003257 }
paul718e3742002-12-13 20:15:29 +00003258}
3259
3260/* Close all RIB tables. */
3261void
paula1ac18c2005-06-28 17:17:12 +00003262rib_close (void)
paul718e3742002-12-13 20:15:29 +00003263{
3264 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3265 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3266}
3267
3268/* Routing information base initialize. */
3269void
paula1ac18c2005-06-28 17:17:12 +00003270rib_init (void)
paul718e3742002-12-13 20:15:29 +00003271{
paul4d38fdb2005-04-28 17:35:14 +00003272 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00003273 /* VRF initialization. */
3274 vrf_init ();
3275}
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003276
3277/*
3278 * vrf_id_get_next
3279 *
3280 * Get the first vrf id that is greater than the given vrf id if any.
3281 *
3282 * Returns TRUE if a vrf id was found, FALSE otherwise.
3283 */
3284static inline int
3285vrf_id_get_next (uint32_t id, uint32_t *next_id_p)
3286{
3287 while (++id < vector_active (vrf_vector))
3288 {
3289 if (vrf_lookup (id))
3290 {
3291 *next_id_p = id;
3292 return 1;
3293 }
3294 }
3295
3296 return 0;
3297}
3298
3299/*
3300 * rib_tables_iter_next
3301 *
3302 * Returns the next table in the iteration.
3303 */
3304struct route_table *
3305rib_tables_iter_next (rib_tables_iter_t *iter)
3306{
3307 struct route_table *table;
3308
3309 /*
3310 * Array that helps us go over all AFI/SAFI combinations via one
3311 * index.
3312 */
3313 static struct {
3314 afi_t afi;
3315 safi_t safi;
3316 } afi_safis[] = {
3317 { AFI_IP, SAFI_UNICAST },
3318 { AFI_IP, SAFI_MULTICAST },
3319 { AFI_IP6, SAFI_UNICAST },
3320 { AFI_IP6, SAFI_MULTICAST },
3321 };
3322
3323 table = NULL;
3324
3325 switch (iter->state)
3326 {
3327
3328 case RIB_TABLES_ITER_S_INIT:
3329 iter->vrf_id = 0;
3330 iter->afi_safi_ix = -1;
3331
3332 /* Fall through */
3333
3334 case RIB_TABLES_ITER_S_ITERATING:
3335 iter->afi_safi_ix++;
3336 while (1)
3337 {
3338
3339 while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
3340 {
3341 table = vrf_table (afi_safis[iter->afi_safi_ix].afi,
3342 afi_safis[iter->afi_safi_ix].safi,
3343 iter->vrf_id);
3344 if (table)
3345 break;
3346
3347 iter->afi_safi_ix++;
3348 }
3349
3350 /*
3351 * Found another table in this vrf.
3352 */
3353 if (table)
3354 break;
3355
3356 /*
3357 * Done with all tables in the current vrf, go to the next
3358 * one.
3359 */
3360 if (!vrf_id_get_next (iter->vrf_id, &iter->vrf_id))
3361 break;
3362
3363 iter->afi_safi_ix = 0;
3364 }
3365
3366 break;
3367
3368 case RIB_TABLES_ITER_S_DONE:
3369 return NULL;
3370 }
3371
3372 if (table)
3373 iter->state = RIB_TABLES_ITER_S_ITERATING;
3374 else
3375 iter->state = RIB_TABLES_ITER_S_DONE;
3376
3377 return table;
3378}