blob: 4dd8551a2943b03eb1834bb3e0d7a8c013e4cc60 [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
paul718e3742002-12-13 20:15:29 +0000205/* Add nexthop to the end of the list. */
paula1ac18c2005-06-28 17:17:12 +0000206static void
paul718e3742002-12-13 20:15:29 +0000207nexthop_add (struct rib *rib, struct nexthop *nexthop)
208{
209 struct nexthop *last;
210
211 for (last = rib->nexthop; last && last->next; last = last->next)
212 ;
213 if (last)
214 last->next = nexthop;
215 else
216 rib->nexthop = nexthop;
217 nexthop->prev = last;
218
219 rib->nexthop_num++;
220}
221
222/* Delete specified nexthop from the list. */
paula1ac18c2005-06-28 17:17:12 +0000223static void
paul718e3742002-12-13 20:15:29 +0000224nexthop_delete (struct rib *rib, struct nexthop *nexthop)
225{
226 if (nexthop->next)
227 nexthop->next->prev = nexthop->prev;
228 if (nexthop->prev)
229 nexthop->prev->next = nexthop->next;
230 else
231 rib->nexthop = nexthop->next;
232 rib->nexthop_num--;
233}
234
235/* Free nexthop. */
paula1ac18c2005-06-28 17:17:12 +0000236static void
paul718e3742002-12-13 20:15:29 +0000237nexthop_free (struct nexthop *nexthop)
238{
paula4b70762003-05-16 17:19:48 +0000239 if (nexthop->ifname)
240 XFREE (0, nexthop->ifname);
paul718e3742002-12-13 20:15:29 +0000241 XFREE (MTYPE_NEXTHOP, nexthop);
242}
243
244struct nexthop *
245nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
246{
247 struct nexthop *nexthop;
248
Stephen Hemminger393deb92008-08-18 14:13:29 -0700249 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000250 nexthop->type = NEXTHOP_TYPE_IFINDEX;
251 nexthop->ifindex = ifindex;
252
253 nexthop_add (rib, nexthop);
254
255 return nexthop;
256}
257
258struct nexthop *
259nexthop_ifname_add (struct rib *rib, char *ifname)
260{
261 struct nexthop *nexthop;
262
Stephen Hemminger393deb92008-08-18 14:13:29 -0700263 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000264 nexthop->type = NEXTHOP_TYPE_IFNAME;
paula4b70762003-05-16 17:19:48 +0000265 nexthop->ifname = XSTRDUP (0, ifname);
paul718e3742002-12-13 20:15:29 +0000266
267 nexthop_add (rib, nexthop);
268
269 return nexthop;
270}
271
272struct nexthop *
Paul Jakma7514fb72007-05-02 16:05:35 +0000273nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src)
paul718e3742002-12-13 20:15:29 +0000274{
275 struct nexthop *nexthop;
276
Stephen Hemminger393deb92008-08-18 14:13:29 -0700277 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000278 nexthop->type = NEXTHOP_TYPE_IPV4;
279 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000280 if (src)
281 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000282
283 nexthop_add (rib, nexthop);
284
285 return nexthop;
286}
287
Josh Bailey26e2ae32012-03-22 01:09:21 -0700288struct nexthop *
paul718e3742002-12-13 20:15:29 +0000289nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
Paul Jakma7514fb72007-05-02 16:05:35 +0000290 struct in_addr *src, unsigned int ifindex)
paul718e3742002-12-13 20:15:29 +0000291{
292 struct nexthop *nexthop;
293
Stephen Hemminger393deb92008-08-18 14:13:29 -0700294 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000295 nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
296 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000297 if (src)
298 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000299 nexthop->ifindex = ifindex;
300
301 nexthop_add (rib, nexthop);
302
303 return nexthop;
304}
305
306#ifdef HAVE_IPV6
307struct nexthop *
308nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
309{
310 struct nexthop *nexthop;
311
Stephen Hemminger393deb92008-08-18 14:13:29 -0700312 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000313 nexthop->type = NEXTHOP_TYPE_IPV6;
314 nexthop->gate.ipv6 = *ipv6;
315
316 nexthop_add (rib, nexthop);
317
318 return nexthop;
319}
320
paula1ac18c2005-06-28 17:17:12 +0000321static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000322nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
323 char *ifname)
324{
325 struct nexthop *nexthop;
326
Stephen Hemminger393deb92008-08-18 14:13:29 -0700327 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000328 nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
329 nexthop->gate.ipv6 = *ipv6;
330 nexthop->ifname = XSTRDUP (0, ifname);
331
332 nexthop_add (rib, nexthop);
333
334 return nexthop;
335}
336
paula1ac18c2005-06-28 17:17:12 +0000337static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000338nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
339 unsigned int ifindex)
340{
341 struct nexthop *nexthop;
342
Stephen Hemminger393deb92008-08-18 14:13:29 -0700343 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000344 nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
345 nexthop->gate.ipv6 = *ipv6;
346 nexthop->ifindex = ifindex;
347
348 nexthop_add (rib, nexthop);
349
350 return nexthop;
351}
352#endif /* HAVE_IPV6 */
353
paul595db7f2003-05-25 21:35:06 +0000354struct nexthop *
355nexthop_blackhole_add (struct rib *rib)
356{
357 struct nexthop *nexthop;
358
Stephen Hemminger393deb92008-08-18 14:13:29 -0700359 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul595db7f2003-05-25 21:35:06 +0000360 nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
361 SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
362
363 nexthop_add (rib, nexthop);
364
365 return nexthop;
366}
367
paul718e3742002-12-13 20:15:29 +0000368/* If force flag is not set, do not modify falgs at all for uninstall
369 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000370static int
paul718e3742002-12-13 20:15:29 +0000371nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
372 struct route_node *top)
373{
374 struct prefix_ipv4 p;
375 struct route_table *table;
376 struct route_node *rn;
377 struct rib *match;
378 struct nexthop *newhop;
379
380 if (nexthop->type == NEXTHOP_TYPE_IPV4)
381 nexthop->ifindex = 0;
382
383 if (set)
384 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
385
386 /* Make lookup prefix. */
387 memset (&p, 0, sizeof (struct prefix_ipv4));
388 p.family = AF_INET;
389 p.prefixlen = IPV4_MAX_PREFIXLEN;
390 p.prefix = nexthop->gate.ipv4;
391
392 /* Lookup table. */
393 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
394 if (! table)
395 return 0;
396
397 rn = route_node_match (table, (struct prefix *) &p);
398 while (rn)
399 {
400 route_unlock_node (rn);
401
David Warda50c1072009-12-03 15:34:39 +0300402 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000403 if (rn == top)
404 return 0;
405
406 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000407 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100408 {
409 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
410 continue;
411 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
412 break;
413 }
paul718e3742002-12-13 20:15:29 +0000414
415 /* If there is no selected route or matched route is EGP, go up
416 tree. */
417 if (! match
418 || match->type == ZEBRA_ROUTE_BGP)
419 {
420 do {
421 rn = rn->parent;
422 } while (rn && rn->info == NULL);
423 if (rn)
424 route_lock_node (rn);
425 }
426 else
427 {
428 if (match->type == ZEBRA_ROUTE_CONNECT)
429 {
430 /* Directly point connected route. */
431 newhop = match->nexthop;
432 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
433 nexthop->ifindex = newhop->ifindex;
434
435 return 1;
436 }
437 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
438 {
439 for (newhop = match->nexthop; newhop; newhop = newhop->next)
440 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
441 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
442 {
443 if (set)
444 {
445 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
446 nexthop->rtype = newhop->type;
447 if (newhop->type == NEXTHOP_TYPE_IPV4 ||
448 newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
449 nexthop->rgate.ipv4 = newhop->gate.ipv4;
450 if (newhop->type == NEXTHOP_TYPE_IFINDEX
451 || newhop->type == NEXTHOP_TYPE_IFNAME
452 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
453 nexthop->rifindex = newhop->ifindex;
454 }
455 return 1;
456 }
457 return 0;
458 }
459 else
460 {
461 return 0;
462 }
463 }
464 }
465 return 0;
466}
467
468#ifdef HAVE_IPV6
469/* If force flag is not set, do not modify falgs at all for uninstall
470 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000471static int
paul718e3742002-12-13 20:15:29 +0000472nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
473 struct route_node *top)
474{
475 struct prefix_ipv6 p;
476 struct route_table *table;
477 struct route_node *rn;
478 struct rib *match;
479 struct nexthop *newhop;
480
481 if (nexthop->type == NEXTHOP_TYPE_IPV6)
482 nexthop->ifindex = 0;
483
484 if (set)
485 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
486
487 /* Make lookup prefix. */
488 memset (&p, 0, sizeof (struct prefix_ipv6));
489 p.family = AF_INET6;
490 p.prefixlen = IPV6_MAX_PREFIXLEN;
491 p.prefix = nexthop->gate.ipv6;
492
493 /* Lookup table. */
494 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
495 if (! table)
496 return 0;
497
498 rn = route_node_match (table, (struct prefix *) &p);
499 while (rn)
500 {
501 route_unlock_node (rn);
502
David Warda50c1072009-12-03 15:34:39 +0300503 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000504 if (rn == top)
505 return 0;
506
507 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000508 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100509 {
510 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
511 continue;
512 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
513 break;
514 }
paul718e3742002-12-13 20:15:29 +0000515
516 /* If there is no selected route or matched route is EGP, go up
517 tree. */
518 if (! match
519 || match->type == ZEBRA_ROUTE_BGP)
520 {
521 do {
522 rn = rn->parent;
523 } while (rn && rn->info == NULL);
524 if (rn)
525 route_lock_node (rn);
526 }
527 else
528 {
529 if (match->type == ZEBRA_ROUTE_CONNECT)
530 {
531 /* Directly point connected route. */
532 newhop = match->nexthop;
533
534 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
535 nexthop->ifindex = newhop->ifindex;
536
537 return 1;
538 }
539 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
540 {
541 for (newhop = match->nexthop; newhop; newhop = newhop->next)
542 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
543 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
544 {
545 if (set)
546 {
547 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
548 nexthop->rtype = newhop->type;
549 if (newhop->type == NEXTHOP_TYPE_IPV6
550 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
551 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
552 nexthop->rgate.ipv6 = newhop->gate.ipv6;
553 if (newhop->type == NEXTHOP_TYPE_IFINDEX
554 || newhop->type == NEXTHOP_TYPE_IFNAME
555 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
556 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
557 nexthop->rifindex = newhop->ifindex;
558 }
559 return 1;
560 }
561 return 0;
562 }
563 else
564 {
565 return 0;
566 }
567 }
568 }
569 return 0;
570}
571#endif /* HAVE_IPV6 */
572
573struct rib *
574rib_match_ipv4 (struct in_addr addr)
575{
576 struct prefix_ipv4 p;
577 struct route_table *table;
578 struct route_node *rn;
579 struct rib *match;
580 struct nexthop *newhop;
581
582 /* Lookup table. */
583 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
584 if (! table)
585 return 0;
586
587 memset (&p, 0, sizeof (struct prefix_ipv4));
588 p.family = AF_INET;
589 p.prefixlen = IPV4_MAX_PREFIXLEN;
590 p.prefix = addr;
591
592 rn = route_node_match (table, (struct prefix *) &p);
593
594 while (rn)
595 {
596 route_unlock_node (rn);
597
598 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000599 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100600 {
601 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
602 continue;
603 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
604 break;
605 }
paul718e3742002-12-13 20:15:29 +0000606
607 /* If there is no selected route or matched route is EGP, go up
608 tree. */
609 if (! match
610 || match->type == ZEBRA_ROUTE_BGP)
611 {
612 do {
613 rn = rn->parent;
614 } while (rn && rn->info == NULL);
615 if (rn)
616 route_lock_node (rn);
617 }
618 else
619 {
620 if (match->type == ZEBRA_ROUTE_CONNECT)
621 /* Directly point connected route. */
622 return match;
623 else
624 {
625 for (newhop = match->nexthop; newhop; newhop = newhop->next)
626 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
627 return match;
628 return NULL;
629 }
630 }
631 }
632 return NULL;
633}
634
635struct rib *
636rib_lookup_ipv4 (struct prefix_ipv4 *p)
637{
638 struct route_table *table;
639 struct route_node *rn;
640 struct rib *match;
641 struct nexthop *nexthop;
642
643 /* Lookup table. */
644 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
645 if (! table)
646 return 0;
647
648 rn = route_node_lookup (table, (struct prefix *) p);
649
650 /* No route for this prefix. */
651 if (! rn)
652 return NULL;
653
654 /* Unlock node. */
655 route_unlock_node (rn);
656
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000657 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100658 {
659 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
660 continue;
661 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
662 break;
663 }
paul718e3742002-12-13 20:15:29 +0000664
665 if (! match || match->type == ZEBRA_ROUTE_BGP)
666 return NULL;
667
668 if (match->type == ZEBRA_ROUTE_CONNECT)
669 return match;
670
671 for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
672 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
673 return match;
674
675 return NULL;
676}
677
Denis Ovsienkodc958242007-08-13 16:03:06 +0000678/*
679 * This clone function, unlike its original rib_lookup_ipv4(), checks
680 * if specified IPv4 route record (prefix/mask -> gate) exists in
681 * the whole RIB and has ZEBRA_FLAG_SELECTED set.
682 *
683 * Return values:
684 * -1: error
685 * 0: exact match found
686 * 1: a match was found with a different gate
687 * 2: connected route found
688 * 3: no matches found
689 */
690int
691rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
692{
693 struct route_table *table;
694 struct route_node *rn;
695 struct rib *match;
696 struct nexthop *nexthop;
697
698 /* Lookup table. */
699 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
700 if (! table)
701 return ZEBRA_RIB_LOOKUP_ERROR;
702
703 /* Scan the RIB table for exactly matching RIB entry. */
704 rn = route_node_lookup (table, (struct prefix *) p);
705
706 /* No route for this prefix. */
707 if (! rn)
708 return ZEBRA_RIB_NOTFOUND;
709
710 /* Unlock node. */
711 route_unlock_node (rn);
712
713 /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000714 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100715 {
716 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
717 continue;
718 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
719 break;
720 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000721
722 /* None such found :( */
723 if (!match)
724 return ZEBRA_RIB_NOTFOUND;
725
726 if (match->type == ZEBRA_ROUTE_CONNECT)
727 return ZEBRA_RIB_FOUND_CONNECTED;
728
729 /* Ok, we have a cood candidate, let's check it's nexthop list... */
730 for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
731 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
732 {
733 /* We are happy with either direct or recursive hexthop */
Jorge Boncompte [DTI2]12829322012-04-10 16:57:25 +0200734 if (nexthop->gate.ipv4.s_addr == sockunion2ip (qgate) ||
735 nexthop->rgate.ipv4.s_addr == sockunion2ip (qgate))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000736 return ZEBRA_RIB_FOUND_EXACT;
737 else
738 {
739 if (IS_ZEBRA_DEBUG_RIB)
740 {
741 char gate_buf[INET_ADDRSTRLEN], rgate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
742 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
743 inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, rgate_buf, INET_ADDRSTRLEN);
Jorge Boncompte [DTI2]12829322012-04-10 16:57:25 +0200744 inet_ntop (AF_INET, &sockunion2ip (qgate), qgate_buf, INET_ADDRSTRLEN);
Denis Ovsienkodc958242007-08-13 16:03:06 +0000745 zlog_debug ("%s: qgate == %s, gate == %s, rgate == %s", __func__, qgate_buf, gate_buf, rgate_buf);
746 }
747 return ZEBRA_RIB_FOUND_NOGATE;
748 }
749 }
750
751 return ZEBRA_RIB_NOTFOUND;
752}
753
paul718e3742002-12-13 20:15:29 +0000754#ifdef HAVE_IPV6
755struct rib *
756rib_match_ipv6 (struct in6_addr *addr)
757{
758 struct prefix_ipv6 p;
759 struct route_table *table;
760 struct route_node *rn;
761 struct rib *match;
762 struct nexthop *newhop;
763
764 /* Lookup table. */
765 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
766 if (! table)
767 return 0;
768
769 memset (&p, 0, sizeof (struct prefix_ipv6));
770 p.family = AF_INET6;
771 p.prefixlen = IPV6_MAX_PREFIXLEN;
772 IPV6_ADDR_COPY (&p.prefix, addr);
773
774 rn = route_node_match (table, (struct prefix *) &p);
775
776 while (rn)
777 {
778 route_unlock_node (rn);
779
780 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000781 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100782 {
783 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
784 continue;
785 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
786 break;
787 }
paul718e3742002-12-13 20:15:29 +0000788
789 /* If there is no selected route or matched route is EGP, go up
790 tree. */
791 if (! match
792 || match->type == ZEBRA_ROUTE_BGP)
793 {
794 do {
795 rn = rn->parent;
796 } while (rn && rn->info == NULL);
797 if (rn)
798 route_lock_node (rn);
799 }
800 else
801 {
802 if (match->type == ZEBRA_ROUTE_CONNECT)
803 /* Directly point connected route. */
804 return match;
805 else
806 {
807 for (newhop = match->nexthop; newhop; newhop = newhop->next)
808 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
809 return match;
810 return NULL;
811 }
812 }
813 }
814 return NULL;
815}
816#endif /* HAVE_IPV6 */
817
Paul Jakma7514fb72007-05-02 16:05:35 +0000818#define RIB_SYSTEM_ROUTE(R) \
819 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
820
Denis Ovsienkodc958242007-08-13 16:03:06 +0000821/* This function verifies reachability of one given nexthop, which can be
822 * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
823 * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
824 * nexthop->ifindex will be updated appropriately as well.
825 * An existing route map can turn (otherwise active) nexthop into inactive, but
826 * not vice versa.
827 *
828 * The return value is the final value of 'ACTIVE' flag.
829 */
830
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300831static unsigned
paul718e3742002-12-13 20:15:29 +0000832nexthop_active_check (struct route_node *rn, struct rib *rib,
833 struct nexthop *nexthop, int set)
834{
835 struct interface *ifp;
Paul Jakma7514fb72007-05-02 16:05:35 +0000836 route_map_result_t ret = RMAP_MATCH;
837 extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
838 struct route_map *rmap;
839 int family;
paul718e3742002-12-13 20:15:29 +0000840
Paul Jakma7514fb72007-05-02 16:05:35 +0000841 family = 0;
paul718e3742002-12-13 20:15:29 +0000842 switch (nexthop->type)
843 {
844 case NEXTHOP_TYPE_IFINDEX:
845 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000846 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000847 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
848 else
849 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
850 break;
paul718e3742002-12-13 20:15:29 +0000851 case NEXTHOP_TYPE_IPV6_IFNAME:
Paul Jakma7514fb72007-05-02 16:05:35 +0000852 family = AFI_IP6;
853 case NEXTHOP_TYPE_IFNAME:
paul718e3742002-12-13 20:15:29 +0000854 ifp = if_lookup_by_name (nexthop->ifname);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000855 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000856 {
857 if (set)
858 nexthop->ifindex = ifp->ifindex;
859 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
860 }
861 else
862 {
863 if (set)
864 nexthop->ifindex = 0;
865 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
866 }
867 break;
868 case NEXTHOP_TYPE_IPV4:
869 case NEXTHOP_TYPE_IPV4_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000870 family = AFI_IP;
paul718e3742002-12-13 20:15:29 +0000871 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
872 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
873 else
874 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
875 break;
876#ifdef HAVE_IPV6
877 case NEXTHOP_TYPE_IPV6:
Paul Jakma7514fb72007-05-02 16:05:35 +0000878 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000879 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
880 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
881 else
882 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
883 break;
884 case NEXTHOP_TYPE_IPV6_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000885 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000886 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
887 {
888 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000889 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000890 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
891 else
892 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
893 }
894 else
895 {
896 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
897 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
898 else
899 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
900 }
901 break;
902#endif /* HAVE_IPV6 */
paul595db7f2003-05-25 21:35:06 +0000903 case NEXTHOP_TYPE_BLACKHOLE:
904 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
905 break;
paul718e3742002-12-13 20:15:29 +0000906 default:
907 break;
908 }
Paul Jakma7514fb72007-05-02 16:05:35 +0000909 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
910 return 0;
911
912 if (RIB_SYSTEM_ROUTE(rib) ||
913 (family == AFI_IP && rn->p.family != AF_INET) ||
914 (family == AFI_IP6 && rn->p.family != AF_INET6))
915 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
916
917 rmap = 0;
918 if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
919 proto_rm[family][rib->type])
920 rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
921 if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
922 rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
923 if (rmap) {
924 ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, nexthop);
925 }
926
927 if (ret == RMAP_DENYMATCH)
928 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
paul718e3742002-12-13 20:15:29 +0000929 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
930}
931
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000932/* Iterate over all nexthops of the given RIB entry and refresh their
933 * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
934 * nexthop is found to toggle the ACTIVE flag, the whole rib structure
935 * is flagged with ZEBRA_FLAG_CHANGED. The 4th 'set' argument is
936 * transparently passed to nexthop_active_check().
937 *
938 * Return value is the new number of active nexthops.
939 */
940
paula1ac18c2005-06-28 17:17:12 +0000941static int
paul718e3742002-12-13 20:15:29 +0000942nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
943{
944 struct nexthop *nexthop;
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300945 unsigned int prev_active, prev_index, new_active;
paul718e3742002-12-13 20:15:29 +0000946
947 rib->nexthop_active_num = 0;
948 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
949
950 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000951 {
952 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
Joakim Tjernlundc3a56062009-06-24 19:15:36 +0200953 prev_index = nexthop->ifindex;
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000954 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
955 rib->nexthop_active_num++;
Joakim Tjernlundc3a56062009-06-24 19:15:36 +0200956 if (prev_active != new_active ||
957 prev_index != nexthop->ifindex)
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000958 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
959 }
paul718e3742002-12-13 20:15:29 +0000960 return rib->nexthop_active_num;
961}
paul6baeb982003-10-28 03:47:15 +0000962
paul718e3742002-12-13 20:15:29 +0000963
paul718e3742002-12-13 20:15:29 +0000964
paula1ac18c2005-06-28 17:17:12 +0000965static void
paul718e3742002-12-13 20:15:29 +0000966rib_install_kernel (struct route_node *rn, struct rib *rib)
967{
968 int ret = 0;
969 struct nexthop *nexthop;
970
Avneesh Sachdev5adc2522012-11-13 22:48:59 +0000971 /*
972 * Make sure we update the FPM any time we send new information to
973 * the kernel.
974 */
975 zfpm_trigger_update (rn, "installing in kernel");
paul718e3742002-12-13 20:15:29 +0000976 switch (PREFIX_FAMILY (&rn->p))
977 {
978 case AF_INET:
979 ret = kernel_add_ipv4 (&rn->p, rib);
980 break;
981#ifdef HAVE_IPV6
982 case AF_INET6:
983 ret = kernel_add_ipv6 (&rn->p, rib);
984 break;
985#endif /* HAVE_IPV6 */
986 }
987
Denis Ovsienkodc958242007-08-13 16:03:06 +0000988 /* This condition is never met, if we are using rt_socket.c */
paul718e3742002-12-13 20:15:29 +0000989 if (ret < 0)
990 {
991 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
992 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
993 }
994}
995
996/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +0000997static int
paul718e3742002-12-13 20:15:29 +0000998rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
999{
1000 int ret = 0;
1001 struct nexthop *nexthop;
1002
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001003 /*
1004 * Make sure we update the FPM any time we send new information to
1005 * the kernel.
1006 */
1007 zfpm_trigger_update (rn, "uninstalling from kernel");
1008
paul718e3742002-12-13 20:15:29 +00001009 switch (PREFIX_FAMILY (&rn->p))
1010 {
1011 case AF_INET:
1012 ret = kernel_delete_ipv4 (&rn->p, rib);
1013 break;
1014#ifdef HAVE_IPV6
1015 case AF_INET6:
1016 ret = kernel_delete_ipv6 (&rn->p, rib);
1017 break;
1018#endif /* HAVE_IPV6 */
1019 }
1020
1021 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1022 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1023
1024 return ret;
1025}
1026
1027/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001028static void
paul718e3742002-12-13 20:15:29 +00001029rib_uninstall (struct route_node *rn, struct rib *rib)
1030{
1031 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1032 {
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001033 zfpm_trigger_update (rn, "rib_uninstall");
1034
paul718e3742002-12-13 20:15:29 +00001035 redistribute_delete (&rn->p, rib);
1036 if (! RIB_SYSTEM_ROUTE (rib))
1037 rib_uninstall_kernel (rn, rib);
1038 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
1039 }
1040}
1041
Paul Jakma6d691122006-07-27 21:49:00 +00001042static void rib_unlink (struct route_node *, struct rib *);
1043
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001044/*
1045 * rib_can_delete_dest
1046 *
1047 * Returns TRUE if the given dest can be deleted from the table.
1048 */
1049static int
1050rib_can_delete_dest (rib_dest_t *dest)
1051{
1052 if (dest->routes)
1053 {
1054 return 0;
1055 }
1056
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001057 /*
1058 * Don't delete the dest if we have to update the FPM about this
1059 * prefix.
1060 */
1061 if (CHECK_FLAG (dest->flags, RIB_DEST_UPDATE_FPM) ||
1062 CHECK_FLAG (dest->flags, RIB_DEST_SENT_TO_FPM))
1063 return 0;
1064
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001065 return 1;
1066}
1067
1068/*
1069 * rib_gc_dest
1070 *
1071 * Garbage collect the rib dest corresponding to the given route node
1072 * if appropriate.
1073 *
1074 * Returns TRUE if the dest was deleted, FALSE otherwise.
1075 */
1076int
1077rib_gc_dest (struct route_node *rn)
1078{
1079 rib_dest_t *dest;
1080 char buf[INET6_ADDRSTRLEN];
1081
1082 dest = rib_dest_from_rnode (rn);
1083 if (!dest)
1084 return 0;
1085
1086 if (!rib_can_delete_dest (dest))
1087 return 0;
1088
1089 if (IS_ZEBRA_DEBUG_RIB)
1090 {
1091 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, sizeof (buf));
1092 zlog_debug ("%s: %s/%d: removing dest from table", __func__,
1093 buf, rn->p.prefixlen);
1094 }
1095
1096 dest->rnode = NULL;
1097 XFREE (MTYPE_RIB_DEST, dest);
1098 rn->info = NULL;
1099
1100 /*
1101 * Release the one reference that we keep on the route node.
1102 */
1103 route_unlock_node (rn);
1104 return 1;
1105}
1106
paul718e3742002-12-13 20:15:29 +00001107/* Core function for processing routing information base. */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001108static void
1109rib_process (struct route_node *rn)
paul718e3742002-12-13 20:15:29 +00001110{
1111 struct rib *rib;
1112 struct rib *next;
1113 struct rib *fib = NULL;
1114 struct rib *select = NULL;
Paul Jakma6d691122006-07-27 21:49:00 +00001115 struct rib *del = NULL;
pauld753e9e2003-01-22 19:45:50 +00001116 int installed = 0;
1117 struct nexthop *nexthop = NULL;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001118 char buf[INET6_ADDRSTRLEN];
paul4d38fdb2005-04-28 17:35:14 +00001119
1120 assert (rn);
1121
Paul Jakma93bdada2007-08-06 19:25:11 +00001122 if (IS_ZEBRA_DEBUG_RIB || IS_ZEBRA_DEBUG_RIB_Q)
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001123 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001124
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001125 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00001126 {
paul718e3742002-12-13 20:15:29 +00001127 /* Currently installed rib. */
1128 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Paul Jakma6d691122006-07-27 21:49:00 +00001129 {
1130 assert (fib == NULL);
1131 fib = rib;
1132 }
1133
1134 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1135 * which we need to do do further work with below.
1136 */
1137 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1138 {
1139 if (rib != fib)
1140 {
1141 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001142 zlog_debug ("%s: %s/%d: rn %p, removing rib %p", __func__,
1143 buf, rn->p.prefixlen, rn, rib);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001144 rib_unlink (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001145 }
1146 else
1147 del = rib;
1148
1149 continue;
1150 }
paul4d38fdb2005-04-28 17:35:14 +00001151
paul718e3742002-12-13 20:15:29 +00001152 /* Skip unreachable nexthop. */
1153 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +00001154 continue;
paul718e3742002-12-13 20:15:29 +00001155
1156 /* Infinit distance. */
1157 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +00001158 continue;
paul718e3742002-12-13 20:15:29 +00001159
paulaf887b52006-01-18 14:52:52 +00001160 /* Newly selected rib, the common case. */
1161 if (!select)
1162 {
1163 select = rib;
1164 continue;
1165 }
1166
1167 /* filter route selection in following order:
paulaf887b52006-01-18 14:52:52 +00001168 * - connected beats other types
paula8d9c1f2006-01-25 06:31:04 +00001169 * - lower distance beats higher
paulaf887b52006-01-18 14:52:52 +00001170 * - lower metric beats higher for equal distance
1171 * - last, hence oldest, route wins tie break.
1172 */
paula1038a12006-01-30 14:08:51 +00001173
1174 /* Connected routes. Pick the last connected
1175 * route of the set of lowest metric connected routes.
1176 */
paula8d9c1f2006-01-25 06:31:04 +00001177 if (rib->type == ZEBRA_ROUTE_CONNECT)
1178 {
paula1038a12006-01-30 14:08:51 +00001179 if (select->type != ZEBRA_ROUTE_CONNECT
paula8d9c1f2006-01-25 06:31:04 +00001180 || rib->metric <= select->metric)
paula1038a12006-01-30 14:08:51 +00001181 select = rib;
1182 continue;
paula8d9c1f2006-01-25 06:31:04 +00001183 }
1184 else if (select->type == ZEBRA_ROUTE_CONNECT)
1185 continue;
1186
1187 /* higher distance loses */
1188 if (rib->distance > select->distance)
1189 continue;
1190
1191 /* lower wins */
1192 if (rib->distance < select->distance)
1193 {
paulaf887b52006-01-18 14:52:52 +00001194 select = rib;
paula8d9c1f2006-01-25 06:31:04 +00001195 continue;
1196 }
1197
1198 /* metric tie-breaks equal distance */
1199 if (rib->metric <= select->metric)
1200 select = rib;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001201 } /* RNODE_FOREACH_RIB_SAFE */
Denis Ovsienkodc958242007-08-13 16:03:06 +00001202
1203 /* After the cycle is finished, the following pointers will be set:
1204 * select --- the winner RIB entry, if any was found, otherwise NULL
1205 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1206 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1207 * rib --- NULL
1208 */
1209
1210 /* Same RIB entry is selected. Update FIB and finish. */
paul718e3742002-12-13 20:15:29 +00001211 if (select && select == fib)
1212 {
Paul Jakma6d691122006-07-27 21:49:00 +00001213 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001214 zlog_debug ("%s: %s/%d: Updating existing route, select %p, fib %p",
1215 __func__, buf, rn->p.prefixlen, select, fib);
paul718e3742002-12-13 20:15:29 +00001216 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +00001217 {
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001218 zfpm_trigger_update (rn, "updating existing route");
1219
paul4d38fdb2005-04-28 17:35:14 +00001220 redistribute_delete (&rn->p, select);
1221 if (! RIB_SYSTEM_ROUTE (select))
1222 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001223
paul4d38fdb2005-04-28 17:35:14 +00001224 /* Set real nexthop. */
1225 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +00001226
paul4d38fdb2005-04-28 17:35:14 +00001227 if (! RIB_SYSTEM_ROUTE (select))
1228 rib_install_kernel (rn, select);
1229 redistribute_add (&rn->p, select);
1230 }
pauld753e9e2003-01-22 19:45:50 +00001231 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001232 {
1233 /* Housekeeping code to deal with
1234 race conditions in kernel with linux
1235 netlink reporting interface up before IPv4 or IPv6 protocol
1236 is ready to add routes.
1237 This makes sure the routes are IN the kernel.
1238 */
pauld753e9e2003-01-22 19:45:50 +00001239
paul4d38fdb2005-04-28 17:35:14 +00001240 for (nexthop = select->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001241 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
paul4d38fdb2005-04-28 17:35:14 +00001242 {
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001243 installed = 1;
1244 break;
paul4d38fdb2005-04-28 17:35:14 +00001245 }
1246 if (! installed)
1247 rib_install_kernel (rn, select);
1248 }
Paul Jakma6d691122006-07-27 21:49:00 +00001249 goto end;
paul718e3742002-12-13 20:15:29 +00001250 }
1251
Denis Ovsienkodc958242007-08-13 16:03:06 +00001252 /* At this point we either haven't found the best RIB entry or it is
1253 * different from what we currently intend to flag with SELECTED. In both
1254 * cases, if a RIB block is present in FIB, it should be withdrawn.
1255 */
paul718e3742002-12-13 20:15:29 +00001256 if (fib)
1257 {
Paul Jakma6d691122006-07-27 21:49:00 +00001258 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001259 zlog_debug ("%s: %s/%d: Removing existing route, fib %p", __func__,
1260 buf, rn->p.prefixlen, fib);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001261
1262 zfpm_trigger_update (rn, "removing existing route");
1263
paul718e3742002-12-13 20:15:29 +00001264 redistribute_delete (&rn->p, fib);
1265 if (! RIB_SYSTEM_ROUTE (fib))
1266 rib_uninstall_kernel (rn, fib);
1267 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1268
1269 /* Set real nexthop. */
1270 nexthop_active_update (rn, fib, 1);
1271 }
1272
Denis Ovsienkodc958242007-08-13 16:03:06 +00001273 /* Regardless of some RIB entry being SELECTED or not before, now we can
1274 * tell, that if a new winner exists, FIB is still not updated with this
1275 * data, but ready to be.
1276 */
paul718e3742002-12-13 20:15:29 +00001277 if (select)
1278 {
Paul Jakma6d691122006-07-27 21:49:00 +00001279 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001280 zlog_debug ("%s: %s/%d: Adding route, select %p", __func__, buf,
1281 rn->p.prefixlen, select);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001282
1283 zfpm_trigger_update (rn, "new route selected");
1284
paul718e3742002-12-13 20:15:29 +00001285 /* Set real nexthop. */
1286 nexthop_active_update (rn, select, 1);
1287
1288 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001289 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001290 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1291 redistribute_add (&rn->p, select);
1292 }
paul4d38fdb2005-04-28 17:35:14 +00001293
Paul Jakma6d691122006-07-27 21:49:00 +00001294 /* FIB route was removed, should be deleted */
1295 if (del)
1296 {
1297 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001298 zlog_debug ("%s: %s/%d: Deleting fib %p, rn %p", __func__, buf,
1299 rn->p.prefixlen, del, rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001300 rib_unlink (rn, del);
1301 }
paul4d38fdb2005-04-28 17:35:14 +00001302
Paul Jakma6d691122006-07-27 21:49:00 +00001303end:
1304 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma93bdada2007-08-06 19:25:11 +00001305 zlog_debug ("%s: %s/%d: rn %p dequeued", __func__, buf, rn->p.prefixlen, rn);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001306
1307 /*
1308 * Check if the dest can be deleted now.
1309 */
1310 rib_gc_dest (rn);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001311}
1312
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001313/* Take a list of route_node structs and return 1, if there was a record
1314 * picked from it and processed by rib_process(). Don't process more,
1315 * than one RN record; operate only in the specified sub-queue.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001316 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001317static unsigned int
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001318process_subq (struct list * subq, u_char qindex)
1319{
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001320 struct listnode *lnode = listhead (subq);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001321 struct route_node *rnode;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001322
1323 if (!lnode)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001324 return 0;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001325
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001326 rnode = listgetdata (lnode);
1327 rib_process (rnode);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001328
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001329 if (rnode->info)
1330 UNSET_FLAG (rib_dest_from_rnode (rnode)->flags, RIB_ROUTE_QUEUED (qindex));
1331
Chris Caputo67b94672009-07-18 04:02:26 +00001332#if 0
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001333 else
1334 {
1335 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1336 __func__, rnode, rnode->lock);
1337 zlog_backtrace(LOG_DEBUG);
1338 }
Chris Caputo67b94672009-07-18 04:02:26 +00001339#endif
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001340 route_unlock_node (rnode);
1341 list_delete_node (subq, lnode);
1342 return 1;
1343}
1344
1345/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1346 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1347 * is pointed to the meta queue structure.
1348 */
1349static wq_item_status
1350meta_queue_process (struct work_queue *dummy, void *data)
1351{
1352 struct meta_queue * mq = data;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001353 unsigned i;
1354
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001355 for (i = 0; i < MQ_SIZE; i++)
1356 if (process_subq (mq->subq[i], i))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001357 {
1358 mq->size--;
1359 break;
1360 }
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001361 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1362}
1363
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001364/*
1365 * Map from rib types to queue type (priority) in meta queue
1366 */
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001367static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
1368 [ZEBRA_ROUTE_SYSTEM] = 4,
1369 [ZEBRA_ROUTE_KERNEL] = 0,
1370 [ZEBRA_ROUTE_CONNECT] = 0,
1371 [ZEBRA_ROUTE_STATIC] = 1,
1372 [ZEBRA_ROUTE_RIP] = 2,
1373 [ZEBRA_ROUTE_RIPNG] = 2,
1374 [ZEBRA_ROUTE_OSPF] = 2,
1375 [ZEBRA_ROUTE_OSPF6] = 2,
1376 [ZEBRA_ROUTE_ISIS] = 2,
1377 [ZEBRA_ROUTE_BGP] = 3,
1378 [ZEBRA_ROUTE_HSLS] = 4,
Paul Jakma57345092011-12-25 17:52:09 +01001379 [ZEBRA_ROUTE_BABEL] = 2,
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001380};
1381
1382/* Look into the RN and queue it into one or more priority queues,
1383 * increasing the size for each data push done.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001384 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001385static void
1386rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001387{
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001388 struct rib *rib;
1389 char buf[INET6_ADDRSTRLEN];
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001390
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001391 if (IS_ZEBRA_DEBUG_RIB_Q)
1392 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001393
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001394 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001395 {
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001396 u_char qindex = meta_queue_map[rib->type];
1397
1398 /* Invariant: at this point we always have rn->info set. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001399 if (CHECK_FLAG (rib_dest_from_rnode (rn)->flags,
1400 RIB_ROUTE_QUEUED (qindex)))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001401 {
1402 if (IS_ZEBRA_DEBUG_RIB_Q)
1403 zlog_debug ("%s: %s/%d: rn %p is already queued in sub-queue %u",
1404 __func__, buf, rn->p.prefixlen, rn, qindex);
1405 continue;
1406 }
1407
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001408 SET_FLAG (rib_dest_from_rnode (rn)->flags, RIB_ROUTE_QUEUED (qindex));
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001409 listnode_add (mq->subq[qindex], rn);
1410 route_lock_node (rn);
1411 mq->size++;
1412
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001413 if (IS_ZEBRA_DEBUG_RIB_Q)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001414 zlog_debug ("%s: %s/%d: queued rn %p into sub-queue %u",
1415 __func__, buf, rn->p.prefixlen, rn, qindex);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001416 }
paul4d38fdb2005-04-28 17:35:14 +00001417}
1418
Paul Jakma6d691122006-07-27 21:49:00 +00001419/* Add route_node to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001420static void
Paul Jakma6d691122006-07-27 21:49:00 +00001421rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
paul4d38fdb2005-04-28 17:35:14 +00001422{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001423 char buf[INET_ADDRSTRLEN];
1424 assert (zebra && rn);
paul4d38fdb2005-04-28 17:35:14 +00001425
Paul Jakma93bdada2007-08-06 19:25:11 +00001426 if (IS_ZEBRA_DEBUG_RIB_Q)
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001427 inet_ntop (AF_INET, &rn->p.u.prefix, buf, INET_ADDRSTRLEN);
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001428
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001429 /* Pointless to queue a route_node with no RIB entries to add or remove */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001430 if (!rnode_to_ribs (rn))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001431 {
1432 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1433 __func__, rn, rn->lock);
1434 zlog_backtrace(LOG_DEBUG);
1435 return;
1436 }
1437
1438 if (IS_ZEBRA_DEBUG_RIB_Q)
1439 zlog_info ("%s: %s/%d: work queue added", __func__, buf, rn->p.prefixlen);
1440
1441 assert (zebra);
1442
1443 if (zebra->ribq == NULL)
1444 {
1445 zlog_err ("%s: work_queue does not exist!", __func__);
1446 return;
Paul Jakma6d691122006-07-27 21:49:00 +00001447 }
paul4d38fdb2005-04-28 17:35:14 +00001448
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001449 /*
1450 * The RIB queue should normally be either empty or holding the only
1451 * work_queue_item element. In the latter case this element would
1452 * hold a pointer to the meta queue structure, which must be used to
1453 * actually queue the route nodes to process. So create the MQ
1454 * holder, if necessary, then push the work into it in any case.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001455 * This semantics was introduced after 0.99.9 release.
1456 */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001457 if (!zebra->ribq->items->count)
1458 work_queue_add (zebra->ribq, zebra->mq);
1459
1460 rib_meta_queue_add (zebra->mq, rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001461
1462 if (IS_ZEBRA_DEBUG_RIB_Q)
1463 zlog_debug ("%s: %s/%d: rn %p queued", __func__, buf, rn->p.prefixlen, rn);
1464
1465 return;
paul4d38fdb2005-04-28 17:35:14 +00001466}
1467
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001468/* Create new meta queue.
1469 A destructor function doesn't seem to be necessary here.
1470 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001471static struct meta_queue *
1472meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001473{
1474 struct meta_queue *new;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001475 unsigned i;
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001476
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001477 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1478 assert(new);
1479
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001480 for (i = 0; i < MQ_SIZE; i++)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001481 {
1482 new->subq[i] = list_new ();
1483 assert(new->subq[i]);
1484 }
1485
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001486 return new;
1487}
1488
paul4d38fdb2005-04-28 17:35:14 +00001489/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001490static void
paul4d38fdb2005-04-28 17:35:14 +00001491rib_queue_init (struct zebra_t *zebra)
1492{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001493 assert (zebra);
1494
paul4d38fdb2005-04-28 17:35:14 +00001495 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001496 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001497 {
Paul Jakma6d691122006-07-27 21:49:00 +00001498 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001499 return;
1500 }
1501
1502 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001503 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001504 zebra->ribq->spec.errorfunc = NULL;
paul4d38fdb2005-04-28 17:35:14 +00001505 /* XXX: TODO: These should be runtime configurable via vty */
1506 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001507 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001508
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001509 if (!(zebra->mq = meta_queue_new ()))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001510 {
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001511 zlog_err ("%s: could not initialise meta queue!", __func__);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001512 return;
1513 }
1514 return;
paul718e3742002-12-13 20:15:29 +00001515}
1516
Paul Jakma6d691122006-07-27 21:49:00 +00001517/* RIB updates are processed via a queue of pointers to route_nodes.
1518 *
1519 * The queue length is bounded by the maximal size of the routing table,
1520 * as a route_node will not be requeued, if already queued.
1521 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001522 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1523 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1524 * and then submit route_node to queue for best-path selection later.
1525 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001526 *
1527 * Deleted RIBs are reaped during best-path selection.
1528 *
1529 * rib_addnode
1530 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001531 * |-------->| | best RIB, if required
1532 * | |
1533 * static_install->|->rib_addqueue...... -> rib_process
1534 * | |
1535 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001536 * |-> set RIB_ENTRY_REMOVE |
1537 * rib_delnode (RIB freed)
1538 *
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001539 * The 'info' pointer of a route_node points to a rib_dest_t
1540 * ('dest'). Queueing state for a route_node is kept on the dest. The
1541 * dest is created on-demand by rib_link() and is kept around at least
1542 * as long as there are ribs hanging off it (@see rib_gc_dest()).
Paul Jakma6d691122006-07-27 21:49:00 +00001543 *
1544 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1545 *
1546 * - route_nodes: refcounted by:
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001547 * - dest attached to route_node:
1548 * - managed by: rib_link/rib_gc_dest
Paul Jakma6d691122006-07-27 21:49:00 +00001549 * - route_node processing queue
1550 * - managed by: rib_addqueue, rib_process.
1551 *
1552 */
1553
paul718e3742002-12-13 20:15:29 +00001554/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001555static void
Paul Jakma6d691122006-07-27 21:49:00 +00001556rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001557{
1558 struct rib *head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001559 rib_dest_t *dest;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001560 char buf[INET6_ADDRSTRLEN];
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001561
paul4d38fdb2005-04-28 17:35:14 +00001562 assert (rib && rn);
1563
Paul Jakma6d691122006-07-27 21:49:00 +00001564 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001565 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001566 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001567 zlog_debug ("%s: %s/%d: rn %p, rib %p", __func__,
1568 buf, rn->p.prefixlen, rn, rib);
1569 }
Paul Jakma6d691122006-07-27 21:49:00 +00001570
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001571 dest = rib_dest_from_rnode (rn);
1572 if (!dest)
Paul Jakma6d691122006-07-27 21:49:00 +00001573 {
1574 if (IS_ZEBRA_DEBUG_RIB)
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001575 {
1576 zlog_debug ("%s: %s/%d: adding dest to table", __func__,
1577 buf, rn->p.prefixlen);
1578 }
1579
1580 dest = XCALLOC (MTYPE_RIB_DEST, sizeof (rib_dest_t));
1581 route_lock_node (rn); /* rn route table reference */
1582 rn->info = dest;
1583 dest->rnode = rn;
1584 }
1585
1586 head = dest->routes;
1587 if (head)
1588 {
Paul Jakma6d691122006-07-27 21:49:00 +00001589 head->prev = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001590 }
paul718e3742002-12-13 20:15:29 +00001591 rib->next = head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001592 dest->routes = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001593 rib_queue_add (&zebrad, rn);
1594}
1595
1596static void
1597rib_addnode (struct route_node *rn, struct rib *rib)
1598{
1599 /* RIB node has been un-removed before route-node is processed.
1600 * route_node must hence already be on the queue for processing..
1601 */
1602 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1603 {
1604 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001605 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001606 char buf[INET6_ADDRSTRLEN];
1607 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001608 zlog_debug ("%s: %s/%d: rn %p, un-removed rib %p",
1609 __func__, buf, rn->p.prefixlen, rn, rib);
1610 }
Paul Jakma6d691122006-07-27 21:49:00 +00001611 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1612 return;
1613 }
1614 rib_link (rn, rib);
1615}
1616
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001617/*
1618 * rib_unlink
1619 *
1620 * Detach a rib structure from a route_node.
1621 *
1622 * Note that a call to rib_unlink() should be followed by a call to
1623 * rib_gc_dest() at some point. This allows a rib_dest_t that is no
1624 * longer required to be deleted.
1625 */
Paul Jakma6d691122006-07-27 21:49:00 +00001626static void
1627rib_unlink (struct route_node *rn, struct rib *rib)
1628{
1629 struct nexthop *nexthop, *next;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001630 char buf[INET6_ADDRSTRLEN];
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001631 rib_dest_t *dest;
Paul Jakma6d691122006-07-27 21:49:00 +00001632
1633 assert (rn && rib);
1634
1635 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001636 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001637 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001638 zlog_debug ("%s: %s/%d: rn %p, rib %p",
1639 __func__, buf, rn->p.prefixlen, rn, rib);
1640 }
Paul Jakma6d691122006-07-27 21:49:00 +00001641
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001642 dest = rib_dest_from_rnode (rn);
1643
Paul Jakma6d691122006-07-27 21:49:00 +00001644 if (rib->next)
1645 rib->next->prev = rib->prev;
1646
1647 if (rib->prev)
1648 rib->prev->next = rib->next;
1649 else
1650 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001651 dest->routes = rib->next;
Paul Jakma6d691122006-07-27 21:49:00 +00001652 }
1653
1654 /* free RIB and nexthops */
1655 for (nexthop = rib->nexthop; nexthop; nexthop = next)
1656 {
1657 next = nexthop->next;
1658 nexthop_free (nexthop);
1659 }
1660 XFREE (MTYPE_RIB, rib);
1661
paul718e3742002-12-13 20:15:29 +00001662}
1663
paula1ac18c2005-06-28 17:17:12 +00001664static void
paul718e3742002-12-13 20:15:29 +00001665rib_delnode (struct route_node *rn, struct rib *rib)
1666{
Paul Jakma6d691122006-07-27 21:49:00 +00001667 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001668 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001669 char buf[INET6_ADDRSTRLEN];
1670 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001671 zlog_debug ("%s: %s/%d: rn %p, rib %p, removing", __func__,
1672 buf, rn->p.prefixlen, rn, rib);
1673 }
Paul Jakma6d691122006-07-27 21:49:00 +00001674 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1675 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001676}
1677
1678int
1679rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001680 struct in_addr *gate, struct in_addr *src,
1681 unsigned int ifindex, u_int32_t vrf_id,
G.Balajicddf3912011-11-26 21:59:32 +04001682 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001683{
1684 struct rib *rib;
1685 struct rib *same = NULL;
1686 struct route_table *table;
1687 struct route_node *rn;
1688 struct nexthop *nexthop;
1689
1690 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04001691 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00001692 if (! table)
1693 return 0;
1694
1695 /* Make it sure prefixlen is applied to the prefix. */
1696 apply_mask_ipv4 (p);
1697
1698 /* Set default distance by route type. */
1699 if (distance == 0)
1700 {
Balaji.G837d16c2012-09-26 14:09:10 +05301701 if ((unsigned)type >= array_size(route_info))
David Lamparter7052f222009-08-27 00:28:28 +02001702 distance = 150;
1703 else
1704 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00001705
1706 /* iBGP distance is 200. */
1707 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1708 distance = 200;
1709 }
1710
1711 /* Lookup route node.*/
1712 rn = route_node_get (table, (struct prefix *) p);
1713
1714 /* If same type of route are installed, treat it as a implicit
1715 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001716 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00001717 {
Paul Jakma6d691122006-07-27 21:49:00 +00001718 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1719 continue;
1720
hassoebf1ead2005-09-21 14:58:20 +00001721 if (rib->type != type)
1722 continue;
1723 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001724 {
1725 same = rib;
1726 break;
1727 }
hassoebf1ead2005-09-21 14:58:20 +00001728 /* Duplicate connected route comes in. */
1729 else if ((nexthop = rib->nexthop) &&
1730 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001731 nexthop->ifindex == ifindex &&
1732 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001733 {
1734 rib->refcnt++;
1735 return 0 ;
1736 }
paul718e3742002-12-13 20:15:29 +00001737 }
1738
1739 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001740 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001741 rib->type = type;
1742 rib->distance = distance;
1743 rib->flags = flags;
1744 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001745 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001746 rib->nexthop_num = 0;
1747 rib->uptime = time (NULL);
1748
1749 /* Nexthop settings. */
1750 if (gate)
1751 {
1752 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001753 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001754 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001755 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001756 }
1757 else
1758 nexthop_ifindex_add (rib, ifindex);
1759
1760 /* If this route is kernel route, set FIB flag to the route. */
1761 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1762 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1763 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1764
1765 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001766 if (IS_ZEBRA_DEBUG_RIB)
1767 zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
paul718e3742002-12-13 20:15:29 +00001768 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001769
paul718e3742002-12-13 20:15:29 +00001770 /* Free implicit route.*/
1771 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001772 {
1773 if (IS_ZEBRA_DEBUG_RIB)
1774 zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001775 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001776 }
paul4d38fdb2005-04-28 17:35:14 +00001777
1778 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001779 return 0;
1780}
1781
Denis Ovsienkodc958242007-08-13 16:03:06 +00001782/* This function dumps the contents of a given RIB entry into
1783 * standard debug log. Calling function name and IP prefix in
1784 * question are passed as 1st and 2nd arguments.
1785 */
1786
1787void rib_dump (const char * func, const struct prefix_ipv4 * p, const struct rib * rib)
1788{
1789 char straddr1[INET_ADDRSTRLEN], straddr2[INET_ADDRSTRLEN];
1790 struct nexthop *nexthop;
1791
1792 inet_ntop (AF_INET, &p->prefix, straddr1, INET_ADDRSTRLEN);
1793 zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr1, p->prefixlen);
1794 zlog_debug
1795 (
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001796 "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
Denis Ovsienkodc958242007-08-13 16:03:06 +00001797 func,
1798 rib->refcnt,
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001799 (unsigned long) rib->uptime,
Denis Ovsienkodc958242007-08-13 16:03:06 +00001800 rib->type,
1801 rib->table
1802 );
1803 zlog_debug
1804 (
1805 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1806 func,
1807 rib->metric,
1808 rib->distance,
1809 rib->flags,
1810 rib->status
1811 );
1812 zlog_debug
1813 (
1814 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1815 func,
1816 rib->nexthop_num,
1817 rib->nexthop_active_num,
1818 rib->nexthop_fib_num
1819 );
1820 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1821 {
1822 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, straddr1, INET_ADDRSTRLEN);
1823 inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, straddr2, INET_ADDRSTRLEN);
1824 zlog_debug
1825 (
1826 "%s: NH %s (%s) with flags %s%s%s",
1827 func,
1828 straddr1,
1829 straddr2,
1830 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1831 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1832 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1833 );
1834 }
1835 zlog_debug ("%s: dump complete", func);
1836}
1837
1838/* This is an exported helper to rtm_read() to dump the strange
1839 * RIB entry found by rib_lookup_ipv4_route()
1840 */
1841
1842void rib_lookup_and_dump (struct prefix_ipv4 * p)
1843{
1844 struct route_table *table;
1845 struct route_node *rn;
1846 struct rib *rib;
1847 char prefix_buf[INET_ADDRSTRLEN];
1848
1849 /* Lookup table. */
1850 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1851 if (! table)
1852 {
1853 zlog_err ("%s: vrf_table() returned NULL", __func__);
1854 return;
1855 }
1856
1857 inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
1858 /* Scan the RIB table for exactly matching RIB entry. */
1859 rn = route_node_lookup (table, (struct prefix *) p);
1860
1861 /* No route for this prefix. */
1862 if (! rn)
1863 {
1864 zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
1865 return;
1866 }
1867
1868 /* Unlock node. */
1869 route_unlock_node (rn);
1870
1871 /* let's go */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001872 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001873 {
1874 zlog_debug
1875 (
1876 "%s: rn %p, rib %p: %s, %s",
1877 __func__,
1878 rn,
1879 rib,
1880 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
1881 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
1882 );
1883 rib_dump (__func__, p, rib);
1884 }
1885}
1886
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001887/* Check if requested address assignment will fail due to another
1888 * route being installed by zebra in FIB already. Take necessary
1889 * actions, if needed: remove such a route from FIB and deSELECT
1890 * corresponding RIB entry. Then put affected RN into RIBQ head.
1891 */
1892void rib_lookup_and_pushup (struct prefix_ipv4 * p)
1893{
1894 struct route_table *table;
1895 struct route_node *rn;
1896 struct rib *rib;
1897 unsigned changed = 0;
1898
1899 if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
1900 {
1901 zlog_err ("%s: vrf_table() returned NULL", __func__);
1902 return;
1903 }
1904
1905 /* No matches would be the simplest case. */
1906 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
1907 return;
1908
1909 /* Unlock node. */
1910 route_unlock_node (rn);
1911
1912 /* Check all RIB entries. In case any changes have to be done, requeue
1913 * the RN into RIBQ head. If the routing message about the new connected
1914 * route (generated by the IP address we are going to assign very soon)
1915 * comes before the RIBQ is processed, the new RIB entry will join
1916 * RIBQ record already on head. This is necessary for proper revalidation
1917 * of the rest of the RIB.
1918 */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001919 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001920 {
1921 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
1922 ! RIB_SYSTEM_ROUTE (rib))
1923 {
1924 changed = 1;
1925 if (IS_ZEBRA_DEBUG_RIB)
1926 {
1927 char buf[INET_ADDRSTRLEN];
1928 inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
1929 zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
1930 rib_dump (__func__, (struct prefix_ipv4 *)&rn->p, rib);
1931 }
1932 rib_uninstall (rn, rib);
1933 }
1934 }
1935 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001936 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001937}
1938
paul718e3742002-12-13 20:15:29 +00001939int
G.Balajicddf3912011-11-26 21:59:32 +04001940rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001941{
1942 struct route_table *table;
1943 struct route_node *rn;
1944 struct rib *same;
1945 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00001946
paul718e3742002-12-13 20:15:29 +00001947 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04001948 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00001949 if (! table)
1950 return 0;
G.Balajicddf3912011-11-26 21:59:32 +04001951
paul718e3742002-12-13 20:15:29 +00001952 /* Make it sure prefixlen is applied to the prefix. */
1953 apply_mask_ipv4 (p);
1954
1955 /* Set default distance by route type. */
1956 if (rib->distance == 0)
1957 {
1958 rib->distance = route_info[rib->type].distance;
1959
1960 /* iBGP distance is 200. */
1961 if (rib->type == ZEBRA_ROUTE_BGP
1962 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1963 rib->distance = 200;
1964 }
1965
1966 /* Lookup route node.*/
1967 rn = route_node_get (table, (struct prefix *) p);
1968
1969 /* If same type of route are installed, treat it as a implicit
1970 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001971 RNODE_FOREACH_RIB (rn, same)
paul718e3742002-12-13 20:15:29 +00001972 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00001973 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00001974 continue;
1975
paul718e3742002-12-13 20:15:29 +00001976 if (same->type == rib->type && same->table == rib->table
1977 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001978 break;
paul718e3742002-12-13 20:15:29 +00001979 }
paul4d38fdb2005-04-28 17:35:14 +00001980
paul718e3742002-12-13 20:15:29 +00001981 /* If this route is kernel route, set FIB flag to the route. */
1982 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
1983 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1984 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1985
1986 /* Link new rib to node.*/
1987 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001988 if (IS_ZEBRA_DEBUG_RIB)
1989 {
1990 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
1991 __func__, rn, rib);
1992 rib_dump (__func__, p, rib);
1993 }
paul718e3742002-12-13 20:15:29 +00001994
paul718e3742002-12-13 20:15:29 +00001995 /* Free implicit route.*/
1996 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001997 {
1998 if (IS_ZEBRA_DEBUG_RIB)
1999 {
2000 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
2001 __func__, rn, same);
2002 rib_dump (__func__, p, same);
2003 }
paul4d38fdb2005-04-28 17:35:14 +00002004 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00002005 }
paul4d38fdb2005-04-28 17:35:14 +00002006
2007 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002008 return 0;
2009}
2010
hassoebf1ead2005-09-21 14:58:20 +00002011/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002012int
2013rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
G.Balajicddf3912011-11-26 21:59:32 +04002014 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002015{
2016 struct route_table *table;
2017 struct route_node *rn;
2018 struct rib *rib;
2019 struct rib *fib = NULL;
2020 struct rib *same = NULL;
2021 struct nexthop *nexthop;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002022 char buf1[INET_ADDRSTRLEN];
2023 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002024
2025 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04002026 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00002027 if (! table)
2028 return 0;
2029
2030 /* Apply mask. */
2031 apply_mask_ipv4 (p);
2032
paul5ec90d22003-06-19 01:41:37 +00002033 if (IS_ZEBRA_DEBUG_KERNEL && gate)
ajsb6178002004-12-07 21:12:56 +00002034 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002035 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul5ec90d22003-06-19 01:41:37 +00002036 p->prefixlen,
2037 inet_ntoa (*gate),
2038 ifindex);
2039
paul718e3742002-12-13 20:15:29 +00002040 /* Lookup route node. */
2041 rn = route_node_lookup (table, (struct prefix *) p);
2042 if (! rn)
2043 {
2044 if (IS_ZEBRA_DEBUG_KERNEL)
2045 {
2046 if (gate)
ajsb6178002004-12-07 21:12:56 +00002047 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002048 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002049 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002050 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002051 ifindex);
2052 else
ajsb6178002004-12-07 21:12:56 +00002053 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002054 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002055 p->prefixlen,
2056 ifindex);
2057 }
2058 return ZEBRA_ERR_RTNOEXIST;
2059 }
2060
2061 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002062 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002063 {
Paul Jakma6d691122006-07-27 21:49:00 +00002064 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2065 continue;
2066
paul718e3742002-12-13 20:15:29 +00002067 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2068 fib = rib;
2069
hassoebf1ead2005-09-21 14:58:20 +00002070 if (rib->type != type)
2071 continue;
2072 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002073 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002074 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002075 if (nexthop->ifindex != ifindex)
2076 continue;
hassoebf1ead2005-09-21 14:58:20 +00002077 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002078 {
hassoebf1ead2005-09-21 14:58:20 +00002079 rib->refcnt--;
2080 route_unlock_node (rn);
2081 route_unlock_node (rn);
2082 return 0;
paul718e3742002-12-13 20:15:29 +00002083 }
hassoebf1ead2005-09-21 14:58:20 +00002084 same = rib;
2085 break;
paul718e3742002-12-13 20:15:29 +00002086 }
hassoebf1ead2005-09-21 14:58:20 +00002087 /* Make sure that the route found has the same gateway. */
2088 else if (gate == NULL ||
2089 ((nexthop = rib->nexthop) &&
2090 (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
2091 IPV4_ADDR_SAME (&nexthop->rgate.ipv4, gate))))
paul5ec90d22003-06-19 01:41:37 +00002092 {
hassoebf1ead2005-09-21 14:58:20 +00002093 same = rib;
2094 break;
paul718e3742002-12-13 20:15:29 +00002095 }
2096 }
2097
2098 /* If same type of route can't be found and this message is from
2099 kernel. */
2100 if (! same)
2101 {
2102 if (fib && type == ZEBRA_ROUTE_KERNEL)
2103 {
2104 /* Unset flags. */
2105 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2106 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2107
2108 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2109 }
2110 else
2111 {
2112 if (IS_ZEBRA_DEBUG_KERNEL)
2113 {
2114 if (gate)
ajsb6178002004-12-07 21:12:56 +00002115 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002116 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002117 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002118 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002119 ifindex,
2120 type);
2121 else
ajsb6178002004-12-07 21:12:56 +00002122 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002123 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002124 p->prefixlen,
2125 ifindex,
2126 type);
2127 }
2128 route_unlock_node (rn);
2129 return ZEBRA_ERR_RTNOEXIST;
2130 }
2131 }
paul4d38fdb2005-04-28 17:35:14 +00002132
paul718e3742002-12-13 20:15:29 +00002133 if (same)
2134 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002135
paul718e3742002-12-13 20:15:29 +00002136 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002137 return 0;
2138}
2139
2140/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002141static void
paul718e3742002-12-13 20:15:29 +00002142static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
2143{
2144 struct rib *rib;
2145 struct route_node *rn;
2146 struct route_table *table;
2147
2148 /* Lookup table. */
2149 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2150 if (! table)
2151 return;
2152
2153 /* Lookup existing route */
2154 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002155 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002156 {
2157 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2158 continue;
2159
2160 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2161 break;
2162 }
paul718e3742002-12-13 20:15:29 +00002163
2164 if (rib)
2165 {
2166 /* Same distance static route is there. Update it with new
2167 nexthop. */
paul718e3742002-12-13 20:15:29 +00002168 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002169 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002170 {
2171 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002172 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002173 break;
2174 case STATIC_IPV4_IFNAME:
2175 nexthop_ifname_add (rib, si->gate.ifname);
2176 break;
2177 case STATIC_IPV4_BLACKHOLE:
2178 nexthop_blackhole_add (rib);
2179 break;
paul4d38fdb2005-04-28 17:35:14 +00002180 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002181 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002182 }
2183 else
2184 {
2185 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002186 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2187
paul718e3742002-12-13 20:15:29 +00002188 rib->type = ZEBRA_ROUTE_STATIC;
2189 rib->distance = si->distance;
2190 rib->metric = 0;
Nolan Leakeb0145dd2012-09-13 17:17:31 +00002191 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002192 rib->nexthop_num = 0;
2193
2194 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002195 {
2196 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002197 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002198 break;
2199 case STATIC_IPV4_IFNAME:
2200 nexthop_ifname_add (rib, si->gate.ifname);
2201 break;
2202 case STATIC_IPV4_BLACKHOLE:
2203 nexthop_blackhole_add (rib);
2204 break;
2205 }
paul718e3742002-12-13 20:15:29 +00002206
hasso81dfcaa2003-05-25 19:21:25 +00002207 /* Save the flags of this static routes (reject, blackhole) */
2208 rib->flags = si->flags;
2209
paul718e3742002-12-13 20:15:29 +00002210 /* Link this rib to the tree. */
2211 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002212 }
2213}
2214
paula1ac18c2005-06-28 17:17:12 +00002215static int
paul718e3742002-12-13 20:15:29 +00002216static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2217{
2218 if (nexthop->type == NEXTHOP_TYPE_IPV4
2219 && si->type == STATIC_IPV4_GATEWAY
2220 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2221 return 1;
2222 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2223 && si->type == STATIC_IPV4_IFNAME
2224 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2225 return 1;
paul595db7f2003-05-25 21:35:06 +00002226 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2227 && si->type == STATIC_IPV4_BLACKHOLE)
2228 return 1;
paule8e19462006-01-19 20:16:55 +00002229 return 0;
paul718e3742002-12-13 20:15:29 +00002230}
2231
2232/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002233static void
paul718e3742002-12-13 20:15:29 +00002234static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
2235{
2236 struct route_node *rn;
2237 struct rib *rib;
2238 struct nexthop *nexthop;
2239 struct route_table *table;
2240
2241 /* Lookup table. */
2242 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2243 if (! table)
2244 return;
paul4d38fdb2005-04-28 17:35:14 +00002245
paul718e3742002-12-13 20:15:29 +00002246 /* Lookup existing route with type and distance. */
2247 rn = route_node_lookup (table, p);
2248 if (! rn)
2249 return;
2250
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002251 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002252 {
2253 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2254 continue;
2255
2256 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2257 break;
2258 }
paul718e3742002-12-13 20:15:29 +00002259
2260 if (! rib)
2261 {
2262 route_unlock_node (rn);
2263 return;
2264 }
2265
2266 /* Lookup nexthop. */
2267 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2268 if (static_ipv4_nexthop_same (nexthop, si))
2269 break;
2270
2271 /* Can't find nexthop. */
2272 if (! nexthop)
2273 {
2274 route_unlock_node (rn);
2275 return;
2276 }
2277
2278 /* Check nexthop. */
2279 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002280 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002281 else
2282 {
paul6baeb982003-10-28 03:47:15 +00002283 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2284 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002285 nexthop_delete (rib, nexthop);
2286 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002287 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002288 }
paul718e3742002-12-13 20:15:29 +00002289 /* Unlock node. */
2290 route_unlock_node (rn);
2291}
2292
2293/* Add static route into static route configuration. */
2294int
hasso39db97e2004-10-12 20:50:58 +00002295static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00002296 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002297{
2298 u_char type = 0;
2299 struct route_node *rn;
2300 struct static_ipv4 *si;
2301 struct static_ipv4 *pp;
2302 struct static_ipv4 *cp;
2303 struct static_ipv4 *update = NULL;
2304 struct route_table *stable;
2305
2306 /* Lookup table. */
2307 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2308 if (! stable)
2309 return -1;
2310
2311 /* Lookup static route prefix. */
2312 rn = route_node_get (stable, p);
2313
2314 /* Make flags. */
2315 if (gate)
2316 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002317 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002318 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002319 else
2320 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002321
2322 /* Do nothing if there is a same static route. */
2323 for (si = rn->info; si; si = si->next)
2324 {
2325 if (type == si->type
2326 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2327 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2328 {
2329 if (distance == si->distance)
2330 {
2331 route_unlock_node (rn);
2332 return 0;
2333 }
2334 else
2335 update = si;
2336 }
2337 }
2338
Paul Jakma3c0755d2006-12-08 00:53:14 +00002339 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002340 if (update)
2341 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
2342
2343 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002344 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
paul718e3742002-12-13 20:15:29 +00002345
2346 si->type = type;
2347 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002348 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002349
2350 if (gate)
2351 si->gate.ipv4 = *gate;
2352 if (ifname)
2353 si->gate.ifname = XSTRDUP (0, ifname);
2354
2355 /* Add new static route information to the tree with sort by
2356 distance value and gateway address. */
2357 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2358 {
2359 if (si->distance < cp->distance)
2360 break;
2361 if (si->distance > cp->distance)
2362 continue;
2363 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2364 {
2365 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2366 break;
2367 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2368 continue;
2369 }
2370 }
2371
2372 /* Make linked list. */
2373 if (pp)
2374 pp->next = si;
2375 else
2376 rn->info = si;
2377 if (cp)
2378 cp->prev = si;
2379 si->prev = pp;
2380 si->next = cp;
2381
2382 /* Install into rib. */
2383 static_install_ipv4 (p, si);
2384
2385 return 1;
2386}
2387
2388/* Delete static route from static route configuration. */
2389int
hasso39db97e2004-10-12 20:50:58 +00002390static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00002391 u_char distance, u_int32_t vrf_id)
2392{
2393 u_char type = 0;
2394 struct route_node *rn;
2395 struct static_ipv4 *si;
2396 struct route_table *stable;
2397
2398 /* Lookup table. */
2399 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2400 if (! stable)
2401 return -1;
2402
2403 /* Lookup static route prefix. */
2404 rn = route_node_lookup (stable, p);
2405 if (! rn)
2406 return 0;
2407
2408 /* Make flags. */
2409 if (gate)
2410 type = STATIC_IPV4_GATEWAY;
2411 else if (ifname)
2412 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002413 else
2414 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002415
2416 /* Find same static route is the tree */
2417 for (si = rn->info; si; si = si->next)
2418 if (type == si->type
2419 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2420 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2421 break;
2422
2423 /* Can't find static route. */
2424 if (! si)
2425 {
2426 route_unlock_node (rn);
2427 return 0;
2428 }
2429
2430 /* Install into rib. */
2431 static_uninstall_ipv4 (p, si);
2432
2433 /* Unlink static route from linked list. */
2434 if (si->prev)
2435 si->prev->next = si->next;
2436 else
2437 rn->info = si->next;
2438 if (si->next)
2439 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002440 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002441
2442 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002443 if (ifname)
2444 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002445 XFREE (MTYPE_STATIC_IPV4, si);
2446
paul143a3852003-09-29 20:06:13 +00002447 route_unlock_node (rn);
2448
paul718e3742002-12-13 20:15:29 +00002449 return 1;
2450}
2451
2452
2453#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00002454static int
paul718e3742002-12-13 20:15:29 +00002455rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2456 struct in6_addr *gate, unsigned int ifindex, int table)
2457{
hasso726f9b22003-05-25 21:04:54 +00002458 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2459#if defined (MUSICA) || defined (LINUX)
2460 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2461 if (p->prefixlen == 96)
2462 return 0;
2463#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00002464 return 1;
hasso726f9b22003-05-25 21:04:54 +00002465 }
paul718e3742002-12-13 20:15:29 +00002466 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
2467 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
2468 {
2469 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
2470 return 1;
2471 }
2472 return 0;
2473}
2474
2475int
2476rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00002477 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
G.Balajif768f362011-11-26 22:10:39 +04002478 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002479{
2480 struct rib *rib;
2481 struct rib *same = NULL;
2482 struct route_table *table;
2483 struct route_node *rn;
2484 struct nexthop *nexthop;
2485
paul718e3742002-12-13 20:15:29 +00002486 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002487 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002488 if (! table)
2489 return 0;
2490
2491 /* Make sure mask is applied. */
2492 apply_mask_ipv6 (p);
2493
2494 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002495 if (!distance)
2496 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002497
2498 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2499 distance = 200;
2500
2501 /* Filter bogus route. */
2502 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
2503 return 0;
2504
2505 /* Lookup route node.*/
2506 rn = route_node_get (table, (struct prefix *) p);
2507
2508 /* If same type of route are installed, treat it as a implicit
2509 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002510 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002511 {
Paul Jakma6d691122006-07-27 21:49:00 +00002512 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2513 continue;
2514
hassoebf1ead2005-09-21 14:58:20 +00002515 if (rib->type != type)
2516 continue;
2517 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002518 {
2519 same = rib;
paul718e3742002-12-13 20:15:29 +00002520 break;
2521 }
hassoebf1ead2005-09-21 14:58:20 +00002522 else if ((nexthop = rib->nexthop) &&
2523 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2524 nexthop->ifindex == ifindex)
2525 {
2526 rib->refcnt++;
2527 return 0;
2528 }
paul718e3742002-12-13 20:15:29 +00002529 }
2530
2531 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002532 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2533
paul718e3742002-12-13 20:15:29 +00002534 rib->type = type;
2535 rib->distance = distance;
2536 rib->flags = flags;
2537 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00002538 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00002539 rib->nexthop_num = 0;
2540 rib->uptime = time (NULL);
2541
2542 /* Nexthop settings. */
2543 if (gate)
2544 {
2545 if (ifindex)
2546 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2547 else
2548 nexthop_ipv6_add (rib, gate);
2549 }
2550 else
2551 nexthop_ifindex_add (rib, ifindex);
2552
2553 /* If this route is kernel route, set FIB flag to the route. */
2554 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2555 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2556 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2557
2558 /* Link new rib to node.*/
2559 rib_addnode (rn, rib);
2560
paul718e3742002-12-13 20:15:29 +00002561 /* Free implicit route.*/
2562 if (same)
paul4d38fdb2005-04-28 17:35:14 +00002563 rib_delnode (rn, same);
2564
2565 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002566 return 0;
2567}
2568
hassoebf1ead2005-09-21 14:58:20 +00002569/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002570int
2571rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
G.Balajif768f362011-11-26 22:10:39 +04002572 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002573{
2574 struct route_table *table;
2575 struct route_node *rn;
2576 struct rib *rib;
2577 struct rib *fib = NULL;
2578 struct rib *same = NULL;
2579 struct nexthop *nexthop;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002580 char buf1[INET6_ADDRSTRLEN];
2581 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002582
2583 /* Apply mask. */
2584 apply_mask_ipv6 (p);
2585
2586 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002587 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002588 if (! table)
2589 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002590
paul718e3742002-12-13 20:15:29 +00002591 /* Lookup route node. */
2592 rn = route_node_lookup (table, (struct prefix *) p);
2593 if (! rn)
2594 {
2595 if (IS_ZEBRA_DEBUG_KERNEL)
2596 {
2597 if (gate)
ajsb6178002004-12-07 21:12:56 +00002598 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002599 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002600 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002601 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002602 ifindex);
2603 else
ajsb6178002004-12-07 21:12:56 +00002604 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002605 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002606 p->prefixlen,
2607 ifindex);
2608 }
2609 return ZEBRA_ERR_RTNOEXIST;
2610 }
2611
2612 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002613 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002614 {
Paul Jakma6d691122006-07-27 21:49:00 +00002615 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2616 continue;
2617
paul718e3742002-12-13 20:15:29 +00002618 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2619 fib = rib;
2620
hassoebf1ead2005-09-21 14:58:20 +00002621 if (rib->type != type)
2622 continue;
2623 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002624 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002625 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002626 if (nexthop->ifindex != ifindex)
2627 continue;
hassoebf1ead2005-09-21 14:58:20 +00002628 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002629 {
hassoebf1ead2005-09-21 14:58:20 +00002630 rib->refcnt--;
2631 route_unlock_node (rn);
2632 route_unlock_node (rn);
2633 return 0;
paul718e3742002-12-13 20:15:29 +00002634 }
hassoebf1ead2005-09-21 14:58:20 +00002635 same = rib;
2636 break;
paul718e3742002-12-13 20:15:29 +00002637 }
hassoebf1ead2005-09-21 14:58:20 +00002638 /* Make sure that the route found has the same gateway. */
2639 else if (gate == NULL ||
2640 ((nexthop = rib->nexthop) &&
2641 (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate) ||
2642 IPV6_ADDR_SAME (&nexthop->rgate.ipv6, gate))))
paul718e3742002-12-13 20:15:29 +00002643 {
hassoebf1ead2005-09-21 14:58:20 +00002644 same = rib;
2645 break;
paul718e3742002-12-13 20:15:29 +00002646 }
2647 }
2648
2649 /* If same type of route can't be found and this message is from
2650 kernel. */
2651 if (! same)
2652 {
2653 if (fib && type == ZEBRA_ROUTE_KERNEL)
2654 {
2655 /* Unset flags. */
2656 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2657 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2658
2659 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2660 }
2661 else
2662 {
2663 if (IS_ZEBRA_DEBUG_KERNEL)
2664 {
2665 if (gate)
ajsb6178002004-12-07 21:12:56 +00002666 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002667 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002668 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002669 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002670 ifindex,
2671 type);
2672 else
ajsb6178002004-12-07 21:12:56 +00002673 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002674 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002675 p->prefixlen,
2676 ifindex,
2677 type);
2678 }
2679 route_unlock_node (rn);
2680 return ZEBRA_ERR_RTNOEXIST;
2681 }
2682 }
2683
2684 if (same)
2685 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002686
paul718e3742002-12-13 20:15:29 +00002687 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002688 return 0;
2689}
2690
2691/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002692static void
paul718e3742002-12-13 20:15:29 +00002693static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2694{
2695 struct rib *rib;
2696 struct route_table *table;
2697 struct route_node *rn;
2698
2699 /* Lookup table. */
2700 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2701 if (! table)
2702 return;
2703
2704 /* Lookup existing route */
2705 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002706 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002707 {
2708 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2709 continue;
2710
2711 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2712 break;
2713 }
paul718e3742002-12-13 20:15:29 +00002714
2715 if (rib)
2716 {
2717 /* Same distance static route is there. Update it with new
2718 nexthop. */
paul718e3742002-12-13 20:15:29 +00002719 route_unlock_node (rn);
2720
2721 switch (si->type)
2722 {
2723 case STATIC_IPV6_GATEWAY:
2724 nexthop_ipv6_add (rib, &si->ipv6);
2725 break;
2726 case STATIC_IPV6_IFNAME:
2727 nexthop_ifname_add (rib, si->ifname);
2728 break;
2729 case STATIC_IPV6_GATEWAY_IFNAME:
2730 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2731 break;
2732 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002733 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002734 }
2735 else
2736 {
2737 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002738 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2739
paul718e3742002-12-13 20:15:29 +00002740 rib->type = ZEBRA_ROUTE_STATIC;
2741 rib->distance = si->distance;
2742 rib->metric = 0;
2743 rib->nexthop_num = 0;
2744
2745 switch (si->type)
2746 {
2747 case STATIC_IPV6_GATEWAY:
2748 nexthop_ipv6_add (rib, &si->ipv6);
2749 break;
2750 case STATIC_IPV6_IFNAME:
2751 nexthop_ifname_add (rib, si->ifname);
2752 break;
2753 case STATIC_IPV6_GATEWAY_IFNAME:
2754 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2755 break;
2756 }
2757
hasso81dfcaa2003-05-25 19:21:25 +00002758 /* Save the flags of this static routes (reject, blackhole) */
2759 rib->flags = si->flags;
2760
paul718e3742002-12-13 20:15:29 +00002761 /* Link this rib to the tree. */
2762 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002763 }
2764}
2765
paula1ac18c2005-06-28 17:17:12 +00002766static int
paul718e3742002-12-13 20:15:29 +00002767static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2768{
2769 if (nexthop->type == NEXTHOP_TYPE_IPV6
2770 && si->type == STATIC_IPV6_GATEWAY
2771 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2772 return 1;
2773 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2774 && si->type == STATIC_IPV6_IFNAME
2775 && strcmp (nexthop->ifname, si->ifname) == 0)
2776 return 1;
2777 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2778 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2779 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2780 && strcmp (nexthop->ifname, si->ifname) == 0)
2781 return 1;
paule8e19462006-01-19 20:16:55 +00002782 return 0;
paul718e3742002-12-13 20:15:29 +00002783}
2784
paula1ac18c2005-06-28 17:17:12 +00002785static void
paul718e3742002-12-13 20:15:29 +00002786static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2787{
2788 struct route_table *table;
2789 struct route_node *rn;
2790 struct rib *rib;
2791 struct nexthop *nexthop;
2792
2793 /* Lookup table. */
2794 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2795 if (! table)
2796 return;
2797
2798 /* Lookup existing route with type and distance. */
2799 rn = route_node_lookup (table, (struct prefix *) p);
2800 if (! rn)
2801 return;
2802
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002803 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002804 {
2805 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2806 continue;
2807
2808 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2809 break;
2810 }
2811
paul718e3742002-12-13 20:15:29 +00002812 if (! rib)
2813 {
2814 route_unlock_node (rn);
2815 return;
2816 }
2817
2818 /* Lookup nexthop. */
2819 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2820 if (static_ipv6_nexthop_same (nexthop, si))
2821 break;
2822
2823 /* Can't find nexthop. */
2824 if (! nexthop)
2825 {
2826 route_unlock_node (rn);
2827 return;
2828 }
2829
2830 /* Check nexthop. */
2831 if (rib->nexthop_num == 1)
2832 {
2833 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002834 }
2835 else
2836 {
paul6baeb982003-10-28 03:47:15 +00002837 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2838 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002839 nexthop_delete (rib, nexthop);
2840 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002841 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002842 }
paul718e3742002-12-13 20:15:29 +00002843 /* Unlock node. */
2844 route_unlock_node (rn);
2845}
2846
2847/* Add static route into static route configuration. */
2848int
2849static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002850 const char *ifname, u_char flags, u_char distance,
2851 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002852{
2853 struct route_node *rn;
2854 struct static_ipv6 *si;
2855 struct static_ipv6 *pp;
2856 struct static_ipv6 *cp;
2857 struct route_table *stable;
2858
2859 /* Lookup table. */
2860 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2861 if (! stable)
2862 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00002863
2864 if (!gate &&
2865 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
2866 return -1;
2867
2868 if (!ifname &&
2869 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
2870 return -1;
paul718e3742002-12-13 20:15:29 +00002871
2872 /* Lookup static route prefix. */
2873 rn = route_node_get (stable, p);
2874
2875 /* Do nothing if there is a same static route. */
2876 for (si = rn->info; si; si = si->next)
2877 {
2878 if (distance == si->distance
2879 && type == si->type
2880 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2881 && (! ifname || strcmp (ifname, si->ifname) == 0))
2882 {
2883 route_unlock_node (rn);
2884 return 0;
2885 }
2886 }
2887
2888 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002889 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
paul718e3742002-12-13 20:15:29 +00002890
2891 si->type = type;
2892 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002893 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002894
2895 switch (type)
2896 {
2897 case STATIC_IPV6_GATEWAY:
2898 si->ipv6 = *gate;
2899 break;
2900 case STATIC_IPV6_IFNAME:
2901 si->ifname = XSTRDUP (0, ifname);
2902 break;
2903 case STATIC_IPV6_GATEWAY_IFNAME:
2904 si->ipv6 = *gate;
2905 si->ifname = XSTRDUP (0, ifname);
2906 break;
2907 }
2908
2909 /* Add new static route information to the tree with sort by
2910 distance value and gateway address. */
2911 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2912 {
2913 if (si->distance < cp->distance)
2914 break;
2915 if (si->distance > cp->distance)
2916 continue;
2917 }
2918
2919 /* Make linked list. */
2920 if (pp)
2921 pp->next = si;
2922 else
2923 rn->info = si;
2924 if (cp)
2925 cp->prev = si;
2926 si->prev = pp;
2927 si->next = cp;
2928
2929 /* Install into rib. */
2930 static_install_ipv6 (p, si);
2931
2932 return 1;
2933}
2934
2935/* Delete static route from static route configuration. */
2936int
2937static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002938 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002939{
2940 struct route_node *rn;
2941 struct static_ipv6 *si;
2942 struct route_table *stable;
2943
2944 /* Lookup table. */
2945 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2946 if (! stable)
2947 return -1;
2948
2949 /* Lookup static route prefix. */
2950 rn = route_node_lookup (stable, p);
2951 if (! rn)
2952 return 0;
2953
2954 /* Find same static route is the tree */
2955 for (si = rn->info; si; si = si->next)
2956 if (distance == si->distance
2957 && type == si->type
2958 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2959 && (! ifname || strcmp (ifname, si->ifname) == 0))
2960 break;
2961
2962 /* Can't find static route. */
2963 if (! si)
2964 {
2965 route_unlock_node (rn);
2966 return 0;
2967 }
2968
2969 /* Install into rib. */
2970 static_uninstall_ipv6 (p, si);
2971
2972 /* Unlink static route from linked list. */
2973 if (si->prev)
2974 si->prev->next = si->next;
2975 else
2976 rn->info = si->next;
2977 if (si->next)
2978 si->next->prev = si->prev;
2979
2980 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002981 if (ifname)
2982 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00002983 XFREE (MTYPE_STATIC_IPV6, si);
2984
2985 return 1;
2986}
2987#endif /* HAVE_IPV6 */
2988
2989/* RIB update function. */
2990void
paula1ac18c2005-06-28 17:17:12 +00002991rib_update (void)
paul718e3742002-12-13 20:15:29 +00002992{
2993 struct route_node *rn;
2994 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00002995
paul718e3742002-12-13 20:15:29 +00002996 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2997 if (table)
2998 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002999 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003000 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003001
3002 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
3003 if (table)
3004 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003005 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00003006 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00003007}
3008
paul718e3742002-12-13 20:15:29 +00003009
3010/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00003011static void
paul718e3742002-12-13 20:15:29 +00003012rib_weed_table (struct route_table *table)
3013{
3014 struct route_node *rn;
3015 struct rib *rib;
3016 struct rib *next;
3017
3018 if (table)
3019 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003020 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003021 {
Paul Jakma6d691122006-07-27 21:49:00 +00003022 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3023 continue;
3024
paulb21b19c2003-06-15 01:28:29 +00003025 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00003026 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00003027 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003028 }
3029}
3030
3031/* Delete all routes from non main table. */
3032void
paula1ac18c2005-06-28 17:17:12 +00003033rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00003034{
3035 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3036 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3037}
3038
3039/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00003040static void
paul718e3742002-12-13 20:15:29 +00003041rib_sweep_table (struct route_table *table)
3042{
3043 struct route_node *rn;
3044 struct rib *rib;
3045 struct rib *next;
3046 int ret = 0;
3047
3048 if (table)
3049 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003050 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003051 {
Paul Jakma6d691122006-07-27 21:49:00 +00003052 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3053 continue;
3054
paul718e3742002-12-13 20:15:29 +00003055 if (rib->type == ZEBRA_ROUTE_KERNEL &&
3056 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
3057 {
3058 ret = rib_uninstall_kernel (rn, rib);
3059 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00003060 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003061 }
3062 }
3063}
3064
3065/* Sweep all RIB tables. */
3066void
paula1ac18c2005-06-28 17:17:12 +00003067rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00003068{
3069 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3070 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3071}
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003072
3073/* Remove specific by protocol routes from 'table'. */
3074static unsigned long
3075rib_score_proto_table (u_char proto, struct route_table *table)
3076{
3077 struct route_node *rn;
3078 struct rib *rib;
3079 struct rib *next;
3080 unsigned long n = 0;
3081
3082 if (table)
3083 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003084 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003085 {
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003086 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3087 continue;
3088 if (rib->type == proto)
3089 {
3090 rib_delnode (rn, rib);
3091 n++;
3092 }
3093 }
3094
3095 return n;
3096}
3097
3098/* Remove specific by protocol routes. */
3099unsigned long
3100rib_score_proto (u_char proto)
3101{
3102 return rib_score_proto_table (proto, vrf_table (AFI_IP, SAFI_UNICAST, 0))
3103 +rib_score_proto_table (proto, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3104}
3105
paul718e3742002-12-13 20:15:29 +00003106/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00003107static void
paul718e3742002-12-13 20:15:29 +00003108rib_close_table (struct route_table *table)
3109{
3110 struct route_node *rn;
3111 struct rib *rib;
3112
3113 if (table)
3114 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003115 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00003116 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003117 if (!CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
3118 continue;
3119
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00003120 zfpm_trigger_update (rn, NULL);
3121
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003122 if (! RIB_SYSTEM_ROUTE (rib))
3123 rib_uninstall_kernel (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00003124 }
paul718e3742002-12-13 20:15:29 +00003125}
3126
3127/* Close all RIB tables. */
3128void
paula1ac18c2005-06-28 17:17:12 +00003129rib_close (void)
paul718e3742002-12-13 20:15:29 +00003130{
3131 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3132 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3133}
3134
3135/* Routing information base initialize. */
3136void
paula1ac18c2005-06-28 17:17:12 +00003137rib_init (void)
paul718e3742002-12-13 20:15:29 +00003138{
paul4d38fdb2005-04-28 17:35:14 +00003139 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00003140 /* VRF initialization. */
3141 vrf_init ();
3142}
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003143
3144/*
3145 * vrf_id_get_next
3146 *
3147 * Get the first vrf id that is greater than the given vrf id if any.
3148 *
3149 * Returns TRUE if a vrf id was found, FALSE otherwise.
3150 */
3151static inline int
3152vrf_id_get_next (uint32_t id, uint32_t *next_id_p)
3153{
3154 while (++id < vector_active (vrf_vector))
3155 {
3156 if (vrf_lookup (id))
3157 {
3158 *next_id_p = id;
3159 return 1;
3160 }
3161 }
3162
3163 return 0;
3164}
3165
3166/*
3167 * rib_tables_iter_next
3168 *
3169 * Returns the next table in the iteration.
3170 */
3171struct route_table *
3172rib_tables_iter_next (rib_tables_iter_t *iter)
3173{
3174 struct route_table *table;
3175
3176 /*
3177 * Array that helps us go over all AFI/SAFI combinations via one
3178 * index.
3179 */
3180 static struct {
3181 afi_t afi;
3182 safi_t safi;
3183 } afi_safis[] = {
3184 { AFI_IP, SAFI_UNICAST },
3185 { AFI_IP, SAFI_MULTICAST },
3186 { AFI_IP6, SAFI_UNICAST },
3187 { AFI_IP6, SAFI_MULTICAST },
3188 };
3189
3190 table = NULL;
3191
3192 switch (iter->state)
3193 {
3194
3195 case RIB_TABLES_ITER_S_INIT:
3196 iter->vrf_id = 0;
3197 iter->afi_safi_ix = -1;
3198
3199 /* Fall through */
3200
3201 case RIB_TABLES_ITER_S_ITERATING:
3202 iter->afi_safi_ix++;
3203 while (1)
3204 {
3205
3206 while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
3207 {
3208 table = vrf_table (afi_safis[iter->afi_safi_ix].afi,
3209 afi_safis[iter->afi_safi_ix].safi,
3210 iter->vrf_id);
3211 if (table)
3212 break;
3213
3214 iter->afi_safi_ix++;
3215 }
3216
3217 /*
3218 * Found another table in this vrf.
3219 */
3220 if (table)
3221 break;
3222
3223 /*
3224 * Done with all tables in the current vrf, go to the next
3225 * one.
3226 */
3227 if (!vrf_id_get_next (iter->vrf_id, &iter->vrf_id))
3228 break;
3229
3230 iter->afi_safi_ix = 0;
3231 }
3232
3233 break;
3234
3235 case RIB_TABLES_ITER_S_DONE:
3236 return NULL;
3237 }
3238
3239 if (table)
3240 iter->state = RIB_TABLES_ITER_S_ITERATING;
3241 else
3242 iter->state = RIB_TABLES_ITER_S_DONE;
3243
3244 return table;
3245}