blob: 301e0cc1dbdd1291f5b6c567c0dfbce86836ced1 [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);
503
504 resolved_hop->type = newhop->type;
paul718e3742002-12-13 20:15:29 +0000505 if (newhop->type == NEXTHOP_TYPE_IPV4 ||
506 newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
Christian Frankefa713d92013-07-05 15:35:37 +0000507 resolved_hop->gate.ipv4 = newhop->gate.ipv4;
508
paul718e3742002-12-13 20:15:29 +0000509 if (newhop->type == NEXTHOP_TYPE_IFINDEX
510 || newhop->type == NEXTHOP_TYPE_IFNAME
511 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
Christian Frankefa713d92013-07-05 15:35:37 +0000512 resolved_hop->ifindex = newhop->ifindex;
513
514 _nexthop_add(&nexthop->resolved, resolved_hop);
paul718e3742002-12-13 20:15:29 +0000515 }
Christian Frankefa713d92013-07-05 15:35:37 +0000516 resolved = 1;
paul718e3742002-12-13 20:15:29 +0000517 }
Christian Frankefa713d92013-07-05 15:35:37 +0000518 return resolved;
paul718e3742002-12-13 20:15:29 +0000519 }
520 else
521 {
522 return 0;
523 }
524 }
525 }
526 return 0;
527}
528
529#ifdef HAVE_IPV6
530/* If force flag is not set, do not modify falgs at all for uninstall
531 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000532static int
paul718e3742002-12-13 20:15:29 +0000533nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
534 struct route_node *top)
535{
536 struct prefix_ipv6 p;
537 struct route_table *table;
538 struct route_node *rn;
539 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000540 int resolved;
paul718e3742002-12-13 20:15:29 +0000541 struct nexthop *newhop;
Christian Frankefa713d92013-07-05 15:35:37 +0000542 struct nexthop *resolved_hop;
paul718e3742002-12-13 20:15:29 +0000543
544 if (nexthop->type == NEXTHOP_TYPE_IPV6)
545 nexthop->ifindex = 0;
546
547 if (set)
Christian Frankefa713d92013-07-05 15:35:37 +0000548 {
549 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
550 nexthops_free(nexthop->resolved);
551 nexthop->resolved = NULL;
552 }
paul718e3742002-12-13 20:15:29 +0000553
554 /* Make lookup prefix. */
555 memset (&p, 0, sizeof (struct prefix_ipv6));
556 p.family = AF_INET6;
557 p.prefixlen = IPV6_MAX_PREFIXLEN;
558 p.prefix = nexthop->gate.ipv6;
559
560 /* Lookup table. */
561 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
562 if (! table)
563 return 0;
564
565 rn = route_node_match (table, (struct prefix *) &p);
566 while (rn)
567 {
568 route_unlock_node (rn);
569
David Warda50c1072009-12-03 15:34:39 +0300570 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000571 if (rn == top)
572 return 0;
573
574 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000575 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100576 {
577 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
578 continue;
579 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
580 break;
581 }
paul718e3742002-12-13 20:15:29 +0000582
583 /* If there is no selected route or matched route is EGP, go up
584 tree. */
585 if (! match
586 || match->type == ZEBRA_ROUTE_BGP)
587 {
588 do {
589 rn = rn->parent;
590 } while (rn && rn->info == NULL);
591 if (rn)
592 route_lock_node (rn);
593 }
594 else
595 {
Christian Franke48a53dc2013-07-05 15:35:38 +0000596 /* If the longest prefix match for the nexthop yields
597 * a blackhole, mark it as inactive. */
598 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE)
599 || CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT))
600 return 0;
601
paul718e3742002-12-13 20:15:29 +0000602 if (match->type == ZEBRA_ROUTE_CONNECT)
603 {
604 /* Directly point connected route. */
605 newhop = match->nexthop;
606
607 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
608 nexthop->ifindex = newhop->ifindex;
609
610 return 1;
611 }
612 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
613 {
Christian Frankefa713d92013-07-05 15:35:37 +0000614 resolved = 0;
paul718e3742002-12-13 20:15:29 +0000615 for (newhop = match->nexthop; newhop; newhop = newhop->next)
616 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
617 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
618 {
619 if (set)
620 {
621 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
Christian Frankefa713d92013-07-05 15:35:37 +0000622
623 resolved_hop = XCALLOC(MTYPE_NEXTHOP, sizeof (struct nexthop));
624 SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
625
626 resolved_hop->type = newhop->type;
paul718e3742002-12-13 20:15:29 +0000627 if (newhop->type == NEXTHOP_TYPE_IPV6
628 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
629 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
Christian Frankefa713d92013-07-05 15:35:37 +0000630 resolved_hop->gate.ipv6 = newhop->gate.ipv6;
631
paul718e3742002-12-13 20:15:29 +0000632 if (newhop->type == NEXTHOP_TYPE_IFINDEX
633 || newhop->type == NEXTHOP_TYPE_IFNAME
634 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
635 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
Christian Frankefa713d92013-07-05 15:35:37 +0000636 resolved_hop->ifindex = newhop->ifindex;
637
638 _nexthop_add(&nexthop->resolved, resolved_hop);
paul718e3742002-12-13 20:15:29 +0000639 }
Christian Frankefa713d92013-07-05 15:35:37 +0000640 resolved = 1;
paul718e3742002-12-13 20:15:29 +0000641 }
Christian Frankefa713d92013-07-05 15:35:37 +0000642 return resolved;
paul718e3742002-12-13 20:15:29 +0000643 }
644 else
645 {
646 return 0;
647 }
648 }
649 }
650 return 0;
651}
652#endif /* HAVE_IPV6 */
653
654struct rib *
655rib_match_ipv4 (struct in_addr addr)
656{
657 struct prefix_ipv4 p;
658 struct route_table *table;
659 struct route_node *rn;
660 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000661 struct nexthop *newhop, *tnewhop;
662 int recursing;
paul718e3742002-12-13 20:15:29 +0000663
664 /* Lookup table. */
665 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
666 if (! table)
667 return 0;
668
669 memset (&p, 0, sizeof (struct prefix_ipv4));
670 p.family = AF_INET;
671 p.prefixlen = IPV4_MAX_PREFIXLEN;
672 p.prefix = addr;
673
674 rn = route_node_match (table, (struct prefix *) &p);
675
676 while (rn)
677 {
678 route_unlock_node (rn);
679
680 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000681 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100682 {
683 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
684 continue;
685 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
686 break;
687 }
paul718e3742002-12-13 20:15:29 +0000688
689 /* If there is no selected route or matched route is EGP, go up
690 tree. */
691 if (! match
692 || match->type == ZEBRA_ROUTE_BGP)
693 {
694 do {
695 rn = rn->parent;
696 } while (rn && rn->info == NULL);
697 if (rn)
698 route_lock_node (rn);
699 }
700 else
701 {
702 if (match->type == ZEBRA_ROUTE_CONNECT)
703 /* Directly point connected route. */
704 return match;
705 else
706 {
Christian Frankefa713d92013-07-05 15:35:37 +0000707 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
paul718e3742002-12-13 20:15:29 +0000708 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
709 return match;
710 return NULL;
711 }
712 }
713 }
714 return NULL;
715}
716
717struct rib *
718rib_lookup_ipv4 (struct prefix_ipv4 *p)
719{
720 struct route_table *table;
721 struct route_node *rn;
722 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000723 struct nexthop *nexthop, *tnexthop;
724 int recursing;
paul718e3742002-12-13 20:15:29 +0000725
726 /* Lookup table. */
727 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
728 if (! table)
729 return 0;
730
731 rn = route_node_lookup (table, (struct prefix *) p);
732
733 /* No route for this prefix. */
734 if (! rn)
735 return NULL;
736
737 /* Unlock node. */
738 route_unlock_node (rn);
739
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000740 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100741 {
742 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
743 continue;
744 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
745 break;
746 }
paul718e3742002-12-13 20:15:29 +0000747
748 if (! match || match->type == ZEBRA_ROUTE_BGP)
749 return NULL;
750
751 if (match->type == ZEBRA_ROUTE_CONNECT)
752 return match;
753
Christian Frankefa713d92013-07-05 15:35:37 +0000754 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +0000755 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
756 return match;
757
758 return NULL;
759}
760
Denis Ovsienkodc958242007-08-13 16:03:06 +0000761/*
762 * This clone function, unlike its original rib_lookup_ipv4(), checks
763 * if specified IPv4 route record (prefix/mask -> gate) exists in
764 * the whole RIB and has ZEBRA_FLAG_SELECTED set.
765 *
766 * Return values:
767 * -1: error
768 * 0: exact match found
769 * 1: a match was found with a different gate
770 * 2: connected route found
771 * 3: no matches found
772 */
773int
774rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
775{
776 struct route_table *table;
777 struct route_node *rn;
778 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000779 struct nexthop *nexthop, *tnexthop;
780 int recursing;
781 int nexthops_active;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000782
783 /* Lookup table. */
784 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
785 if (! table)
786 return ZEBRA_RIB_LOOKUP_ERROR;
787
788 /* Scan the RIB table for exactly matching RIB entry. */
789 rn = route_node_lookup (table, (struct prefix *) p);
790
791 /* No route for this prefix. */
792 if (! rn)
793 return ZEBRA_RIB_NOTFOUND;
794
795 /* Unlock node. */
796 route_unlock_node (rn);
797
798 /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000799 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100800 {
801 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
802 continue;
803 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
804 break;
805 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000806
807 /* None such found :( */
808 if (!match)
809 return ZEBRA_RIB_NOTFOUND;
810
811 if (match->type == ZEBRA_ROUTE_CONNECT)
812 return ZEBRA_RIB_FOUND_CONNECTED;
813
814 /* Ok, we have a cood candidate, let's check it's nexthop list... */
Christian Frankefa713d92013-07-05 15:35:37 +0000815 nexthops_active = 0;
816 for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000817 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000818 {
Christian Frankefa713d92013-07-05 15:35:37 +0000819 nexthops_active = 1;
820 if (nexthop->gate.ipv4.s_addr == sockunion2ip (qgate))
821 return ZEBRA_RIB_FOUND_EXACT;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000822 if (IS_ZEBRA_DEBUG_RIB)
Christian Frankefa713d92013-07-05 15:35:37 +0000823 {
824 char gate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
825 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
826 inet_ntop (AF_INET, &sockunion2ip(qgate), qgate_buf, INET_ADDRSTRLEN);
827 zlog_debug ("%s: qgate == %s, %s == %s", __func__,
828 qgate_buf, recursing ? "rgate" : "gate", gate_buf);
829 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000830 }
Christian Frankefa713d92013-07-05 15:35:37 +0000831
832 if (nexthops_active)
833 return ZEBRA_RIB_FOUND_NOGATE;
Denis Ovsienkodc958242007-08-13 16:03:06 +0000834
835 return ZEBRA_RIB_NOTFOUND;
836}
837
paul718e3742002-12-13 20:15:29 +0000838#ifdef HAVE_IPV6
839struct rib *
840rib_match_ipv6 (struct in6_addr *addr)
841{
842 struct prefix_ipv6 p;
843 struct route_table *table;
844 struct route_node *rn;
845 struct rib *match;
Christian Frankefa713d92013-07-05 15:35:37 +0000846 struct nexthop *newhop, *tnewhop;
847 int recursing;
paul718e3742002-12-13 20:15:29 +0000848
849 /* Lookup table. */
850 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
851 if (! table)
852 return 0;
853
854 memset (&p, 0, sizeof (struct prefix_ipv6));
855 p.family = AF_INET6;
856 p.prefixlen = IPV6_MAX_PREFIXLEN;
857 IPV6_ADDR_COPY (&p.prefix, addr);
858
859 rn = route_node_match (table, (struct prefix *) &p);
860
861 while (rn)
862 {
863 route_unlock_node (rn);
864
865 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000866 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100867 {
868 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
869 continue;
870 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
871 break;
872 }
paul718e3742002-12-13 20:15:29 +0000873
874 /* If there is no selected route or matched route is EGP, go up
875 tree. */
876 if (! match
877 || match->type == ZEBRA_ROUTE_BGP)
878 {
879 do {
880 rn = rn->parent;
881 } while (rn && rn->info == NULL);
882 if (rn)
883 route_lock_node (rn);
884 }
885 else
886 {
887 if (match->type == ZEBRA_ROUTE_CONNECT)
888 /* Directly point connected route. */
889 return match;
890 else
891 {
Christian Frankefa713d92013-07-05 15:35:37 +0000892 for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
paul718e3742002-12-13 20:15:29 +0000893 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
894 return match;
895 return NULL;
896 }
897 }
898 }
899 return NULL;
900}
901#endif /* HAVE_IPV6 */
902
Paul Jakma7514fb72007-05-02 16:05:35 +0000903#define RIB_SYSTEM_ROUTE(R) \
904 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
905
Denis Ovsienkodc958242007-08-13 16:03:06 +0000906/* This function verifies reachability of one given nexthop, which can be
907 * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
908 * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
909 * nexthop->ifindex will be updated appropriately as well.
910 * An existing route map can turn (otherwise active) nexthop into inactive, but
911 * not vice versa.
912 *
913 * The return value is the final value of 'ACTIVE' flag.
914 */
915
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300916static unsigned
paul718e3742002-12-13 20:15:29 +0000917nexthop_active_check (struct route_node *rn, struct rib *rib,
918 struct nexthop *nexthop, int set)
919{
920 struct interface *ifp;
Paul Jakma7514fb72007-05-02 16:05:35 +0000921 route_map_result_t ret = RMAP_MATCH;
922 extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
923 struct route_map *rmap;
924 int family;
paul718e3742002-12-13 20:15:29 +0000925
Paul Jakma7514fb72007-05-02 16:05:35 +0000926 family = 0;
paul718e3742002-12-13 20:15:29 +0000927 switch (nexthop->type)
928 {
929 case NEXTHOP_TYPE_IFINDEX:
930 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000931 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000932 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
933 else
934 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
935 break;
paul718e3742002-12-13 20:15:29 +0000936 case NEXTHOP_TYPE_IPV6_IFNAME:
Paul Jakma7514fb72007-05-02 16:05:35 +0000937 family = AFI_IP6;
938 case NEXTHOP_TYPE_IFNAME:
paul718e3742002-12-13 20:15:29 +0000939 ifp = if_lookup_by_name (nexthop->ifname);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000940 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000941 {
942 if (set)
943 nexthop->ifindex = ifp->ifindex;
944 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
945 }
946 else
947 {
948 if (set)
949 nexthop->ifindex = 0;
950 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
951 }
952 break;
953 case NEXTHOP_TYPE_IPV4:
954 case NEXTHOP_TYPE_IPV4_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000955 family = AFI_IP;
paul718e3742002-12-13 20:15:29 +0000956 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
957 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
958 else
959 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
960 break;
961#ifdef HAVE_IPV6
962 case NEXTHOP_TYPE_IPV6:
Paul Jakma7514fb72007-05-02 16:05:35 +0000963 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000964 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
965 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
966 else
967 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
968 break;
969 case NEXTHOP_TYPE_IPV6_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000970 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000971 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
972 {
973 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000974 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000975 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
976 else
977 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
978 }
979 else
980 {
981 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
982 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
983 else
984 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
985 }
986 break;
987#endif /* HAVE_IPV6 */
paul595db7f2003-05-25 21:35:06 +0000988 case NEXTHOP_TYPE_BLACKHOLE:
989 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
990 break;
paul718e3742002-12-13 20:15:29 +0000991 default:
992 break;
993 }
Paul Jakma7514fb72007-05-02 16:05:35 +0000994 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
995 return 0;
996
997 if (RIB_SYSTEM_ROUTE(rib) ||
998 (family == AFI_IP && rn->p.family != AF_INET) ||
999 (family == AFI_IP6 && rn->p.family != AF_INET6))
1000 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1001
1002 rmap = 0;
1003 if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
1004 proto_rm[family][rib->type])
1005 rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
1006 if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
1007 rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
1008 if (rmap) {
1009 ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, nexthop);
1010 }
1011
1012 if (ret == RMAP_DENYMATCH)
1013 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
paul718e3742002-12-13 20:15:29 +00001014 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
1015}
1016
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001017/* Iterate over all nexthops of the given RIB entry and refresh their
1018 * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
1019 * nexthop is found to toggle the ACTIVE flag, the whole rib structure
1020 * is flagged with ZEBRA_FLAG_CHANGED. The 4th 'set' argument is
1021 * transparently passed to nexthop_active_check().
1022 *
1023 * Return value is the new number of active nexthops.
1024 */
1025
paula1ac18c2005-06-28 17:17:12 +00001026static int
paul718e3742002-12-13 20:15:29 +00001027nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
1028{
1029 struct nexthop *nexthop;
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001030 unsigned int prev_active, prev_index, new_active;
paul718e3742002-12-13 20:15:29 +00001031
1032 rib->nexthop_active_num = 0;
1033 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1034
1035 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001036 {
1037 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001038 prev_index = nexthop->ifindex;
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001039 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
1040 rib->nexthop_active_num++;
Joakim Tjernlundc3a56062009-06-24 19:15:36 +02001041 if (prev_active != new_active ||
1042 prev_index != nexthop->ifindex)
Denis Ovsienko03e232a2007-08-14 09:46:48 +00001043 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
1044 }
paul718e3742002-12-13 20:15:29 +00001045 return rib->nexthop_active_num;
1046}
paul6baeb982003-10-28 03:47:15 +00001047
paul718e3742002-12-13 20:15:29 +00001048
paul718e3742002-12-13 20:15:29 +00001049
paula1ac18c2005-06-28 17:17:12 +00001050static void
paul718e3742002-12-13 20:15:29 +00001051rib_install_kernel (struct route_node *rn, struct rib *rib)
1052{
1053 int ret = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001054 struct nexthop *nexthop, *tnexthop;
1055 int recursing;
paul718e3742002-12-13 20:15:29 +00001056
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001057 /*
1058 * Make sure we update the FPM any time we send new information to
1059 * the kernel.
1060 */
1061 zfpm_trigger_update (rn, "installing in kernel");
paul718e3742002-12-13 20:15:29 +00001062 switch (PREFIX_FAMILY (&rn->p))
1063 {
1064 case AF_INET:
1065 ret = kernel_add_ipv4 (&rn->p, rib);
1066 break;
1067#ifdef HAVE_IPV6
1068 case AF_INET6:
1069 ret = kernel_add_ipv6 (&rn->p, rib);
1070 break;
1071#endif /* HAVE_IPV6 */
1072 }
1073
Denis Ovsienkodc958242007-08-13 16:03:06 +00001074 /* This condition is never met, if we are using rt_socket.c */
paul718e3742002-12-13 20:15:29 +00001075 if (ret < 0)
1076 {
Christian Frankefa713d92013-07-05 15:35:37 +00001077 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +00001078 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1079 }
1080}
1081
1082/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001083static int
paul718e3742002-12-13 20:15:29 +00001084rib_uninstall_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, "uninstalling from kernel");
1095
paul718e3742002-12-13 20:15:29 +00001096 switch (PREFIX_FAMILY (&rn->p))
1097 {
1098 case AF_INET:
1099 ret = kernel_delete_ipv4 (&rn->p, rib);
1100 break;
1101#ifdef HAVE_IPV6
1102 case AF_INET6:
1103 ret = kernel_delete_ipv6 (&rn->p, rib);
1104 break;
1105#endif /* HAVE_IPV6 */
1106 }
1107
Christian Frankefa713d92013-07-05 15:35:37 +00001108 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +00001109 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1110
1111 return ret;
1112}
1113
1114/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001115static void
paul718e3742002-12-13 20:15:29 +00001116rib_uninstall (struct route_node *rn, struct rib *rib)
1117{
1118 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1119 {
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001120 zfpm_trigger_update (rn, "rib_uninstall");
1121
paul718e3742002-12-13 20:15:29 +00001122 redistribute_delete (&rn->p, rib);
1123 if (! RIB_SYSTEM_ROUTE (rib))
1124 rib_uninstall_kernel (rn, rib);
1125 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
1126 }
1127}
1128
Paul Jakma6d691122006-07-27 21:49:00 +00001129static void rib_unlink (struct route_node *, struct rib *);
1130
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001131/*
1132 * rib_can_delete_dest
1133 *
1134 * Returns TRUE if the given dest can be deleted from the table.
1135 */
1136static int
1137rib_can_delete_dest (rib_dest_t *dest)
1138{
1139 if (dest->routes)
1140 {
1141 return 0;
1142 }
1143
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001144 /*
1145 * Don't delete the dest if we have to update the FPM about this
1146 * prefix.
1147 */
1148 if (CHECK_FLAG (dest->flags, RIB_DEST_UPDATE_FPM) ||
1149 CHECK_FLAG (dest->flags, RIB_DEST_SENT_TO_FPM))
1150 return 0;
1151
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001152 return 1;
1153}
1154
1155/*
1156 * rib_gc_dest
1157 *
1158 * Garbage collect the rib dest corresponding to the given route node
1159 * if appropriate.
1160 *
1161 * Returns TRUE if the dest was deleted, FALSE otherwise.
1162 */
1163int
1164rib_gc_dest (struct route_node *rn)
1165{
1166 rib_dest_t *dest;
1167 char buf[INET6_ADDRSTRLEN];
1168
1169 dest = rib_dest_from_rnode (rn);
1170 if (!dest)
1171 return 0;
1172
1173 if (!rib_can_delete_dest (dest))
1174 return 0;
1175
1176 if (IS_ZEBRA_DEBUG_RIB)
1177 {
1178 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, sizeof (buf));
1179 zlog_debug ("%s: %s/%d: removing dest from table", __func__,
1180 buf, rn->p.prefixlen);
1181 }
1182
1183 dest->rnode = NULL;
1184 XFREE (MTYPE_RIB_DEST, dest);
1185 rn->info = NULL;
1186
1187 /*
1188 * Release the one reference that we keep on the route node.
1189 */
1190 route_unlock_node (rn);
1191 return 1;
1192}
1193
paul718e3742002-12-13 20:15:29 +00001194/* Core function for processing routing information base. */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001195static void
1196rib_process (struct route_node *rn)
paul718e3742002-12-13 20:15:29 +00001197{
1198 struct rib *rib;
1199 struct rib *next;
1200 struct rib *fib = NULL;
1201 struct rib *select = NULL;
Paul Jakma6d691122006-07-27 21:49:00 +00001202 struct rib *del = NULL;
pauld753e9e2003-01-22 19:45:50 +00001203 int installed = 0;
Christian Frankefa713d92013-07-05 15:35:37 +00001204 struct nexthop *nexthop = NULL, *tnexthop;
1205 int recursing;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001206 char buf[INET6_ADDRSTRLEN];
paul4d38fdb2005-04-28 17:35:14 +00001207
1208 assert (rn);
1209
Paul Jakma93bdada2007-08-06 19:25:11 +00001210 if (IS_ZEBRA_DEBUG_RIB || IS_ZEBRA_DEBUG_RIB_Q)
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001211 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001212
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001213 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00001214 {
paul718e3742002-12-13 20:15:29 +00001215 /* Currently installed rib. */
1216 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Paul Jakma6d691122006-07-27 21:49:00 +00001217 {
1218 assert (fib == NULL);
1219 fib = rib;
1220 }
1221
1222 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1223 * which we need to do do further work with below.
1224 */
1225 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1226 {
1227 if (rib != fib)
1228 {
1229 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001230 zlog_debug ("%s: %s/%d: rn %p, removing rib %p", __func__,
1231 buf, rn->p.prefixlen, rn, rib);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001232 rib_unlink (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001233 }
1234 else
1235 del = rib;
1236
1237 continue;
1238 }
paul4d38fdb2005-04-28 17:35:14 +00001239
paul718e3742002-12-13 20:15:29 +00001240 /* Skip unreachable nexthop. */
1241 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +00001242 continue;
paul718e3742002-12-13 20:15:29 +00001243
1244 /* Infinit distance. */
1245 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +00001246 continue;
paul718e3742002-12-13 20:15:29 +00001247
paulaf887b52006-01-18 14:52:52 +00001248 /* Newly selected rib, the common case. */
1249 if (!select)
1250 {
1251 select = rib;
1252 continue;
1253 }
1254
1255 /* filter route selection in following order:
paulaf887b52006-01-18 14:52:52 +00001256 * - connected beats other types
paula8d9c1f2006-01-25 06:31:04 +00001257 * - lower distance beats higher
paulaf887b52006-01-18 14:52:52 +00001258 * - lower metric beats higher for equal distance
1259 * - last, hence oldest, route wins tie break.
1260 */
paula1038a12006-01-30 14:08:51 +00001261
1262 /* Connected routes. Pick the last connected
1263 * route of the set of lowest metric connected routes.
1264 */
paula8d9c1f2006-01-25 06:31:04 +00001265 if (rib->type == ZEBRA_ROUTE_CONNECT)
1266 {
paula1038a12006-01-30 14:08:51 +00001267 if (select->type != ZEBRA_ROUTE_CONNECT
paula8d9c1f2006-01-25 06:31:04 +00001268 || rib->metric <= select->metric)
paula1038a12006-01-30 14:08:51 +00001269 select = rib;
1270 continue;
paula8d9c1f2006-01-25 06:31:04 +00001271 }
1272 else if (select->type == ZEBRA_ROUTE_CONNECT)
1273 continue;
1274
1275 /* higher distance loses */
1276 if (rib->distance > select->distance)
1277 continue;
1278
1279 /* lower wins */
1280 if (rib->distance < select->distance)
1281 {
paulaf887b52006-01-18 14:52:52 +00001282 select = rib;
paula8d9c1f2006-01-25 06:31:04 +00001283 continue;
1284 }
1285
1286 /* metric tie-breaks equal distance */
1287 if (rib->metric <= select->metric)
1288 select = rib;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001289 } /* RNODE_FOREACH_RIB_SAFE */
Denis Ovsienkodc958242007-08-13 16:03:06 +00001290
1291 /* After the cycle is finished, the following pointers will be set:
1292 * select --- the winner RIB entry, if any was found, otherwise NULL
1293 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1294 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1295 * rib --- NULL
1296 */
1297
1298 /* Same RIB entry is selected. Update FIB and finish. */
paul718e3742002-12-13 20:15:29 +00001299 if (select && select == fib)
1300 {
Paul Jakma6d691122006-07-27 21:49:00 +00001301 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001302 zlog_debug ("%s: %s/%d: Updating existing route, select %p, fib %p",
1303 __func__, buf, rn->p.prefixlen, select, fib);
paul718e3742002-12-13 20:15:29 +00001304 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +00001305 {
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001306 zfpm_trigger_update (rn, "updating existing route");
1307
paul4d38fdb2005-04-28 17:35:14 +00001308 redistribute_delete (&rn->p, select);
1309 if (! RIB_SYSTEM_ROUTE (select))
1310 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001311
paul4d38fdb2005-04-28 17:35:14 +00001312 /* Set real nexthop. */
1313 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +00001314
paul4d38fdb2005-04-28 17:35:14 +00001315 if (! RIB_SYSTEM_ROUTE (select))
1316 rib_install_kernel (rn, select);
1317 redistribute_add (&rn->p, select);
1318 }
pauld753e9e2003-01-22 19:45:50 +00001319 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001320 {
1321 /* Housekeeping code to deal with
1322 race conditions in kernel with linux
1323 netlink reporting interface up before IPv4 or IPv6 protocol
1324 is ready to add routes.
1325 This makes sure the routes are IN the kernel.
1326 */
pauld753e9e2003-01-22 19:45:50 +00001327
Christian Frankefa713d92013-07-05 15:35:37 +00001328 for (ALL_NEXTHOPS_RO(select->nexthop, nexthop, tnexthop, recursing))
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001329 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
paul4d38fdb2005-04-28 17:35:14 +00001330 {
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001331 installed = 1;
1332 break;
paul4d38fdb2005-04-28 17:35:14 +00001333 }
1334 if (! installed)
1335 rib_install_kernel (rn, select);
1336 }
Paul Jakma6d691122006-07-27 21:49:00 +00001337 goto end;
paul718e3742002-12-13 20:15:29 +00001338 }
1339
Denis Ovsienkodc958242007-08-13 16:03:06 +00001340 /* At this point we either haven't found the best RIB entry or it is
1341 * different from what we currently intend to flag with SELECTED. In both
1342 * cases, if a RIB block is present in FIB, it should be withdrawn.
1343 */
paul718e3742002-12-13 20:15:29 +00001344 if (fib)
1345 {
Paul Jakma6d691122006-07-27 21:49:00 +00001346 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001347 zlog_debug ("%s: %s/%d: Removing existing route, fib %p", __func__,
1348 buf, rn->p.prefixlen, fib);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001349
1350 zfpm_trigger_update (rn, "removing existing route");
1351
paul718e3742002-12-13 20:15:29 +00001352 redistribute_delete (&rn->p, fib);
1353 if (! RIB_SYSTEM_ROUTE (fib))
1354 rib_uninstall_kernel (rn, fib);
1355 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1356
1357 /* Set real nexthop. */
1358 nexthop_active_update (rn, fib, 1);
1359 }
1360
Denis Ovsienkodc958242007-08-13 16:03:06 +00001361 /* Regardless of some RIB entry being SELECTED or not before, now we can
1362 * tell, that if a new winner exists, FIB is still not updated with this
1363 * data, but ready to be.
1364 */
paul718e3742002-12-13 20:15:29 +00001365 if (select)
1366 {
Paul Jakma6d691122006-07-27 21:49:00 +00001367 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001368 zlog_debug ("%s: %s/%d: Adding route, select %p", __func__, buf,
1369 rn->p.prefixlen, select);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001370
1371 zfpm_trigger_update (rn, "new route selected");
1372
paul718e3742002-12-13 20:15:29 +00001373 /* Set real nexthop. */
1374 nexthop_active_update (rn, select, 1);
1375
1376 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001377 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001378 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1379 redistribute_add (&rn->p, select);
1380 }
paul4d38fdb2005-04-28 17:35:14 +00001381
Paul Jakma6d691122006-07-27 21:49:00 +00001382 /* FIB route was removed, should be deleted */
1383 if (del)
1384 {
1385 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001386 zlog_debug ("%s: %s/%d: Deleting fib %p, rn %p", __func__, buf,
1387 rn->p.prefixlen, del, rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001388 rib_unlink (rn, del);
1389 }
paul4d38fdb2005-04-28 17:35:14 +00001390
Paul Jakma6d691122006-07-27 21:49:00 +00001391end:
1392 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma93bdada2007-08-06 19:25:11 +00001393 zlog_debug ("%s: %s/%d: rn %p dequeued", __func__, buf, rn->p.prefixlen, rn);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001394
1395 /*
1396 * Check if the dest can be deleted now.
1397 */
1398 rib_gc_dest (rn);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001399}
1400
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001401/* Take a list of route_node structs and return 1, if there was a record
1402 * picked from it and processed by rib_process(). Don't process more,
1403 * than one RN record; operate only in the specified sub-queue.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001404 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001405static unsigned int
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001406process_subq (struct list * subq, u_char qindex)
1407{
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001408 struct listnode *lnode = listhead (subq);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001409 struct route_node *rnode;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001410
1411 if (!lnode)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001412 return 0;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001413
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001414 rnode = listgetdata (lnode);
1415 rib_process (rnode);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001416
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001417 if (rnode->info)
1418 UNSET_FLAG (rib_dest_from_rnode (rnode)->flags, RIB_ROUTE_QUEUED (qindex));
1419
Chris Caputo67b94672009-07-18 04:02:26 +00001420#if 0
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001421 else
1422 {
1423 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1424 __func__, rnode, rnode->lock);
1425 zlog_backtrace(LOG_DEBUG);
1426 }
Chris Caputo67b94672009-07-18 04:02:26 +00001427#endif
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001428 route_unlock_node (rnode);
1429 list_delete_node (subq, lnode);
1430 return 1;
1431}
1432
1433/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1434 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1435 * is pointed to the meta queue structure.
1436 */
1437static wq_item_status
1438meta_queue_process (struct work_queue *dummy, void *data)
1439{
1440 struct meta_queue * mq = data;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001441 unsigned i;
1442
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001443 for (i = 0; i < MQ_SIZE; i++)
1444 if (process_subq (mq->subq[i], i))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001445 {
1446 mq->size--;
1447 break;
1448 }
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001449 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1450}
1451
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001452/*
1453 * Map from rib types to queue type (priority) in meta queue
1454 */
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001455static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
1456 [ZEBRA_ROUTE_SYSTEM] = 4,
1457 [ZEBRA_ROUTE_KERNEL] = 0,
1458 [ZEBRA_ROUTE_CONNECT] = 0,
1459 [ZEBRA_ROUTE_STATIC] = 1,
1460 [ZEBRA_ROUTE_RIP] = 2,
1461 [ZEBRA_ROUTE_RIPNG] = 2,
1462 [ZEBRA_ROUTE_OSPF] = 2,
1463 [ZEBRA_ROUTE_OSPF6] = 2,
1464 [ZEBRA_ROUTE_ISIS] = 2,
1465 [ZEBRA_ROUTE_BGP] = 3,
1466 [ZEBRA_ROUTE_HSLS] = 4,
Paul Jakma57345092011-12-25 17:52:09 +01001467 [ZEBRA_ROUTE_BABEL] = 2,
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001468};
1469
1470/* Look into the RN and queue it into one or more priority queues,
1471 * increasing the size for each data push done.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001472 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001473static void
1474rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001475{
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001476 struct rib *rib;
1477 char buf[INET6_ADDRSTRLEN];
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001478
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001479 if (IS_ZEBRA_DEBUG_RIB_Q)
1480 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001481
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001482 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001483 {
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001484 u_char qindex = meta_queue_map[rib->type];
1485
1486 /* Invariant: at this point we always have rn->info set. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001487 if (CHECK_FLAG (rib_dest_from_rnode (rn)->flags,
1488 RIB_ROUTE_QUEUED (qindex)))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001489 {
1490 if (IS_ZEBRA_DEBUG_RIB_Q)
1491 zlog_debug ("%s: %s/%d: rn %p is already queued in sub-queue %u",
1492 __func__, buf, rn->p.prefixlen, rn, qindex);
1493 continue;
1494 }
1495
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001496 SET_FLAG (rib_dest_from_rnode (rn)->flags, RIB_ROUTE_QUEUED (qindex));
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001497 listnode_add (mq->subq[qindex], rn);
1498 route_lock_node (rn);
1499 mq->size++;
1500
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001501 if (IS_ZEBRA_DEBUG_RIB_Q)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001502 zlog_debug ("%s: %s/%d: queued rn %p into sub-queue %u",
1503 __func__, buf, rn->p.prefixlen, rn, qindex);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001504 }
paul4d38fdb2005-04-28 17:35:14 +00001505}
1506
Paul Jakma6d691122006-07-27 21:49:00 +00001507/* Add route_node to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001508static void
Paul Jakma6d691122006-07-27 21:49:00 +00001509rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
paul4d38fdb2005-04-28 17:35:14 +00001510{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001511 char buf[INET_ADDRSTRLEN];
1512 assert (zebra && rn);
paul4d38fdb2005-04-28 17:35:14 +00001513
Paul Jakma93bdada2007-08-06 19:25:11 +00001514 if (IS_ZEBRA_DEBUG_RIB_Q)
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001515 inet_ntop (AF_INET, &rn->p.u.prefix, buf, INET_ADDRSTRLEN);
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001516
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001517 /* Pointless to queue a route_node with no RIB entries to add or remove */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001518 if (!rnode_to_ribs (rn))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001519 {
1520 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1521 __func__, rn, rn->lock);
1522 zlog_backtrace(LOG_DEBUG);
1523 return;
1524 }
1525
1526 if (IS_ZEBRA_DEBUG_RIB_Q)
1527 zlog_info ("%s: %s/%d: work queue added", __func__, buf, rn->p.prefixlen);
1528
1529 assert (zebra);
1530
1531 if (zebra->ribq == NULL)
1532 {
1533 zlog_err ("%s: work_queue does not exist!", __func__);
1534 return;
Paul Jakma6d691122006-07-27 21:49:00 +00001535 }
paul4d38fdb2005-04-28 17:35:14 +00001536
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001537 /*
1538 * The RIB queue should normally be either empty or holding the only
1539 * work_queue_item element. In the latter case this element would
1540 * hold a pointer to the meta queue structure, which must be used to
1541 * actually queue the route nodes to process. So create the MQ
1542 * holder, if necessary, then push the work into it in any case.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001543 * This semantics was introduced after 0.99.9 release.
1544 */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001545 if (!zebra->ribq->items->count)
1546 work_queue_add (zebra->ribq, zebra->mq);
1547
1548 rib_meta_queue_add (zebra->mq, rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001549
1550 if (IS_ZEBRA_DEBUG_RIB_Q)
1551 zlog_debug ("%s: %s/%d: rn %p queued", __func__, buf, rn->p.prefixlen, rn);
1552
1553 return;
paul4d38fdb2005-04-28 17:35:14 +00001554}
1555
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001556/* Create new meta queue.
1557 A destructor function doesn't seem to be necessary here.
1558 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001559static struct meta_queue *
1560meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001561{
1562 struct meta_queue *new;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001563 unsigned i;
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001564
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001565 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1566 assert(new);
1567
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001568 for (i = 0; i < MQ_SIZE; i++)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001569 {
1570 new->subq[i] = list_new ();
1571 assert(new->subq[i]);
1572 }
1573
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001574 return new;
1575}
1576
paul4d38fdb2005-04-28 17:35:14 +00001577/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001578static void
paul4d38fdb2005-04-28 17:35:14 +00001579rib_queue_init (struct zebra_t *zebra)
1580{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001581 assert (zebra);
1582
paul4d38fdb2005-04-28 17:35:14 +00001583 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001584 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001585 {
Paul Jakma6d691122006-07-27 21:49:00 +00001586 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001587 return;
1588 }
1589
1590 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001591 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001592 zebra->ribq->spec.errorfunc = NULL;
paul4d38fdb2005-04-28 17:35:14 +00001593 /* XXX: TODO: These should be runtime configurable via vty */
1594 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001595 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001596
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001597 if (!(zebra->mq = meta_queue_new ()))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001598 {
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001599 zlog_err ("%s: could not initialise meta queue!", __func__);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001600 return;
1601 }
1602 return;
paul718e3742002-12-13 20:15:29 +00001603}
1604
Paul Jakma6d691122006-07-27 21:49:00 +00001605/* RIB updates are processed via a queue of pointers to route_nodes.
1606 *
1607 * The queue length is bounded by the maximal size of the routing table,
1608 * as a route_node will not be requeued, if already queued.
1609 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001610 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1611 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1612 * and then submit route_node to queue for best-path selection later.
1613 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001614 *
1615 * Deleted RIBs are reaped during best-path selection.
1616 *
1617 * rib_addnode
1618 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001619 * |-------->| | best RIB, if required
1620 * | |
1621 * static_install->|->rib_addqueue...... -> rib_process
1622 * | |
1623 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001624 * |-> set RIB_ENTRY_REMOVE |
1625 * rib_delnode (RIB freed)
1626 *
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001627 * The 'info' pointer of a route_node points to a rib_dest_t
1628 * ('dest'). Queueing state for a route_node is kept on the dest. The
1629 * dest is created on-demand by rib_link() and is kept around at least
1630 * as long as there are ribs hanging off it (@see rib_gc_dest()).
Paul Jakma6d691122006-07-27 21:49:00 +00001631 *
1632 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1633 *
1634 * - route_nodes: refcounted by:
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001635 * - dest attached to route_node:
1636 * - managed by: rib_link/rib_gc_dest
Paul Jakma6d691122006-07-27 21:49:00 +00001637 * - route_node processing queue
1638 * - managed by: rib_addqueue, rib_process.
1639 *
1640 */
1641
paul718e3742002-12-13 20:15:29 +00001642/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001643static void
Paul Jakma6d691122006-07-27 21:49:00 +00001644rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001645{
1646 struct rib *head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001647 rib_dest_t *dest;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001648 char buf[INET6_ADDRSTRLEN];
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001649
paul4d38fdb2005-04-28 17:35:14 +00001650 assert (rib && rn);
1651
Paul Jakma6d691122006-07-27 21:49:00 +00001652 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001653 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001654 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001655 zlog_debug ("%s: %s/%d: rn %p, rib %p", __func__,
1656 buf, rn->p.prefixlen, rn, rib);
1657 }
Paul Jakma6d691122006-07-27 21:49:00 +00001658
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001659 dest = rib_dest_from_rnode (rn);
1660 if (!dest)
Paul Jakma6d691122006-07-27 21:49:00 +00001661 {
1662 if (IS_ZEBRA_DEBUG_RIB)
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001663 {
1664 zlog_debug ("%s: %s/%d: adding dest to table", __func__,
1665 buf, rn->p.prefixlen);
1666 }
1667
1668 dest = XCALLOC (MTYPE_RIB_DEST, sizeof (rib_dest_t));
1669 route_lock_node (rn); /* rn route table reference */
1670 rn->info = dest;
1671 dest->rnode = rn;
1672 }
1673
1674 head = dest->routes;
1675 if (head)
1676 {
Paul Jakma6d691122006-07-27 21:49:00 +00001677 head->prev = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001678 }
paul718e3742002-12-13 20:15:29 +00001679 rib->next = head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001680 dest->routes = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001681 rib_queue_add (&zebrad, rn);
1682}
1683
1684static void
1685rib_addnode (struct route_node *rn, struct rib *rib)
1686{
1687 /* RIB node has been un-removed before route-node is processed.
1688 * route_node must hence already be on the queue for processing..
1689 */
1690 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1691 {
1692 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001693 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001694 char buf[INET6_ADDRSTRLEN];
1695 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001696 zlog_debug ("%s: %s/%d: rn %p, un-removed rib %p",
1697 __func__, buf, rn->p.prefixlen, rn, rib);
1698 }
Paul Jakma6d691122006-07-27 21:49:00 +00001699 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1700 return;
1701 }
1702 rib_link (rn, rib);
1703}
1704
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001705/*
1706 * rib_unlink
1707 *
1708 * Detach a rib structure from a route_node.
1709 *
1710 * Note that a call to rib_unlink() should be followed by a call to
1711 * rib_gc_dest() at some point. This allows a rib_dest_t that is no
1712 * longer required to be deleted.
1713 */
Paul Jakma6d691122006-07-27 21:49:00 +00001714static void
1715rib_unlink (struct route_node *rn, struct rib *rib)
1716{
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001717 char buf[INET6_ADDRSTRLEN];
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001718 rib_dest_t *dest;
Paul Jakma6d691122006-07-27 21:49:00 +00001719
1720 assert (rn && rib);
1721
1722 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001723 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001724 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001725 zlog_debug ("%s: %s/%d: rn %p, rib %p",
1726 __func__, buf, rn->p.prefixlen, rn, rib);
1727 }
Paul Jakma6d691122006-07-27 21:49:00 +00001728
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001729 dest = rib_dest_from_rnode (rn);
1730
Paul Jakma6d691122006-07-27 21:49:00 +00001731 if (rib->next)
1732 rib->next->prev = rib->prev;
1733
1734 if (rib->prev)
1735 rib->prev->next = rib->next;
1736 else
1737 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001738 dest->routes = rib->next;
Paul Jakma6d691122006-07-27 21:49:00 +00001739 }
1740
1741 /* free RIB and nexthops */
Christian Frankefa713d92013-07-05 15:35:37 +00001742 nexthops_free(rib->nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00001743 XFREE (MTYPE_RIB, rib);
1744
paul718e3742002-12-13 20:15:29 +00001745}
1746
paula1ac18c2005-06-28 17:17:12 +00001747static void
paul718e3742002-12-13 20:15:29 +00001748rib_delnode (struct route_node *rn, struct rib *rib)
1749{
Paul Jakma6d691122006-07-27 21:49:00 +00001750 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001751 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001752 char buf[INET6_ADDRSTRLEN];
1753 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001754 zlog_debug ("%s: %s/%d: rn %p, rib %p, removing", __func__,
1755 buf, rn->p.prefixlen, rn, rib);
1756 }
Paul Jakma6d691122006-07-27 21:49:00 +00001757 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1758 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001759}
1760
1761int
1762rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001763 struct in_addr *gate, struct in_addr *src,
1764 unsigned int ifindex, u_int32_t vrf_id,
G.Balajicddf3912011-11-26 21:59:32 +04001765 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001766{
1767 struct rib *rib;
1768 struct rib *same = NULL;
1769 struct route_table *table;
1770 struct route_node *rn;
1771 struct nexthop *nexthop;
1772
1773 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04001774 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00001775 if (! table)
1776 return 0;
1777
1778 /* Make it sure prefixlen is applied to the prefix. */
1779 apply_mask_ipv4 (p);
1780
1781 /* Set default distance by route type. */
1782 if (distance == 0)
1783 {
Balaji.G837d16c2012-09-26 14:09:10 +05301784 if ((unsigned)type >= array_size(route_info))
David Lamparter7052f222009-08-27 00:28:28 +02001785 distance = 150;
1786 else
1787 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00001788
1789 /* iBGP distance is 200. */
1790 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1791 distance = 200;
1792 }
1793
1794 /* Lookup route node.*/
1795 rn = route_node_get (table, (struct prefix *) p);
1796
1797 /* If same type of route are installed, treat it as a implicit
1798 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001799 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00001800 {
Paul Jakma6d691122006-07-27 21:49:00 +00001801 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1802 continue;
1803
hassoebf1ead2005-09-21 14:58:20 +00001804 if (rib->type != type)
1805 continue;
1806 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001807 {
1808 same = rib;
1809 break;
1810 }
hassoebf1ead2005-09-21 14:58:20 +00001811 /* Duplicate connected route comes in. */
1812 else if ((nexthop = rib->nexthop) &&
1813 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001814 nexthop->ifindex == ifindex &&
1815 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001816 {
1817 rib->refcnt++;
1818 return 0 ;
1819 }
paul718e3742002-12-13 20:15:29 +00001820 }
1821
1822 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001823 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001824 rib->type = type;
1825 rib->distance = distance;
1826 rib->flags = flags;
1827 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001828 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001829 rib->nexthop_num = 0;
1830 rib->uptime = time (NULL);
1831
1832 /* Nexthop settings. */
1833 if (gate)
1834 {
1835 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001836 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001837 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001838 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001839 }
1840 else
1841 nexthop_ifindex_add (rib, ifindex);
1842
1843 /* If this route is kernel route, set FIB flag to the route. */
1844 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1845 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1846 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1847
1848 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001849 if (IS_ZEBRA_DEBUG_RIB)
1850 zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
paul718e3742002-12-13 20:15:29 +00001851 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001852
paul718e3742002-12-13 20:15:29 +00001853 /* Free implicit route.*/
1854 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001855 {
1856 if (IS_ZEBRA_DEBUG_RIB)
1857 zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001858 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001859 }
paul4d38fdb2005-04-28 17:35:14 +00001860
1861 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001862 return 0;
1863}
1864
Denis Ovsienkodc958242007-08-13 16:03:06 +00001865/* This function dumps the contents of a given RIB entry into
1866 * standard debug log. Calling function name and IP prefix in
1867 * question are passed as 1st and 2nd arguments.
1868 */
1869
1870void rib_dump (const char * func, const struct prefix_ipv4 * p, const struct rib * rib)
1871{
Christian Frankefa713d92013-07-05 15:35:37 +00001872 char straddr[INET_ADDRSTRLEN];
1873 struct nexthop *nexthop, *tnexthop;
1874 int recursing;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001875
Christian Frankefa713d92013-07-05 15:35:37 +00001876 inet_ntop (AF_INET, &p->prefix, straddr, INET_ADDRSTRLEN);
1877 zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr, p->prefixlen);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001878 zlog_debug
1879 (
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001880 "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
Denis Ovsienkodc958242007-08-13 16:03:06 +00001881 func,
1882 rib->refcnt,
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001883 (unsigned long) rib->uptime,
Denis Ovsienkodc958242007-08-13 16:03:06 +00001884 rib->type,
1885 rib->table
1886 );
1887 zlog_debug
1888 (
1889 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1890 func,
1891 rib->metric,
1892 rib->distance,
1893 rib->flags,
1894 rib->status
1895 );
1896 zlog_debug
1897 (
1898 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1899 func,
1900 rib->nexthop_num,
1901 rib->nexthop_active_num,
1902 rib->nexthop_fib_num
1903 );
Christian Frankefa713d92013-07-05 15:35:37 +00001904 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1905 {
1906 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, straddr, INET_ADDRSTRLEN);
1907 zlog_debug
1908 (
1909 "%s: %s %s with flags %s%s%s",
1910 func,
1911 (recursing ? " NH" : "NH"),
1912 straddr,
1913 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1914 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1915 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1916 );
1917 }
Denis Ovsienkodc958242007-08-13 16:03:06 +00001918 zlog_debug ("%s: dump complete", func);
1919}
1920
1921/* This is an exported helper to rtm_read() to dump the strange
1922 * RIB entry found by rib_lookup_ipv4_route()
1923 */
1924
1925void rib_lookup_and_dump (struct prefix_ipv4 * p)
1926{
1927 struct route_table *table;
1928 struct route_node *rn;
1929 struct rib *rib;
1930 char prefix_buf[INET_ADDRSTRLEN];
1931
1932 /* Lookup table. */
1933 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1934 if (! table)
1935 {
1936 zlog_err ("%s: vrf_table() returned NULL", __func__);
1937 return;
1938 }
1939
1940 inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
1941 /* Scan the RIB table for exactly matching RIB entry. */
1942 rn = route_node_lookup (table, (struct prefix *) p);
1943
1944 /* No route for this prefix. */
1945 if (! rn)
1946 {
1947 zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
1948 return;
1949 }
1950
1951 /* Unlock node. */
1952 route_unlock_node (rn);
1953
1954 /* let's go */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001955 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001956 {
1957 zlog_debug
1958 (
1959 "%s: rn %p, rib %p: %s, %s",
1960 __func__,
1961 rn,
1962 rib,
1963 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
1964 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
1965 );
1966 rib_dump (__func__, p, rib);
1967 }
1968}
1969
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001970/* Check if requested address assignment will fail due to another
1971 * route being installed by zebra in FIB already. Take necessary
1972 * actions, if needed: remove such a route from FIB and deSELECT
1973 * corresponding RIB entry. Then put affected RN into RIBQ head.
1974 */
1975void rib_lookup_and_pushup (struct prefix_ipv4 * p)
1976{
1977 struct route_table *table;
1978 struct route_node *rn;
1979 struct rib *rib;
1980 unsigned changed = 0;
1981
1982 if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
1983 {
1984 zlog_err ("%s: vrf_table() returned NULL", __func__);
1985 return;
1986 }
1987
1988 /* No matches would be the simplest case. */
1989 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
1990 return;
1991
1992 /* Unlock node. */
1993 route_unlock_node (rn);
1994
1995 /* Check all RIB entries. In case any changes have to be done, requeue
1996 * the RN into RIBQ head. If the routing message about the new connected
1997 * route (generated by the IP address we are going to assign very soon)
1998 * comes before the RIBQ is processed, the new RIB entry will join
1999 * RIBQ record already on head. This is necessary for proper revalidation
2000 * of the rest of the RIB.
2001 */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002002 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002003 {
2004 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
2005 ! RIB_SYSTEM_ROUTE (rib))
2006 {
2007 changed = 1;
2008 if (IS_ZEBRA_DEBUG_RIB)
2009 {
2010 char buf[INET_ADDRSTRLEN];
2011 inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
2012 zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
2013 rib_dump (__func__, (struct prefix_ipv4 *)&rn->p, rib);
2014 }
2015 rib_uninstall (rn, rib);
2016 }
2017 }
2018 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002019 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00002020}
2021
paul718e3742002-12-13 20:15:29 +00002022int
G.Balajicddf3912011-11-26 21:59:32 +04002023rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002024{
2025 struct route_table *table;
2026 struct route_node *rn;
2027 struct rib *same;
2028 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00002029
paul718e3742002-12-13 20:15:29 +00002030 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04002031 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00002032 if (! table)
2033 return 0;
G.Balajicddf3912011-11-26 21:59:32 +04002034
paul718e3742002-12-13 20:15:29 +00002035 /* Make it sure prefixlen is applied to the prefix. */
2036 apply_mask_ipv4 (p);
2037
2038 /* Set default distance by route type. */
2039 if (rib->distance == 0)
2040 {
2041 rib->distance = route_info[rib->type].distance;
2042
2043 /* iBGP distance is 200. */
2044 if (rib->type == ZEBRA_ROUTE_BGP
2045 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
2046 rib->distance = 200;
2047 }
2048
2049 /* Lookup route node.*/
2050 rn = route_node_get (table, (struct prefix *) p);
2051
2052 /* If same type of route are installed, treat it as a implicit
2053 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002054 RNODE_FOREACH_RIB (rn, same)
paul718e3742002-12-13 20:15:29 +00002055 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00002056 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00002057 continue;
2058
paul718e3742002-12-13 20:15:29 +00002059 if (same->type == rib->type && same->table == rib->table
2060 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00002061 break;
paul718e3742002-12-13 20:15:29 +00002062 }
paul4d38fdb2005-04-28 17:35:14 +00002063
paul718e3742002-12-13 20:15:29 +00002064 /* If this route is kernel route, set FIB flag to the route. */
2065 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
2066 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2067 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2068
2069 /* Link new rib to node.*/
2070 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002071 if (IS_ZEBRA_DEBUG_RIB)
2072 {
2073 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
2074 __func__, rn, rib);
2075 rib_dump (__func__, p, rib);
2076 }
paul718e3742002-12-13 20:15:29 +00002077
paul718e3742002-12-13 20:15:29 +00002078 /* Free implicit route.*/
2079 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00002080 {
2081 if (IS_ZEBRA_DEBUG_RIB)
2082 {
2083 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
2084 __func__, rn, same);
2085 rib_dump (__func__, p, same);
2086 }
paul4d38fdb2005-04-28 17:35:14 +00002087 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002088 }
paul4d38fdb2005-04-28 17:35:14 +00002089
2090 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002091 return 0;
2092}
2093
hassoebf1ead2005-09-21 14:58:20 +00002094/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002095int
2096rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
G.Balajicddf3912011-11-26 21:59:32 +04002097 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002098{
2099 struct route_table *table;
2100 struct route_node *rn;
2101 struct rib *rib;
2102 struct rib *fib = NULL;
2103 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002104 struct nexthop *nexthop, *tnexthop;
2105 int recursing;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002106 char buf1[INET_ADDRSTRLEN];
2107 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002108
2109 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04002110 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00002111 if (! table)
2112 return 0;
2113
2114 /* Apply mask. */
2115 apply_mask_ipv4 (p);
2116
paul5ec90d22003-06-19 01:41:37 +00002117 if (IS_ZEBRA_DEBUG_KERNEL && gate)
ajsb6178002004-12-07 21:12:56 +00002118 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002119 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul5ec90d22003-06-19 01:41:37 +00002120 p->prefixlen,
2121 inet_ntoa (*gate),
2122 ifindex);
2123
paul718e3742002-12-13 20:15:29 +00002124 /* Lookup route node. */
2125 rn = route_node_lookup (table, (struct prefix *) p);
2126 if (! rn)
2127 {
2128 if (IS_ZEBRA_DEBUG_KERNEL)
2129 {
2130 if (gate)
ajsb6178002004-12-07 21:12:56 +00002131 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002132 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002133 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002134 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002135 ifindex);
2136 else
ajsb6178002004-12-07 21:12:56 +00002137 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002138 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002139 p->prefixlen,
2140 ifindex);
2141 }
2142 return ZEBRA_ERR_RTNOEXIST;
2143 }
2144
2145 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002146 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002147 {
Paul Jakma6d691122006-07-27 21:49:00 +00002148 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2149 continue;
2150
paul718e3742002-12-13 20:15:29 +00002151 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2152 fib = rib;
2153
hassoebf1ead2005-09-21 14:58:20 +00002154 if (rib->type != type)
2155 continue;
2156 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002157 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002158 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002159 if (nexthop->ifindex != ifindex)
2160 continue;
hassoebf1ead2005-09-21 14:58:20 +00002161 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002162 {
hassoebf1ead2005-09-21 14:58:20 +00002163 rib->refcnt--;
2164 route_unlock_node (rn);
2165 route_unlock_node (rn);
2166 return 0;
paul718e3742002-12-13 20:15:29 +00002167 }
hassoebf1ead2005-09-21 14:58:20 +00002168 same = rib;
2169 break;
paul718e3742002-12-13 20:15:29 +00002170 }
hassoebf1ead2005-09-21 14:58:20 +00002171 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002172 else
paul5ec90d22003-06-19 01:41:37 +00002173 {
Christian Frankefa713d92013-07-05 15:35:37 +00002174 if (gate == NULL)
2175 {
2176 same = rib;
2177 break;
2178 }
2179 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2180 if (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate))
2181 {
2182 same = rib;
2183 break;
2184 }
2185 if (same)
2186 break;
2187 }
paul718e3742002-12-13 20:15:29 +00002188 }
paul718e3742002-12-13 20:15:29 +00002189 /* If same type of route can't be found and this message is from
2190 kernel. */
2191 if (! same)
2192 {
2193 if (fib && type == ZEBRA_ROUTE_KERNEL)
2194 {
2195 /* Unset flags. */
2196 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2197 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2198
2199 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2200 }
2201 else
2202 {
2203 if (IS_ZEBRA_DEBUG_KERNEL)
2204 {
2205 if (gate)
ajsb6178002004-12-07 21:12:56 +00002206 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002207 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002208 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002209 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002210 ifindex,
2211 type);
2212 else
ajsb6178002004-12-07 21:12:56 +00002213 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002214 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002215 p->prefixlen,
2216 ifindex,
2217 type);
2218 }
2219 route_unlock_node (rn);
2220 return ZEBRA_ERR_RTNOEXIST;
2221 }
2222 }
paul4d38fdb2005-04-28 17:35:14 +00002223
paul718e3742002-12-13 20:15:29 +00002224 if (same)
2225 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002226
paul718e3742002-12-13 20:15:29 +00002227 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002228 return 0;
2229}
2230
2231/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002232static void
paul718e3742002-12-13 20:15:29 +00002233static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
2234{
2235 struct rib *rib;
2236 struct route_node *rn;
2237 struct route_table *table;
2238
2239 /* Lookup table. */
2240 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2241 if (! table)
2242 return;
2243
2244 /* Lookup existing route */
2245 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002246 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002247 {
2248 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2249 continue;
2250
2251 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2252 break;
2253 }
paul718e3742002-12-13 20:15:29 +00002254
2255 if (rib)
2256 {
2257 /* Same distance static route is there. Update it with new
2258 nexthop. */
paul718e3742002-12-13 20:15:29 +00002259 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002260 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002261 {
2262 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002263 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002264 break;
2265 case STATIC_IPV4_IFNAME:
2266 nexthop_ifname_add (rib, si->gate.ifname);
2267 break;
2268 case STATIC_IPV4_BLACKHOLE:
2269 nexthop_blackhole_add (rib);
2270 break;
paul4d38fdb2005-04-28 17:35:14 +00002271 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002272 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002273 }
2274 else
2275 {
2276 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002277 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2278
paul718e3742002-12-13 20:15:29 +00002279 rib->type = ZEBRA_ROUTE_STATIC;
2280 rib->distance = si->distance;
2281 rib->metric = 0;
Nolan Leakeb0145dd2012-09-13 17:17:31 +00002282 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002283 rib->nexthop_num = 0;
2284
2285 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002286 {
2287 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002288 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002289 break;
2290 case STATIC_IPV4_IFNAME:
2291 nexthop_ifname_add (rib, si->gate.ifname);
2292 break;
2293 case STATIC_IPV4_BLACKHOLE:
2294 nexthop_blackhole_add (rib);
2295 break;
2296 }
paul718e3742002-12-13 20:15:29 +00002297
hasso81dfcaa2003-05-25 19:21:25 +00002298 /* Save the flags of this static routes (reject, blackhole) */
2299 rib->flags = si->flags;
2300
paul718e3742002-12-13 20:15:29 +00002301 /* Link this rib to the tree. */
2302 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002303 }
2304}
2305
paula1ac18c2005-06-28 17:17:12 +00002306static int
paul718e3742002-12-13 20:15:29 +00002307static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2308{
2309 if (nexthop->type == NEXTHOP_TYPE_IPV4
2310 && si->type == STATIC_IPV4_GATEWAY
2311 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2312 return 1;
2313 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2314 && si->type == STATIC_IPV4_IFNAME
2315 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2316 return 1;
paul595db7f2003-05-25 21:35:06 +00002317 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2318 && si->type == STATIC_IPV4_BLACKHOLE)
2319 return 1;
paule8e19462006-01-19 20:16:55 +00002320 return 0;
paul718e3742002-12-13 20:15:29 +00002321}
2322
2323/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002324static void
paul718e3742002-12-13 20:15:29 +00002325static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
2326{
2327 struct route_node *rn;
2328 struct rib *rib;
2329 struct nexthop *nexthop;
2330 struct route_table *table;
2331
2332 /* Lookup table. */
2333 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2334 if (! table)
2335 return;
paul4d38fdb2005-04-28 17:35:14 +00002336
paul718e3742002-12-13 20:15:29 +00002337 /* Lookup existing route with type and distance. */
2338 rn = route_node_lookup (table, p);
2339 if (! rn)
2340 return;
2341
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002342 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002343 {
2344 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2345 continue;
2346
2347 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2348 break;
2349 }
paul718e3742002-12-13 20:15:29 +00002350
2351 if (! rib)
2352 {
2353 route_unlock_node (rn);
2354 return;
2355 }
2356
2357 /* Lookup nexthop. */
2358 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2359 if (static_ipv4_nexthop_same (nexthop, si))
2360 break;
2361
2362 /* Can't find nexthop. */
2363 if (! nexthop)
2364 {
2365 route_unlock_node (rn);
2366 return;
2367 }
2368
2369 /* Check nexthop. */
2370 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002371 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002372 else
2373 {
paul6baeb982003-10-28 03:47:15 +00002374 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2375 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002376 nexthop_delete (rib, nexthop);
2377 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002378 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002379 }
paul718e3742002-12-13 20:15:29 +00002380 /* Unlock node. */
2381 route_unlock_node (rn);
2382}
2383
2384/* Add static route into static route configuration. */
2385int
hasso39db97e2004-10-12 20:50:58 +00002386static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00002387 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002388{
2389 u_char type = 0;
2390 struct route_node *rn;
2391 struct static_ipv4 *si;
2392 struct static_ipv4 *pp;
2393 struct static_ipv4 *cp;
2394 struct static_ipv4 *update = NULL;
2395 struct route_table *stable;
2396
2397 /* Lookup table. */
2398 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2399 if (! stable)
2400 return -1;
2401
2402 /* Lookup static route prefix. */
2403 rn = route_node_get (stable, p);
2404
2405 /* Make flags. */
2406 if (gate)
2407 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002408 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002409 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002410 else
2411 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002412
2413 /* Do nothing if there is a same static route. */
2414 for (si = rn->info; si; si = si->next)
2415 {
2416 if (type == si->type
2417 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2418 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2419 {
2420 if (distance == si->distance)
2421 {
2422 route_unlock_node (rn);
2423 return 0;
2424 }
2425 else
2426 update = si;
2427 }
2428 }
2429
Paul Jakma3c0755d2006-12-08 00:53:14 +00002430 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002431 if (update)
2432 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
2433
2434 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002435 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
paul718e3742002-12-13 20:15:29 +00002436
2437 si->type = type;
2438 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002439 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002440
2441 if (gate)
2442 si->gate.ipv4 = *gate;
2443 if (ifname)
2444 si->gate.ifname = XSTRDUP (0, ifname);
2445
2446 /* Add new static route information to the tree with sort by
2447 distance value and gateway address. */
2448 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2449 {
2450 if (si->distance < cp->distance)
2451 break;
2452 if (si->distance > cp->distance)
2453 continue;
2454 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2455 {
2456 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2457 break;
2458 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2459 continue;
2460 }
2461 }
2462
2463 /* Make linked list. */
2464 if (pp)
2465 pp->next = si;
2466 else
2467 rn->info = si;
2468 if (cp)
2469 cp->prev = si;
2470 si->prev = pp;
2471 si->next = cp;
2472
2473 /* Install into rib. */
2474 static_install_ipv4 (p, si);
2475
2476 return 1;
2477}
2478
2479/* Delete static route from static route configuration. */
2480int
hasso39db97e2004-10-12 20:50:58 +00002481static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00002482 u_char distance, u_int32_t vrf_id)
2483{
2484 u_char type = 0;
2485 struct route_node *rn;
2486 struct static_ipv4 *si;
2487 struct route_table *stable;
2488
2489 /* Lookup table. */
2490 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2491 if (! stable)
2492 return -1;
2493
2494 /* Lookup static route prefix. */
2495 rn = route_node_lookup (stable, p);
2496 if (! rn)
2497 return 0;
2498
2499 /* Make flags. */
2500 if (gate)
2501 type = STATIC_IPV4_GATEWAY;
2502 else if (ifname)
2503 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002504 else
2505 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002506
2507 /* Find same static route is the tree */
2508 for (si = rn->info; si; si = si->next)
2509 if (type == si->type
2510 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2511 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2512 break;
2513
2514 /* Can't find static route. */
2515 if (! si)
2516 {
2517 route_unlock_node (rn);
2518 return 0;
2519 }
2520
2521 /* Install into rib. */
2522 static_uninstall_ipv4 (p, si);
2523
2524 /* Unlink static route from linked list. */
2525 if (si->prev)
2526 si->prev->next = si->next;
2527 else
2528 rn->info = si->next;
2529 if (si->next)
2530 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002531 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002532
2533 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002534 if (ifname)
2535 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002536 XFREE (MTYPE_STATIC_IPV4, si);
2537
paul143a3852003-09-29 20:06:13 +00002538 route_unlock_node (rn);
2539
paul718e3742002-12-13 20:15:29 +00002540 return 1;
2541}
2542
2543
2544#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00002545static int
paul718e3742002-12-13 20:15:29 +00002546rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2547 struct in6_addr *gate, unsigned int ifindex, int table)
2548{
hasso726f9b22003-05-25 21:04:54 +00002549 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2550#if defined (MUSICA) || defined (LINUX)
2551 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2552 if (p->prefixlen == 96)
2553 return 0;
2554#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00002555 return 1;
hasso726f9b22003-05-25 21:04:54 +00002556 }
paul718e3742002-12-13 20:15:29 +00002557 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
2558 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
2559 {
2560 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
2561 return 1;
2562 }
2563 return 0;
2564}
2565
2566int
2567rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00002568 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
G.Balajif768f362011-11-26 22:10:39 +04002569 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002570{
2571 struct rib *rib;
2572 struct rib *same = NULL;
2573 struct route_table *table;
2574 struct route_node *rn;
2575 struct nexthop *nexthop;
2576
paul718e3742002-12-13 20:15:29 +00002577 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002578 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002579 if (! table)
2580 return 0;
2581
2582 /* Make sure mask is applied. */
2583 apply_mask_ipv6 (p);
2584
2585 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002586 if (!distance)
2587 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002588
2589 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2590 distance = 200;
2591
2592 /* Filter bogus route. */
2593 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
2594 return 0;
2595
2596 /* Lookup route node.*/
2597 rn = route_node_get (table, (struct prefix *) p);
2598
2599 /* If same type of route are installed, treat it as a implicit
2600 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002601 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002602 {
Paul Jakma6d691122006-07-27 21:49:00 +00002603 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2604 continue;
2605
hassoebf1ead2005-09-21 14:58:20 +00002606 if (rib->type != type)
2607 continue;
2608 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002609 {
2610 same = rib;
paul718e3742002-12-13 20:15:29 +00002611 break;
2612 }
hassoebf1ead2005-09-21 14:58:20 +00002613 else if ((nexthop = rib->nexthop) &&
2614 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2615 nexthop->ifindex == ifindex)
2616 {
2617 rib->refcnt++;
2618 return 0;
2619 }
paul718e3742002-12-13 20:15:29 +00002620 }
2621
2622 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002623 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2624
paul718e3742002-12-13 20:15:29 +00002625 rib->type = type;
2626 rib->distance = distance;
2627 rib->flags = flags;
2628 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00002629 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00002630 rib->nexthop_num = 0;
2631 rib->uptime = time (NULL);
2632
2633 /* Nexthop settings. */
2634 if (gate)
2635 {
2636 if (ifindex)
2637 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2638 else
2639 nexthop_ipv6_add (rib, gate);
2640 }
2641 else
2642 nexthop_ifindex_add (rib, ifindex);
2643
2644 /* If this route is kernel route, set FIB flag to the route. */
2645 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2646 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2647 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2648
2649 /* Link new rib to node.*/
2650 rib_addnode (rn, rib);
2651
paul718e3742002-12-13 20:15:29 +00002652 /* Free implicit route.*/
2653 if (same)
paul4d38fdb2005-04-28 17:35:14 +00002654 rib_delnode (rn, same);
2655
2656 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002657 return 0;
2658}
2659
hassoebf1ead2005-09-21 14:58:20 +00002660/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002661int
2662rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
G.Balajif768f362011-11-26 22:10:39 +04002663 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002664{
2665 struct route_table *table;
2666 struct route_node *rn;
2667 struct rib *rib;
2668 struct rib *fib = NULL;
2669 struct rib *same = NULL;
Christian Frankefa713d92013-07-05 15:35:37 +00002670 struct nexthop *nexthop, *tnexthop;
2671 int recursing;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002672 char buf1[INET6_ADDRSTRLEN];
2673 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002674
2675 /* Apply mask. */
2676 apply_mask_ipv6 (p);
2677
2678 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002679 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002680 if (! table)
2681 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002682
paul718e3742002-12-13 20:15:29 +00002683 /* Lookup route node. */
2684 rn = route_node_lookup (table, (struct prefix *) p);
2685 if (! rn)
2686 {
2687 if (IS_ZEBRA_DEBUG_KERNEL)
2688 {
2689 if (gate)
ajsb6178002004-12-07 21:12:56 +00002690 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002691 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002692 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002693 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002694 ifindex);
2695 else
ajsb6178002004-12-07 21:12:56 +00002696 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002697 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002698 p->prefixlen,
2699 ifindex);
2700 }
2701 return ZEBRA_ERR_RTNOEXIST;
2702 }
2703
2704 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002705 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002706 {
Paul Jakma6d691122006-07-27 21:49:00 +00002707 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2708 continue;
2709
paul718e3742002-12-13 20:15:29 +00002710 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2711 fib = rib;
2712
hassoebf1ead2005-09-21 14:58:20 +00002713 if (rib->type != type)
2714 continue;
2715 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002716 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002717 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002718 if (nexthop->ifindex != ifindex)
2719 continue;
hassoebf1ead2005-09-21 14:58:20 +00002720 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002721 {
hassoebf1ead2005-09-21 14:58:20 +00002722 rib->refcnt--;
2723 route_unlock_node (rn);
2724 route_unlock_node (rn);
2725 return 0;
paul718e3742002-12-13 20:15:29 +00002726 }
hassoebf1ead2005-09-21 14:58:20 +00002727 same = rib;
2728 break;
paul718e3742002-12-13 20:15:29 +00002729 }
hassoebf1ead2005-09-21 14:58:20 +00002730 /* Make sure that the route found has the same gateway. */
Christian Frankefa713d92013-07-05 15:35:37 +00002731 else
2732 {
2733 if (gate == NULL)
2734 {
2735 same = rib;
2736 break;
2737 }
2738 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
2739 if (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate))
2740 {
2741 same = rib;
2742 break;
2743 }
2744 if (same)
2745 break;
2746 }
paul718e3742002-12-13 20:15:29 +00002747 }
2748
2749 /* If same type of route can't be found and this message is from
2750 kernel. */
2751 if (! same)
2752 {
2753 if (fib && type == ZEBRA_ROUTE_KERNEL)
2754 {
2755 /* Unset flags. */
2756 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2757 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2758
2759 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2760 }
2761 else
2762 {
2763 if (IS_ZEBRA_DEBUG_KERNEL)
2764 {
2765 if (gate)
ajsb6178002004-12-07 21:12:56 +00002766 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002767 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002768 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002769 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002770 ifindex,
2771 type);
2772 else
ajsb6178002004-12-07 21:12:56 +00002773 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002774 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002775 p->prefixlen,
2776 ifindex,
2777 type);
2778 }
2779 route_unlock_node (rn);
2780 return ZEBRA_ERR_RTNOEXIST;
2781 }
2782 }
2783
2784 if (same)
2785 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002786
paul718e3742002-12-13 20:15:29 +00002787 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002788 return 0;
2789}
2790
2791/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002792static void
paul718e3742002-12-13 20:15:29 +00002793static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2794{
2795 struct rib *rib;
2796 struct route_table *table;
2797 struct route_node *rn;
2798
2799 /* Lookup table. */
2800 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2801 if (! table)
2802 return;
2803
2804 /* Lookup existing route */
2805 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002806 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002807 {
2808 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2809 continue;
2810
2811 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2812 break;
2813 }
paul718e3742002-12-13 20:15:29 +00002814
2815 if (rib)
2816 {
2817 /* Same distance static route is there. Update it with new
2818 nexthop. */
paul718e3742002-12-13 20:15:29 +00002819 route_unlock_node (rn);
2820
2821 switch (si->type)
2822 {
2823 case STATIC_IPV6_GATEWAY:
2824 nexthop_ipv6_add (rib, &si->ipv6);
2825 break;
2826 case STATIC_IPV6_IFNAME:
2827 nexthop_ifname_add (rib, si->ifname);
2828 break;
2829 case STATIC_IPV6_GATEWAY_IFNAME:
2830 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2831 break;
2832 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002833 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002834 }
2835 else
2836 {
2837 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002838 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2839
paul718e3742002-12-13 20:15:29 +00002840 rib->type = ZEBRA_ROUTE_STATIC;
2841 rib->distance = si->distance;
2842 rib->metric = 0;
2843 rib->nexthop_num = 0;
2844
2845 switch (si->type)
2846 {
2847 case STATIC_IPV6_GATEWAY:
2848 nexthop_ipv6_add (rib, &si->ipv6);
2849 break;
2850 case STATIC_IPV6_IFNAME:
2851 nexthop_ifname_add (rib, si->ifname);
2852 break;
2853 case STATIC_IPV6_GATEWAY_IFNAME:
2854 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2855 break;
2856 }
2857
hasso81dfcaa2003-05-25 19:21:25 +00002858 /* Save the flags of this static routes (reject, blackhole) */
2859 rib->flags = si->flags;
2860
paul718e3742002-12-13 20:15:29 +00002861 /* Link this rib to the tree. */
2862 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002863 }
2864}
2865
paula1ac18c2005-06-28 17:17:12 +00002866static int
paul718e3742002-12-13 20:15:29 +00002867static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2868{
2869 if (nexthop->type == NEXTHOP_TYPE_IPV6
2870 && si->type == STATIC_IPV6_GATEWAY
2871 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2872 return 1;
2873 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2874 && si->type == STATIC_IPV6_IFNAME
2875 && strcmp (nexthop->ifname, si->ifname) == 0)
2876 return 1;
2877 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2878 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2879 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2880 && strcmp (nexthop->ifname, si->ifname) == 0)
2881 return 1;
paule8e19462006-01-19 20:16:55 +00002882 return 0;
paul718e3742002-12-13 20:15:29 +00002883}
2884
paula1ac18c2005-06-28 17:17:12 +00002885static void
paul718e3742002-12-13 20:15:29 +00002886static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2887{
2888 struct route_table *table;
2889 struct route_node *rn;
2890 struct rib *rib;
2891 struct nexthop *nexthop;
2892
2893 /* Lookup table. */
2894 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2895 if (! table)
2896 return;
2897
2898 /* Lookup existing route with type and distance. */
2899 rn = route_node_lookup (table, (struct prefix *) p);
2900 if (! rn)
2901 return;
2902
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002903 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002904 {
2905 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2906 continue;
2907
2908 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2909 break;
2910 }
2911
paul718e3742002-12-13 20:15:29 +00002912 if (! rib)
2913 {
2914 route_unlock_node (rn);
2915 return;
2916 }
2917
2918 /* Lookup nexthop. */
2919 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2920 if (static_ipv6_nexthop_same (nexthop, si))
2921 break;
2922
2923 /* Can't find nexthop. */
2924 if (! nexthop)
2925 {
2926 route_unlock_node (rn);
2927 return;
2928 }
2929
2930 /* Check nexthop. */
2931 if (rib->nexthop_num == 1)
2932 {
2933 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002934 }
2935 else
2936 {
paul6baeb982003-10-28 03:47:15 +00002937 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2938 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002939 nexthop_delete (rib, nexthop);
2940 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002941 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002942 }
paul718e3742002-12-13 20:15:29 +00002943 /* Unlock node. */
2944 route_unlock_node (rn);
2945}
2946
2947/* Add static route into static route configuration. */
2948int
2949static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002950 const char *ifname, u_char flags, u_char distance,
2951 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002952{
2953 struct route_node *rn;
2954 struct static_ipv6 *si;
2955 struct static_ipv6 *pp;
2956 struct static_ipv6 *cp;
2957 struct route_table *stable;
2958
2959 /* Lookup table. */
2960 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2961 if (! stable)
2962 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00002963
2964 if (!gate &&
2965 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
2966 return -1;
2967
2968 if (!ifname &&
2969 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
2970 return -1;
paul718e3742002-12-13 20:15:29 +00002971
2972 /* Lookup static route prefix. */
2973 rn = route_node_get (stable, p);
2974
2975 /* Do nothing if there is a same static route. */
2976 for (si = rn->info; si; si = si->next)
2977 {
2978 if (distance == si->distance
2979 && type == si->type
2980 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2981 && (! ifname || strcmp (ifname, si->ifname) == 0))
2982 {
2983 route_unlock_node (rn);
2984 return 0;
2985 }
2986 }
2987
2988 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002989 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
paul718e3742002-12-13 20:15:29 +00002990
2991 si->type = type;
2992 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002993 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002994
2995 switch (type)
2996 {
2997 case STATIC_IPV6_GATEWAY:
2998 si->ipv6 = *gate;
2999 break;
3000 case STATIC_IPV6_IFNAME:
3001 si->ifname = XSTRDUP (0, ifname);
3002 break;
3003 case STATIC_IPV6_GATEWAY_IFNAME:
3004 si->ipv6 = *gate;
3005 si->ifname = XSTRDUP (0, ifname);
3006 break;
3007 }
3008
3009 /* Add new static route information to the tree with sort by
3010 distance value and gateway address. */
3011 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
3012 {
3013 if (si->distance < cp->distance)
3014 break;
3015 if (si->distance > cp->distance)
3016 continue;
3017 }
3018
3019 /* Make linked list. */
3020 if (pp)
3021 pp->next = si;
3022 else
3023 rn->info = si;
3024 if (cp)
3025 cp->prev = si;
3026 si->prev = pp;
3027 si->next = cp;
3028
3029 /* Install into rib. */
3030 static_install_ipv6 (p, si);
3031
3032 return 1;
3033}
3034
3035/* Delete static route from static route configuration. */
3036int
3037static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00003038 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00003039{
3040 struct route_node *rn;
3041 struct static_ipv6 *si;
3042 struct route_table *stable;
3043
3044 /* Lookup table. */
3045 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
3046 if (! stable)
3047 return -1;
3048
3049 /* Lookup static route prefix. */
3050 rn = route_node_lookup (stable, p);
3051 if (! rn)
3052 return 0;
3053
3054 /* Find same static route is the tree */
3055 for (si = rn->info; si; si = si->next)
3056 if (distance == si->distance
3057 && type == si->type
3058 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
3059 && (! ifname || strcmp (ifname, si->ifname) == 0))
3060 break;
3061
3062 /* Can't find static route. */
3063 if (! si)
3064 {
3065 route_unlock_node (rn);
3066 return 0;
3067 }
3068
3069 /* Install into rib. */
3070 static_uninstall_ipv6 (p, si);
3071
3072 /* Unlink static route from linked list. */
3073 if (si->prev)
3074 si->prev->next = si->next;
3075 else
3076 rn->info = si->next;
3077 if (si->next)
3078 si->next->prev = si->prev;
3079
3080 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00003081 if (ifname)
3082 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00003083 XFREE (MTYPE_STATIC_IPV6, si);
3084
3085 return 1;
3086}
3087#endif /* HAVE_IPV6 */
3088
3089/* RIB update function. */
3090void
paula1ac18c2005-06-28 17:17:12 +00003091rib_update (void)
paul718e3742002-12-13 20:15:29 +00003092{
3093 struct route_node *rn;
3094 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00003095
paul718e3742002-12-13 20:15:29 +00003096 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
3097 if (table)
3098 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003099 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003100 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003101
3102 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
3103 if (table)
3104 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003105 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003106 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003107}
3108
paul718e3742002-12-13 20:15:29 +00003109
3110/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00003111static void
paul718e3742002-12-13 20:15:29 +00003112rib_weed_table (struct route_table *table)
3113{
3114 struct route_node *rn;
3115 struct rib *rib;
3116 struct rib *next;
3117
3118 if (table)
3119 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003120 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003121 {
Paul Jakma6d691122006-07-27 21:49:00 +00003122 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3123 continue;
3124
paulb21b19c2003-06-15 01:28:29 +00003125 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00003126 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00003127 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003128 }
3129}
3130
3131/* Delete all routes from non main table. */
3132void
paula1ac18c2005-06-28 17:17:12 +00003133rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00003134{
3135 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3136 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3137}
3138
3139/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00003140static void
paul718e3742002-12-13 20:15:29 +00003141rib_sweep_table (struct route_table *table)
3142{
3143 struct route_node *rn;
3144 struct rib *rib;
3145 struct rib *next;
3146 int ret = 0;
3147
3148 if (table)
3149 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003150 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003151 {
Paul Jakma6d691122006-07-27 21:49:00 +00003152 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3153 continue;
3154
paul718e3742002-12-13 20:15:29 +00003155 if (rib->type == ZEBRA_ROUTE_KERNEL &&
3156 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
3157 {
3158 ret = rib_uninstall_kernel (rn, rib);
3159 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00003160 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003161 }
3162 }
3163}
3164
3165/* Sweep all RIB tables. */
3166void
paula1ac18c2005-06-28 17:17:12 +00003167rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00003168{
3169 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3170 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3171}
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003172
3173/* Remove specific by protocol routes from 'table'. */
3174static unsigned long
3175rib_score_proto_table (u_char proto, struct route_table *table)
3176{
3177 struct route_node *rn;
3178 struct rib *rib;
3179 struct rib *next;
3180 unsigned long n = 0;
3181
3182 if (table)
3183 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003184 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003185 {
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003186 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3187 continue;
3188 if (rib->type == proto)
3189 {
3190 rib_delnode (rn, rib);
3191 n++;
3192 }
3193 }
3194
3195 return n;
3196}
3197
3198/* Remove specific by protocol routes. */
3199unsigned long
3200rib_score_proto (u_char proto)
3201{
3202 return rib_score_proto_table (proto, vrf_table (AFI_IP, SAFI_UNICAST, 0))
3203 +rib_score_proto_table (proto, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3204}
3205
paul718e3742002-12-13 20:15:29 +00003206/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00003207static void
paul718e3742002-12-13 20:15:29 +00003208rib_close_table (struct route_table *table)
3209{
3210 struct route_node *rn;
3211 struct rib *rib;
3212
3213 if (table)
3214 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003215 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00003216 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003217 if (!CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
3218 continue;
3219
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00003220 zfpm_trigger_update (rn, NULL);
3221
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003222 if (! RIB_SYSTEM_ROUTE (rib))
3223 rib_uninstall_kernel (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00003224 }
paul718e3742002-12-13 20:15:29 +00003225}
3226
3227/* Close all RIB tables. */
3228void
paula1ac18c2005-06-28 17:17:12 +00003229rib_close (void)
paul718e3742002-12-13 20:15:29 +00003230{
3231 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3232 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3233}
3234
3235/* Routing information base initialize. */
3236void
paula1ac18c2005-06-28 17:17:12 +00003237rib_init (void)
paul718e3742002-12-13 20:15:29 +00003238{
paul4d38fdb2005-04-28 17:35:14 +00003239 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00003240 /* VRF initialization. */
3241 vrf_init ();
3242}
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003243
3244/*
3245 * vrf_id_get_next
3246 *
3247 * Get the first vrf id that is greater than the given vrf id if any.
3248 *
3249 * Returns TRUE if a vrf id was found, FALSE otherwise.
3250 */
3251static inline int
3252vrf_id_get_next (uint32_t id, uint32_t *next_id_p)
3253{
3254 while (++id < vector_active (vrf_vector))
3255 {
3256 if (vrf_lookup (id))
3257 {
3258 *next_id_p = id;
3259 return 1;
3260 }
3261 }
3262
3263 return 0;
3264}
3265
3266/*
3267 * rib_tables_iter_next
3268 *
3269 * Returns the next table in the iteration.
3270 */
3271struct route_table *
3272rib_tables_iter_next (rib_tables_iter_t *iter)
3273{
3274 struct route_table *table;
3275
3276 /*
3277 * Array that helps us go over all AFI/SAFI combinations via one
3278 * index.
3279 */
3280 static struct {
3281 afi_t afi;
3282 safi_t safi;
3283 } afi_safis[] = {
3284 { AFI_IP, SAFI_UNICAST },
3285 { AFI_IP, SAFI_MULTICAST },
3286 { AFI_IP6, SAFI_UNICAST },
3287 { AFI_IP6, SAFI_MULTICAST },
3288 };
3289
3290 table = NULL;
3291
3292 switch (iter->state)
3293 {
3294
3295 case RIB_TABLES_ITER_S_INIT:
3296 iter->vrf_id = 0;
3297 iter->afi_safi_ix = -1;
3298
3299 /* Fall through */
3300
3301 case RIB_TABLES_ITER_S_ITERATING:
3302 iter->afi_safi_ix++;
3303 while (1)
3304 {
3305
3306 while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
3307 {
3308 table = vrf_table (afi_safis[iter->afi_safi_ix].afi,
3309 afi_safis[iter->afi_safi_ix].safi,
3310 iter->vrf_id);
3311 if (table)
3312 break;
3313
3314 iter->afi_safi_ix++;
3315 }
3316
3317 /*
3318 * Found another table in this vrf.
3319 */
3320 if (table)
3321 break;
3322
3323 /*
3324 * Done with all tables in the current vrf, go to the next
3325 * one.
3326 */
3327 if (!vrf_id_get_next (iter->vrf_id, &iter->vrf_id))
3328 break;
3329
3330 iter->afi_safi_ix = 0;
3331 }
3332
3333 break;
3334
3335 case RIB_TABLES_ITER_S_DONE:
3336 return NULL;
3337 }
3338
3339 if (table)
3340 iter->state = RIB_TABLES_ITER_S_ITERATING;
3341 else
3342 iter->state = RIB_TABLES_ITER_S_DONE;
3343
3344 return table;
3345}