blob: a75d721513adf08fc9e2e9978562d6fbd84b1116 [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
158 return vrf->table[afi][safi];
159}
160
161/* Lookup static route table. */
162struct route_table *
163vrf_static_table (afi_t afi, safi_t safi, u_int32_t id)
164{
165 struct vrf *vrf;
166
167 vrf = vrf_lookup (id);
168 if (! vrf)
169 return NULL;
170
171 return vrf->stable[afi][safi];
172}
173
Avneesh Sachdev78deec42012-11-13 22:48:56 +0000174/*
175 * nexthop_type_to_str
176 */
177const char *
178nexthop_type_to_str (enum nexthop_types_t nh_type)
179{
180 static const char *desc[] = {
181 "none",
182 "Directly connected",
183 "Interface route",
184 "IPv4 nexthop",
185 "IPv4 nexthop with ifindex",
186 "IPv4 nexthop with ifname",
187 "IPv6 nexthop",
188 "IPv6 nexthop with ifindex",
189 "IPv6 nexthop with ifname",
190 "Null0 nexthop",
191 };
192
193 if (nh_type >= ZEBRA_NUM_OF (desc))
194 return "<Invalid nh type>";
195
196 return desc[nh_type];
197}
198
paul718e3742002-12-13 20:15:29 +0000199/* Add nexthop to the end of the list. */
paula1ac18c2005-06-28 17:17:12 +0000200static void
paul718e3742002-12-13 20:15:29 +0000201nexthop_add (struct rib *rib, struct nexthop *nexthop)
202{
203 struct nexthop *last;
204
205 for (last = rib->nexthop; last && last->next; last = last->next)
206 ;
207 if (last)
208 last->next = nexthop;
209 else
210 rib->nexthop = nexthop;
211 nexthop->prev = last;
212
213 rib->nexthop_num++;
214}
215
216/* Delete specified nexthop from the list. */
paula1ac18c2005-06-28 17:17:12 +0000217static void
paul718e3742002-12-13 20:15:29 +0000218nexthop_delete (struct rib *rib, struct nexthop *nexthop)
219{
220 if (nexthop->next)
221 nexthop->next->prev = nexthop->prev;
222 if (nexthop->prev)
223 nexthop->prev->next = nexthop->next;
224 else
225 rib->nexthop = nexthop->next;
226 rib->nexthop_num--;
227}
228
229/* Free nexthop. */
paula1ac18c2005-06-28 17:17:12 +0000230static void
paul718e3742002-12-13 20:15:29 +0000231nexthop_free (struct nexthop *nexthop)
232{
paula4b70762003-05-16 17:19:48 +0000233 if (nexthop->ifname)
234 XFREE (0, nexthop->ifname);
paul718e3742002-12-13 20:15:29 +0000235 XFREE (MTYPE_NEXTHOP, nexthop);
236}
237
238struct nexthop *
239nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
240{
241 struct nexthop *nexthop;
242
Stephen Hemminger393deb92008-08-18 14:13:29 -0700243 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000244 nexthop->type = NEXTHOP_TYPE_IFINDEX;
245 nexthop->ifindex = ifindex;
246
247 nexthop_add (rib, nexthop);
248
249 return nexthop;
250}
251
252struct nexthop *
253nexthop_ifname_add (struct rib *rib, char *ifname)
254{
255 struct nexthop *nexthop;
256
Stephen Hemminger393deb92008-08-18 14:13:29 -0700257 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000258 nexthop->type = NEXTHOP_TYPE_IFNAME;
paula4b70762003-05-16 17:19:48 +0000259 nexthop->ifname = XSTRDUP (0, ifname);
paul718e3742002-12-13 20:15:29 +0000260
261 nexthop_add (rib, nexthop);
262
263 return nexthop;
264}
265
266struct nexthop *
Paul Jakma7514fb72007-05-02 16:05:35 +0000267nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src)
paul718e3742002-12-13 20:15:29 +0000268{
269 struct nexthop *nexthop;
270
Stephen Hemminger393deb92008-08-18 14:13:29 -0700271 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000272 nexthop->type = NEXTHOP_TYPE_IPV4;
273 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000274 if (src)
275 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000276
277 nexthop_add (rib, nexthop);
278
279 return nexthop;
280}
281
Josh Bailey26e2ae32012-03-22 01:09:21 -0700282struct nexthop *
paul718e3742002-12-13 20:15:29 +0000283nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
Paul Jakma7514fb72007-05-02 16:05:35 +0000284 struct in_addr *src, unsigned int ifindex)
paul718e3742002-12-13 20:15:29 +0000285{
286 struct nexthop *nexthop;
287
Stephen Hemminger393deb92008-08-18 14:13:29 -0700288 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000289 nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
290 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000291 if (src)
292 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000293 nexthop->ifindex = ifindex;
294
295 nexthop_add (rib, nexthop);
296
297 return nexthop;
298}
299
300#ifdef HAVE_IPV6
301struct nexthop *
302nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
303{
304 struct nexthop *nexthop;
305
Stephen Hemminger393deb92008-08-18 14:13:29 -0700306 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000307 nexthop->type = NEXTHOP_TYPE_IPV6;
308 nexthop->gate.ipv6 = *ipv6;
309
310 nexthop_add (rib, nexthop);
311
312 return nexthop;
313}
314
paula1ac18c2005-06-28 17:17:12 +0000315static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000316nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
317 char *ifname)
318{
319 struct nexthop *nexthop;
320
Stephen Hemminger393deb92008-08-18 14:13:29 -0700321 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000322 nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
323 nexthop->gate.ipv6 = *ipv6;
324 nexthop->ifname = XSTRDUP (0, ifname);
325
326 nexthop_add (rib, nexthop);
327
328 return nexthop;
329}
330
paula1ac18c2005-06-28 17:17:12 +0000331static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000332nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
333 unsigned int ifindex)
334{
335 struct nexthop *nexthop;
336
Stephen Hemminger393deb92008-08-18 14:13:29 -0700337 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000338 nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
339 nexthop->gate.ipv6 = *ipv6;
340 nexthop->ifindex = ifindex;
341
342 nexthop_add (rib, nexthop);
343
344 return nexthop;
345}
346#endif /* HAVE_IPV6 */
347
paul595db7f2003-05-25 21:35:06 +0000348struct nexthop *
349nexthop_blackhole_add (struct rib *rib)
350{
351 struct nexthop *nexthop;
352
Stephen Hemminger393deb92008-08-18 14:13:29 -0700353 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul595db7f2003-05-25 21:35:06 +0000354 nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
355 SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
356
357 nexthop_add (rib, nexthop);
358
359 return nexthop;
360}
361
paul718e3742002-12-13 20:15:29 +0000362/* If force flag is not set, do not modify falgs at all for uninstall
363 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000364static int
paul718e3742002-12-13 20:15:29 +0000365nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
366 struct route_node *top)
367{
368 struct prefix_ipv4 p;
369 struct route_table *table;
370 struct route_node *rn;
371 struct rib *match;
372 struct nexthop *newhop;
373
374 if (nexthop->type == NEXTHOP_TYPE_IPV4)
375 nexthop->ifindex = 0;
376
377 if (set)
378 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
379
380 /* Make lookup prefix. */
381 memset (&p, 0, sizeof (struct prefix_ipv4));
382 p.family = AF_INET;
383 p.prefixlen = IPV4_MAX_PREFIXLEN;
384 p.prefix = nexthop->gate.ipv4;
385
386 /* Lookup table. */
387 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
388 if (! table)
389 return 0;
390
391 rn = route_node_match (table, (struct prefix *) &p);
392 while (rn)
393 {
394 route_unlock_node (rn);
395
David Warda50c1072009-12-03 15:34:39 +0300396 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000397 if (rn == top)
398 return 0;
399
400 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000401 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100402 {
403 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
404 continue;
405 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
406 break;
407 }
paul718e3742002-12-13 20:15:29 +0000408
409 /* If there is no selected route or matched route is EGP, go up
410 tree. */
411 if (! match
412 || match->type == ZEBRA_ROUTE_BGP)
413 {
414 do {
415 rn = rn->parent;
416 } while (rn && rn->info == NULL);
417 if (rn)
418 route_lock_node (rn);
419 }
420 else
421 {
422 if (match->type == ZEBRA_ROUTE_CONNECT)
423 {
424 /* Directly point connected route. */
425 newhop = match->nexthop;
426 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
427 nexthop->ifindex = newhop->ifindex;
428
429 return 1;
430 }
431 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
432 {
433 for (newhop = match->nexthop; newhop; newhop = newhop->next)
434 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
435 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
436 {
437 if (set)
438 {
439 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
440 nexthop->rtype = newhop->type;
441 if (newhop->type == NEXTHOP_TYPE_IPV4 ||
442 newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
443 nexthop->rgate.ipv4 = newhop->gate.ipv4;
444 if (newhop->type == NEXTHOP_TYPE_IFINDEX
445 || newhop->type == NEXTHOP_TYPE_IFNAME
446 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
447 nexthop->rifindex = newhop->ifindex;
448 }
449 return 1;
450 }
451 return 0;
452 }
453 else
454 {
455 return 0;
456 }
457 }
458 }
459 return 0;
460}
461
462#ifdef HAVE_IPV6
463/* If force flag is not set, do not modify falgs at all for uninstall
464 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000465static int
paul718e3742002-12-13 20:15:29 +0000466nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
467 struct route_node *top)
468{
469 struct prefix_ipv6 p;
470 struct route_table *table;
471 struct route_node *rn;
472 struct rib *match;
473 struct nexthop *newhop;
474
475 if (nexthop->type == NEXTHOP_TYPE_IPV6)
476 nexthop->ifindex = 0;
477
478 if (set)
479 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
480
481 /* Make lookup prefix. */
482 memset (&p, 0, sizeof (struct prefix_ipv6));
483 p.family = AF_INET6;
484 p.prefixlen = IPV6_MAX_PREFIXLEN;
485 p.prefix = nexthop->gate.ipv6;
486
487 /* Lookup table. */
488 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
489 if (! table)
490 return 0;
491
492 rn = route_node_match (table, (struct prefix *) &p);
493 while (rn)
494 {
495 route_unlock_node (rn);
496
David Warda50c1072009-12-03 15:34:39 +0300497 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000498 if (rn == top)
499 return 0;
500
501 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000502 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100503 {
504 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
505 continue;
506 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
507 break;
508 }
paul718e3742002-12-13 20:15:29 +0000509
510 /* If there is no selected route or matched route is EGP, go up
511 tree. */
512 if (! match
513 || match->type == ZEBRA_ROUTE_BGP)
514 {
515 do {
516 rn = rn->parent;
517 } while (rn && rn->info == NULL);
518 if (rn)
519 route_lock_node (rn);
520 }
521 else
522 {
523 if (match->type == ZEBRA_ROUTE_CONNECT)
524 {
525 /* Directly point connected route. */
526 newhop = match->nexthop;
527
528 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
529 nexthop->ifindex = newhop->ifindex;
530
531 return 1;
532 }
533 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
534 {
535 for (newhop = match->nexthop; newhop; newhop = newhop->next)
536 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
537 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
538 {
539 if (set)
540 {
541 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
542 nexthop->rtype = newhop->type;
543 if (newhop->type == NEXTHOP_TYPE_IPV6
544 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
545 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
546 nexthop->rgate.ipv6 = newhop->gate.ipv6;
547 if (newhop->type == NEXTHOP_TYPE_IFINDEX
548 || newhop->type == NEXTHOP_TYPE_IFNAME
549 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
550 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
551 nexthop->rifindex = newhop->ifindex;
552 }
553 return 1;
554 }
555 return 0;
556 }
557 else
558 {
559 return 0;
560 }
561 }
562 }
563 return 0;
564}
565#endif /* HAVE_IPV6 */
566
567struct rib *
568rib_match_ipv4 (struct in_addr addr)
569{
570 struct prefix_ipv4 p;
571 struct route_table *table;
572 struct route_node *rn;
573 struct rib *match;
574 struct nexthop *newhop;
575
576 /* Lookup table. */
577 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
578 if (! table)
579 return 0;
580
581 memset (&p, 0, sizeof (struct prefix_ipv4));
582 p.family = AF_INET;
583 p.prefixlen = IPV4_MAX_PREFIXLEN;
584 p.prefix = addr;
585
586 rn = route_node_match (table, (struct prefix *) &p);
587
588 while (rn)
589 {
590 route_unlock_node (rn);
591
592 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000593 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100594 {
595 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
596 continue;
597 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
598 break;
599 }
paul718e3742002-12-13 20:15:29 +0000600
601 /* If there is no selected route or matched route is EGP, go up
602 tree. */
603 if (! match
604 || match->type == ZEBRA_ROUTE_BGP)
605 {
606 do {
607 rn = rn->parent;
608 } while (rn && rn->info == NULL);
609 if (rn)
610 route_lock_node (rn);
611 }
612 else
613 {
614 if (match->type == ZEBRA_ROUTE_CONNECT)
615 /* Directly point connected route. */
616 return match;
617 else
618 {
619 for (newhop = match->nexthop; newhop; newhop = newhop->next)
620 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
621 return match;
622 return NULL;
623 }
624 }
625 }
626 return NULL;
627}
628
629struct rib *
630rib_lookup_ipv4 (struct prefix_ipv4 *p)
631{
632 struct route_table *table;
633 struct route_node *rn;
634 struct rib *match;
635 struct nexthop *nexthop;
636
637 /* Lookup table. */
638 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
639 if (! table)
640 return 0;
641
642 rn = route_node_lookup (table, (struct prefix *) p);
643
644 /* No route for this prefix. */
645 if (! rn)
646 return NULL;
647
648 /* Unlock node. */
649 route_unlock_node (rn);
650
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000651 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100652 {
653 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
654 continue;
655 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
656 break;
657 }
paul718e3742002-12-13 20:15:29 +0000658
659 if (! match || match->type == ZEBRA_ROUTE_BGP)
660 return NULL;
661
662 if (match->type == ZEBRA_ROUTE_CONNECT)
663 return match;
664
665 for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
666 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
667 return match;
668
669 return NULL;
670}
671
Denis Ovsienkodc958242007-08-13 16:03:06 +0000672/*
673 * This clone function, unlike its original rib_lookup_ipv4(), checks
674 * if specified IPv4 route record (prefix/mask -> gate) exists in
675 * the whole RIB and has ZEBRA_FLAG_SELECTED set.
676 *
677 * Return values:
678 * -1: error
679 * 0: exact match found
680 * 1: a match was found with a different gate
681 * 2: connected route found
682 * 3: no matches found
683 */
684int
685rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
686{
687 struct route_table *table;
688 struct route_node *rn;
689 struct rib *match;
690 struct nexthop *nexthop;
691
692 /* Lookup table. */
693 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
694 if (! table)
695 return ZEBRA_RIB_LOOKUP_ERROR;
696
697 /* Scan the RIB table for exactly matching RIB entry. */
698 rn = route_node_lookup (table, (struct prefix *) p);
699
700 /* No route for this prefix. */
701 if (! rn)
702 return ZEBRA_RIB_NOTFOUND;
703
704 /* Unlock node. */
705 route_unlock_node (rn);
706
707 /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000708 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100709 {
710 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
711 continue;
712 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
713 break;
714 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000715
716 /* None such found :( */
717 if (!match)
718 return ZEBRA_RIB_NOTFOUND;
719
720 if (match->type == ZEBRA_ROUTE_CONNECT)
721 return ZEBRA_RIB_FOUND_CONNECTED;
722
723 /* Ok, we have a cood candidate, let's check it's nexthop list... */
724 for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
725 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
726 {
727 /* We are happy with either direct or recursive hexthop */
Jorge Boncompte [DTI2]12829322012-04-10 16:57:25 +0200728 if (nexthop->gate.ipv4.s_addr == sockunion2ip (qgate) ||
729 nexthop->rgate.ipv4.s_addr == sockunion2ip (qgate))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000730 return ZEBRA_RIB_FOUND_EXACT;
731 else
732 {
733 if (IS_ZEBRA_DEBUG_RIB)
734 {
735 char gate_buf[INET_ADDRSTRLEN], rgate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
736 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
737 inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, rgate_buf, INET_ADDRSTRLEN);
Jorge Boncompte [DTI2]12829322012-04-10 16:57:25 +0200738 inet_ntop (AF_INET, &sockunion2ip (qgate), qgate_buf, INET_ADDRSTRLEN);
Denis Ovsienkodc958242007-08-13 16:03:06 +0000739 zlog_debug ("%s: qgate == %s, gate == %s, rgate == %s", __func__, qgate_buf, gate_buf, rgate_buf);
740 }
741 return ZEBRA_RIB_FOUND_NOGATE;
742 }
743 }
744
745 return ZEBRA_RIB_NOTFOUND;
746}
747
paul718e3742002-12-13 20:15:29 +0000748#ifdef HAVE_IPV6
749struct rib *
750rib_match_ipv6 (struct in6_addr *addr)
751{
752 struct prefix_ipv6 p;
753 struct route_table *table;
754 struct route_node *rn;
755 struct rib *match;
756 struct nexthop *newhop;
757
758 /* Lookup table. */
759 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
760 if (! table)
761 return 0;
762
763 memset (&p, 0, sizeof (struct prefix_ipv6));
764 p.family = AF_INET6;
765 p.prefixlen = IPV6_MAX_PREFIXLEN;
766 IPV6_ADDR_COPY (&p.prefix, addr);
767
768 rn = route_node_match (table, (struct prefix *) &p);
769
770 while (rn)
771 {
772 route_unlock_node (rn);
773
774 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000775 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100776 {
777 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
778 continue;
779 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
780 break;
781 }
paul718e3742002-12-13 20:15:29 +0000782
783 /* If there is no selected route or matched route is EGP, go up
784 tree. */
785 if (! match
786 || match->type == ZEBRA_ROUTE_BGP)
787 {
788 do {
789 rn = rn->parent;
790 } while (rn && rn->info == NULL);
791 if (rn)
792 route_lock_node (rn);
793 }
794 else
795 {
796 if (match->type == ZEBRA_ROUTE_CONNECT)
797 /* Directly point connected route. */
798 return match;
799 else
800 {
801 for (newhop = match->nexthop; newhop; newhop = newhop->next)
802 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
803 return match;
804 return NULL;
805 }
806 }
807 }
808 return NULL;
809}
810#endif /* HAVE_IPV6 */
811
Paul Jakma7514fb72007-05-02 16:05:35 +0000812#define RIB_SYSTEM_ROUTE(R) \
813 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
814
Denis Ovsienkodc958242007-08-13 16:03:06 +0000815/* This function verifies reachability of one given nexthop, which can be
816 * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
817 * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
818 * nexthop->ifindex will be updated appropriately as well.
819 * An existing route map can turn (otherwise active) nexthop into inactive, but
820 * not vice versa.
821 *
822 * The return value is the final value of 'ACTIVE' flag.
823 */
824
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300825static unsigned
paul718e3742002-12-13 20:15:29 +0000826nexthop_active_check (struct route_node *rn, struct rib *rib,
827 struct nexthop *nexthop, int set)
828{
829 struct interface *ifp;
Paul Jakma7514fb72007-05-02 16:05:35 +0000830 route_map_result_t ret = RMAP_MATCH;
831 extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
832 struct route_map *rmap;
833 int family;
paul718e3742002-12-13 20:15:29 +0000834
Paul Jakma7514fb72007-05-02 16:05:35 +0000835 family = 0;
paul718e3742002-12-13 20:15:29 +0000836 switch (nexthop->type)
837 {
838 case NEXTHOP_TYPE_IFINDEX:
839 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000840 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000841 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
842 else
843 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
844 break;
paul718e3742002-12-13 20:15:29 +0000845 case NEXTHOP_TYPE_IPV6_IFNAME:
Paul Jakma7514fb72007-05-02 16:05:35 +0000846 family = AFI_IP6;
847 case NEXTHOP_TYPE_IFNAME:
paul718e3742002-12-13 20:15:29 +0000848 ifp = if_lookup_by_name (nexthop->ifname);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000849 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000850 {
851 if (set)
852 nexthop->ifindex = ifp->ifindex;
853 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
854 }
855 else
856 {
857 if (set)
858 nexthop->ifindex = 0;
859 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
860 }
861 break;
862 case NEXTHOP_TYPE_IPV4:
863 case NEXTHOP_TYPE_IPV4_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000864 family = AFI_IP;
paul718e3742002-12-13 20:15:29 +0000865 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
866 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
867 else
868 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
869 break;
870#ifdef HAVE_IPV6
871 case NEXTHOP_TYPE_IPV6:
Paul Jakma7514fb72007-05-02 16:05:35 +0000872 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000873 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
874 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
875 else
876 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
877 break;
878 case NEXTHOP_TYPE_IPV6_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000879 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000880 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
881 {
882 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000883 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000884 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
885 else
886 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
887 }
888 else
889 {
890 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
891 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
892 else
893 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
894 }
895 break;
896#endif /* HAVE_IPV6 */
paul595db7f2003-05-25 21:35:06 +0000897 case NEXTHOP_TYPE_BLACKHOLE:
898 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
899 break;
paul718e3742002-12-13 20:15:29 +0000900 default:
901 break;
902 }
Paul Jakma7514fb72007-05-02 16:05:35 +0000903 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
904 return 0;
905
906 if (RIB_SYSTEM_ROUTE(rib) ||
907 (family == AFI_IP && rn->p.family != AF_INET) ||
908 (family == AFI_IP6 && rn->p.family != AF_INET6))
909 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
910
911 rmap = 0;
912 if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
913 proto_rm[family][rib->type])
914 rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
915 if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
916 rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
917 if (rmap) {
918 ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, nexthop);
919 }
920
921 if (ret == RMAP_DENYMATCH)
922 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
paul718e3742002-12-13 20:15:29 +0000923 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
924}
925
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000926/* Iterate over all nexthops of the given RIB entry and refresh their
927 * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
928 * nexthop is found to toggle the ACTIVE flag, the whole rib structure
929 * is flagged with ZEBRA_FLAG_CHANGED. The 4th 'set' argument is
930 * transparently passed to nexthop_active_check().
931 *
932 * Return value is the new number of active nexthops.
933 */
934
paula1ac18c2005-06-28 17:17:12 +0000935static int
paul718e3742002-12-13 20:15:29 +0000936nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
937{
938 struct nexthop *nexthop;
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300939 unsigned int prev_active, prev_index, new_active;
paul718e3742002-12-13 20:15:29 +0000940
941 rib->nexthop_active_num = 0;
942 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
943
944 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000945 {
946 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
Joakim Tjernlundc3a56062009-06-24 19:15:36 +0200947 prev_index = nexthop->ifindex;
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000948 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
949 rib->nexthop_active_num++;
Joakim Tjernlundc3a56062009-06-24 19:15:36 +0200950 if (prev_active != new_active ||
951 prev_index != nexthop->ifindex)
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000952 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
953 }
paul718e3742002-12-13 20:15:29 +0000954 return rib->nexthop_active_num;
955}
paul6baeb982003-10-28 03:47:15 +0000956
paul718e3742002-12-13 20:15:29 +0000957
paul718e3742002-12-13 20:15:29 +0000958
paula1ac18c2005-06-28 17:17:12 +0000959static void
paul718e3742002-12-13 20:15:29 +0000960rib_install_kernel (struct route_node *rn, struct rib *rib)
961{
962 int ret = 0;
963 struct nexthop *nexthop;
964
Avneesh Sachdev5adc2522012-11-13 22:48:59 +0000965 /*
966 * Make sure we update the FPM any time we send new information to
967 * the kernel.
968 */
969 zfpm_trigger_update (rn, "installing in kernel");
paul718e3742002-12-13 20:15:29 +0000970 switch (PREFIX_FAMILY (&rn->p))
971 {
972 case AF_INET:
973 ret = kernel_add_ipv4 (&rn->p, rib);
974 break;
975#ifdef HAVE_IPV6
976 case AF_INET6:
977 ret = kernel_add_ipv6 (&rn->p, rib);
978 break;
979#endif /* HAVE_IPV6 */
980 }
981
Denis Ovsienkodc958242007-08-13 16:03:06 +0000982 /* This condition is never met, if we are using rt_socket.c */
paul718e3742002-12-13 20:15:29 +0000983 if (ret < 0)
984 {
985 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
986 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
987 }
988}
989
990/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +0000991static int
paul718e3742002-12-13 20:15:29 +0000992rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
993{
994 int ret = 0;
995 struct nexthop *nexthop;
996
Avneesh Sachdev5adc2522012-11-13 22:48:59 +0000997 /*
998 * Make sure we update the FPM any time we send new information to
999 * the kernel.
1000 */
1001 zfpm_trigger_update (rn, "uninstalling from kernel");
1002
paul718e3742002-12-13 20:15:29 +00001003 switch (PREFIX_FAMILY (&rn->p))
1004 {
1005 case AF_INET:
1006 ret = kernel_delete_ipv4 (&rn->p, rib);
1007 break;
1008#ifdef HAVE_IPV6
1009 case AF_INET6:
1010 ret = kernel_delete_ipv6 (&rn->p, rib);
1011 break;
1012#endif /* HAVE_IPV6 */
1013 }
1014
1015 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1016 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1017
1018 return ret;
1019}
1020
1021/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +00001022static void
paul718e3742002-12-13 20:15:29 +00001023rib_uninstall (struct route_node *rn, struct rib *rib)
1024{
1025 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1026 {
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001027 zfpm_trigger_update (rn, "rib_uninstall");
1028
paul718e3742002-12-13 20:15:29 +00001029 redistribute_delete (&rn->p, rib);
1030 if (! RIB_SYSTEM_ROUTE (rib))
1031 rib_uninstall_kernel (rn, rib);
1032 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
1033 }
1034}
1035
Paul Jakma6d691122006-07-27 21:49:00 +00001036static void rib_unlink (struct route_node *, struct rib *);
1037
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001038/*
1039 * rib_can_delete_dest
1040 *
1041 * Returns TRUE if the given dest can be deleted from the table.
1042 */
1043static int
1044rib_can_delete_dest (rib_dest_t *dest)
1045{
1046 if (dest->routes)
1047 {
1048 return 0;
1049 }
1050
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001051 /*
1052 * Don't delete the dest if we have to update the FPM about this
1053 * prefix.
1054 */
1055 if (CHECK_FLAG (dest->flags, RIB_DEST_UPDATE_FPM) ||
1056 CHECK_FLAG (dest->flags, RIB_DEST_SENT_TO_FPM))
1057 return 0;
1058
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001059 return 1;
1060}
1061
1062/*
1063 * rib_gc_dest
1064 *
1065 * Garbage collect the rib dest corresponding to the given route node
1066 * if appropriate.
1067 *
1068 * Returns TRUE if the dest was deleted, FALSE otherwise.
1069 */
1070int
1071rib_gc_dest (struct route_node *rn)
1072{
1073 rib_dest_t *dest;
1074 char buf[INET6_ADDRSTRLEN];
1075
1076 dest = rib_dest_from_rnode (rn);
1077 if (!dest)
1078 return 0;
1079
1080 if (!rib_can_delete_dest (dest))
1081 return 0;
1082
1083 if (IS_ZEBRA_DEBUG_RIB)
1084 {
1085 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, sizeof (buf));
1086 zlog_debug ("%s: %s/%d: removing dest from table", __func__,
1087 buf, rn->p.prefixlen);
1088 }
1089
1090 dest->rnode = NULL;
1091 XFREE (MTYPE_RIB_DEST, dest);
1092 rn->info = NULL;
1093
1094 /*
1095 * Release the one reference that we keep on the route node.
1096 */
1097 route_unlock_node (rn);
1098 return 1;
1099}
1100
paul718e3742002-12-13 20:15:29 +00001101/* Core function for processing routing information base. */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001102static void
1103rib_process (struct route_node *rn)
paul718e3742002-12-13 20:15:29 +00001104{
1105 struct rib *rib;
1106 struct rib *next;
1107 struct rib *fib = NULL;
1108 struct rib *select = NULL;
Paul Jakma6d691122006-07-27 21:49:00 +00001109 struct rib *del = NULL;
pauld753e9e2003-01-22 19:45:50 +00001110 int installed = 0;
1111 struct nexthop *nexthop = NULL;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001112 char buf[INET6_ADDRSTRLEN];
paul4d38fdb2005-04-28 17:35:14 +00001113
1114 assert (rn);
1115
Paul Jakma93bdada2007-08-06 19:25:11 +00001116 if (IS_ZEBRA_DEBUG_RIB || IS_ZEBRA_DEBUG_RIB_Q)
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001117 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001118
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001119 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00001120 {
paul718e3742002-12-13 20:15:29 +00001121 /* Currently installed rib. */
1122 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Paul Jakma6d691122006-07-27 21:49:00 +00001123 {
1124 assert (fib == NULL);
1125 fib = rib;
1126 }
1127
1128 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1129 * which we need to do do further work with below.
1130 */
1131 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1132 {
1133 if (rib != fib)
1134 {
1135 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001136 zlog_debug ("%s: %s/%d: rn %p, removing rib %p", __func__,
1137 buf, rn->p.prefixlen, rn, rib);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001138 rib_unlink (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001139 }
1140 else
1141 del = rib;
1142
1143 continue;
1144 }
paul4d38fdb2005-04-28 17:35:14 +00001145
paul718e3742002-12-13 20:15:29 +00001146 /* Skip unreachable nexthop. */
1147 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +00001148 continue;
paul718e3742002-12-13 20:15:29 +00001149
1150 /* Infinit distance. */
1151 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +00001152 continue;
paul718e3742002-12-13 20:15:29 +00001153
paulaf887b52006-01-18 14:52:52 +00001154 /* Newly selected rib, the common case. */
1155 if (!select)
1156 {
1157 select = rib;
1158 continue;
1159 }
1160
1161 /* filter route selection in following order:
paulaf887b52006-01-18 14:52:52 +00001162 * - connected beats other types
paula8d9c1f2006-01-25 06:31:04 +00001163 * - lower distance beats higher
paulaf887b52006-01-18 14:52:52 +00001164 * - lower metric beats higher for equal distance
1165 * - last, hence oldest, route wins tie break.
1166 */
paula1038a12006-01-30 14:08:51 +00001167
1168 /* Connected routes. Pick the last connected
1169 * route of the set of lowest metric connected routes.
1170 */
paula8d9c1f2006-01-25 06:31:04 +00001171 if (rib->type == ZEBRA_ROUTE_CONNECT)
1172 {
paula1038a12006-01-30 14:08:51 +00001173 if (select->type != ZEBRA_ROUTE_CONNECT
paula8d9c1f2006-01-25 06:31:04 +00001174 || rib->metric <= select->metric)
paula1038a12006-01-30 14:08:51 +00001175 select = rib;
1176 continue;
paula8d9c1f2006-01-25 06:31:04 +00001177 }
1178 else if (select->type == ZEBRA_ROUTE_CONNECT)
1179 continue;
1180
1181 /* higher distance loses */
1182 if (rib->distance > select->distance)
1183 continue;
1184
1185 /* lower wins */
1186 if (rib->distance < select->distance)
1187 {
paulaf887b52006-01-18 14:52:52 +00001188 select = rib;
paula8d9c1f2006-01-25 06:31:04 +00001189 continue;
1190 }
1191
1192 /* metric tie-breaks equal distance */
1193 if (rib->metric <= select->metric)
1194 select = rib;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001195 } /* RNODE_FOREACH_RIB_SAFE */
Denis Ovsienkodc958242007-08-13 16:03:06 +00001196
1197 /* After the cycle is finished, the following pointers will be set:
1198 * select --- the winner RIB entry, if any was found, otherwise NULL
1199 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1200 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1201 * rib --- NULL
1202 */
1203
1204 /* Same RIB entry is selected. Update FIB and finish. */
paul718e3742002-12-13 20:15:29 +00001205 if (select && select == fib)
1206 {
Paul Jakma6d691122006-07-27 21:49:00 +00001207 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001208 zlog_debug ("%s: %s/%d: Updating existing route, select %p, fib %p",
1209 __func__, buf, rn->p.prefixlen, select, fib);
paul718e3742002-12-13 20:15:29 +00001210 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +00001211 {
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001212 zfpm_trigger_update (rn, "updating existing route");
1213
paul4d38fdb2005-04-28 17:35:14 +00001214 redistribute_delete (&rn->p, select);
1215 if (! RIB_SYSTEM_ROUTE (select))
1216 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001217
paul4d38fdb2005-04-28 17:35:14 +00001218 /* Set real nexthop. */
1219 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +00001220
paul4d38fdb2005-04-28 17:35:14 +00001221 if (! RIB_SYSTEM_ROUTE (select))
1222 rib_install_kernel (rn, select);
1223 redistribute_add (&rn->p, select);
1224 }
pauld753e9e2003-01-22 19:45:50 +00001225 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001226 {
1227 /* Housekeeping code to deal with
1228 race conditions in kernel with linux
1229 netlink reporting interface up before IPv4 or IPv6 protocol
1230 is ready to add routes.
1231 This makes sure the routes are IN the kernel.
1232 */
pauld753e9e2003-01-22 19:45:50 +00001233
paul4d38fdb2005-04-28 17:35:14 +00001234 for (nexthop = select->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001235 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
paul4d38fdb2005-04-28 17:35:14 +00001236 {
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001237 installed = 1;
1238 break;
paul4d38fdb2005-04-28 17:35:14 +00001239 }
1240 if (! installed)
1241 rib_install_kernel (rn, select);
1242 }
Paul Jakma6d691122006-07-27 21:49:00 +00001243 goto end;
paul718e3742002-12-13 20:15:29 +00001244 }
1245
Denis Ovsienkodc958242007-08-13 16:03:06 +00001246 /* At this point we either haven't found the best RIB entry or it is
1247 * different from what we currently intend to flag with SELECTED. In both
1248 * cases, if a RIB block is present in FIB, it should be withdrawn.
1249 */
paul718e3742002-12-13 20:15:29 +00001250 if (fib)
1251 {
Paul Jakma6d691122006-07-27 21:49:00 +00001252 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001253 zlog_debug ("%s: %s/%d: Removing existing route, fib %p", __func__,
1254 buf, rn->p.prefixlen, fib);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001255
1256 zfpm_trigger_update (rn, "removing existing route");
1257
paul718e3742002-12-13 20:15:29 +00001258 redistribute_delete (&rn->p, fib);
1259 if (! RIB_SYSTEM_ROUTE (fib))
1260 rib_uninstall_kernel (rn, fib);
1261 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1262
1263 /* Set real nexthop. */
1264 nexthop_active_update (rn, fib, 1);
1265 }
1266
Denis Ovsienkodc958242007-08-13 16:03:06 +00001267 /* Regardless of some RIB entry being SELECTED or not before, now we can
1268 * tell, that if a new winner exists, FIB is still not updated with this
1269 * data, but ready to be.
1270 */
paul718e3742002-12-13 20:15:29 +00001271 if (select)
1272 {
Paul Jakma6d691122006-07-27 21:49:00 +00001273 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001274 zlog_debug ("%s: %s/%d: Adding route, select %p", __func__, buf,
1275 rn->p.prefixlen, select);
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00001276
1277 zfpm_trigger_update (rn, "new route selected");
1278
paul718e3742002-12-13 20:15:29 +00001279 /* Set real nexthop. */
1280 nexthop_active_update (rn, select, 1);
1281
1282 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001283 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001284 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1285 redistribute_add (&rn->p, select);
1286 }
paul4d38fdb2005-04-28 17:35:14 +00001287
Paul Jakma6d691122006-07-27 21:49:00 +00001288 /* FIB route was removed, should be deleted */
1289 if (del)
1290 {
1291 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001292 zlog_debug ("%s: %s/%d: Deleting fib %p, rn %p", __func__, buf,
1293 rn->p.prefixlen, del, rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001294 rib_unlink (rn, del);
1295 }
paul4d38fdb2005-04-28 17:35:14 +00001296
Paul Jakma6d691122006-07-27 21:49:00 +00001297end:
1298 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma93bdada2007-08-06 19:25:11 +00001299 zlog_debug ("%s: %s/%d: rn %p dequeued", __func__, buf, rn->p.prefixlen, rn);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001300
1301 /*
1302 * Check if the dest can be deleted now.
1303 */
1304 rib_gc_dest (rn);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001305}
1306
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001307/* Take a list of route_node structs and return 1, if there was a record
1308 * picked from it and processed by rib_process(). Don't process more,
1309 * than one RN record; operate only in the specified sub-queue.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001310 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001311static unsigned int
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001312process_subq (struct list * subq, u_char qindex)
1313{
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001314 struct listnode *lnode = listhead (subq);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001315 struct route_node *rnode;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001316
1317 if (!lnode)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001318 return 0;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001319
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001320 rnode = listgetdata (lnode);
1321 rib_process (rnode);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001322
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001323 if (rnode->info)
1324 UNSET_FLAG (rib_dest_from_rnode (rnode)->flags, RIB_ROUTE_QUEUED (qindex));
1325
Chris Caputo67b94672009-07-18 04:02:26 +00001326#if 0
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001327 else
1328 {
1329 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1330 __func__, rnode, rnode->lock);
1331 zlog_backtrace(LOG_DEBUG);
1332 }
Chris Caputo67b94672009-07-18 04:02:26 +00001333#endif
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001334 route_unlock_node (rnode);
1335 list_delete_node (subq, lnode);
1336 return 1;
1337}
1338
1339/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1340 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1341 * is pointed to the meta queue structure.
1342 */
1343static wq_item_status
1344meta_queue_process (struct work_queue *dummy, void *data)
1345{
1346 struct meta_queue * mq = data;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001347 unsigned i;
1348
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001349 for (i = 0; i < MQ_SIZE; i++)
1350 if (process_subq (mq->subq[i], i))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001351 {
1352 mq->size--;
1353 break;
1354 }
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001355 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1356}
1357
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001358/*
1359 * Map from rib types to queue type (priority) in meta queue
1360 */
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001361static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
1362 [ZEBRA_ROUTE_SYSTEM] = 4,
1363 [ZEBRA_ROUTE_KERNEL] = 0,
1364 [ZEBRA_ROUTE_CONNECT] = 0,
1365 [ZEBRA_ROUTE_STATIC] = 1,
1366 [ZEBRA_ROUTE_RIP] = 2,
1367 [ZEBRA_ROUTE_RIPNG] = 2,
1368 [ZEBRA_ROUTE_OSPF] = 2,
1369 [ZEBRA_ROUTE_OSPF6] = 2,
1370 [ZEBRA_ROUTE_ISIS] = 2,
1371 [ZEBRA_ROUTE_BGP] = 3,
1372 [ZEBRA_ROUTE_HSLS] = 4,
Paul Jakma57345092011-12-25 17:52:09 +01001373 [ZEBRA_ROUTE_BABEL] = 2,
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001374};
1375
1376/* Look into the RN and queue it into one or more priority queues,
1377 * increasing the size for each data push done.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001378 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001379static void
1380rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001381{
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001382 struct rib *rib;
1383 char buf[INET6_ADDRSTRLEN];
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001384
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001385 if (IS_ZEBRA_DEBUG_RIB_Q)
1386 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001387
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001388 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001389 {
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001390 u_char qindex = meta_queue_map[rib->type];
1391
1392 /* Invariant: at this point we always have rn->info set. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001393 if (CHECK_FLAG (rib_dest_from_rnode (rn)->flags,
1394 RIB_ROUTE_QUEUED (qindex)))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001395 {
1396 if (IS_ZEBRA_DEBUG_RIB_Q)
1397 zlog_debug ("%s: %s/%d: rn %p is already queued in sub-queue %u",
1398 __func__, buf, rn->p.prefixlen, rn, qindex);
1399 continue;
1400 }
1401
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001402 SET_FLAG (rib_dest_from_rnode (rn)->flags, RIB_ROUTE_QUEUED (qindex));
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001403 listnode_add (mq->subq[qindex], rn);
1404 route_lock_node (rn);
1405 mq->size++;
1406
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001407 if (IS_ZEBRA_DEBUG_RIB_Q)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001408 zlog_debug ("%s: %s/%d: queued rn %p into sub-queue %u",
1409 __func__, buf, rn->p.prefixlen, rn, qindex);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001410 }
paul4d38fdb2005-04-28 17:35:14 +00001411}
1412
Paul Jakma6d691122006-07-27 21:49:00 +00001413/* Add route_node to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001414static void
Paul Jakma6d691122006-07-27 21:49:00 +00001415rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
paul4d38fdb2005-04-28 17:35:14 +00001416{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001417 char buf[INET_ADDRSTRLEN];
1418 assert (zebra && rn);
paul4d38fdb2005-04-28 17:35:14 +00001419
Paul Jakma93bdada2007-08-06 19:25:11 +00001420 if (IS_ZEBRA_DEBUG_RIB_Q)
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001421 inet_ntop (AF_INET, &rn->p.u.prefix, buf, INET_ADDRSTRLEN);
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001422
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001423 /* Pointless to queue a route_node with no RIB entries to add or remove */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001424 if (!rnode_to_ribs (rn))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001425 {
1426 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1427 __func__, rn, rn->lock);
1428 zlog_backtrace(LOG_DEBUG);
1429 return;
1430 }
1431
1432 if (IS_ZEBRA_DEBUG_RIB_Q)
1433 zlog_info ("%s: %s/%d: work queue added", __func__, buf, rn->p.prefixlen);
1434
1435 assert (zebra);
1436
1437 if (zebra->ribq == NULL)
1438 {
1439 zlog_err ("%s: work_queue does not exist!", __func__);
1440 return;
Paul Jakma6d691122006-07-27 21:49:00 +00001441 }
paul4d38fdb2005-04-28 17:35:14 +00001442
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001443 /*
1444 * The RIB queue should normally be either empty or holding the only
1445 * work_queue_item element. In the latter case this element would
1446 * hold a pointer to the meta queue structure, which must be used to
1447 * actually queue the route nodes to process. So create the MQ
1448 * holder, if necessary, then push the work into it in any case.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001449 * This semantics was introduced after 0.99.9 release.
1450 */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001451 if (!zebra->ribq->items->count)
1452 work_queue_add (zebra->ribq, zebra->mq);
1453
1454 rib_meta_queue_add (zebra->mq, rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001455
1456 if (IS_ZEBRA_DEBUG_RIB_Q)
1457 zlog_debug ("%s: %s/%d: rn %p queued", __func__, buf, rn->p.prefixlen, rn);
1458
1459 return;
paul4d38fdb2005-04-28 17:35:14 +00001460}
1461
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001462/* Create new meta queue.
1463 A destructor function doesn't seem to be necessary here.
1464 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001465static struct meta_queue *
1466meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001467{
1468 struct meta_queue *new;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001469 unsigned i;
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001470
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001471 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1472 assert(new);
1473
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001474 for (i = 0; i < MQ_SIZE; i++)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001475 {
1476 new->subq[i] = list_new ();
1477 assert(new->subq[i]);
1478 }
1479
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001480 return new;
1481}
1482
paul4d38fdb2005-04-28 17:35:14 +00001483/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001484static void
paul4d38fdb2005-04-28 17:35:14 +00001485rib_queue_init (struct zebra_t *zebra)
1486{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001487 assert (zebra);
1488
paul4d38fdb2005-04-28 17:35:14 +00001489 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001490 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001491 {
Paul Jakma6d691122006-07-27 21:49:00 +00001492 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001493 return;
1494 }
1495
1496 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001497 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001498 zebra->ribq->spec.errorfunc = NULL;
paul4d38fdb2005-04-28 17:35:14 +00001499 /* XXX: TODO: These should be runtime configurable via vty */
1500 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001501 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001502
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001503 if (!(zebra->mq = meta_queue_new ()))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001504 {
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001505 zlog_err ("%s: could not initialise meta queue!", __func__);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001506 return;
1507 }
1508 return;
paul718e3742002-12-13 20:15:29 +00001509}
1510
Paul Jakma6d691122006-07-27 21:49:00 +00001511/* RIB updates are processed via a queue of pointers to route_nodes.
1512 *
1513 * The queue length is bounded by the maximal size of the routing table,
1514 * as a route_node will not be requeued, if already queued.
1515 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001516 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1517 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1518 * and then submit route_node to queue for best-path selection later.
1519 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001520 *
1521 * Deleted RIBs are reaped during best-path selection.
1522 *
1523 * rib_addnode
1524 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001525 * |-------->| | best RIB, if required
1526 * | |
1527 * static_install->|->rib_addqueue...... -> rib_process
1528 * | |
1529 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001530 * |-> set RIB_ENTRY_REMOVE |
1531 * rib_delnode (RIB freed)
1532 *
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001533 * The 'info' pointer of a route_node points to a rib_dest_t
1534 * ('dest'). Queueing state for a route_node is kept on the dest. The
1535 * dest is created on-demand by rib_link() and is kept around at least
1536 * as long as there are ribs hanging off it (@see rib_gc_dest()).
Paul Jakma6d691122006-07-27 21:49:00 +00001537 *
1538 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1539 *
1540 * - route_nodes: refcounted by:
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001541 * - dest attached to route_node:
1542 * - managed by: rib_link/rib_gc_dest
Paul Jakma6d691122006-07-27 21:49:00 +00001543 * - route_node processing queue
1544 * - managed by: rib_addqueue, rib_process.
1545 *
1546 */
1547
paul718e3742002-12-13 20:15:29 +00001548/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001549static void
Paul Jakma6d691122006-07-27 21:49:00 +00001550rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001551{
1552 struct rib *head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001553 rib_dest_t *dest;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001554 char buf[INET6_ADDRSTRLEN];
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001555
paul4d38fdb2005-04-28 17:35:14 +00001556 assert (rib && rn);
1557
Paul Jakma6d691122006-07-27 21:49:00 +00001558 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001559 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001560 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001561 zlog_debug ("%s: %s/%d: rn %p, rib %p", __func__,
1562 buf, rn->p.prefixlen, rn, rib);
1563 }
Paul Jakma6d691122006-07-27 21:49:00 +00001564
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001565 dest = rib_dest_from_rnode (rn);
1566 if (!dest)
Paul Jakma6d691122006-07-27 21:49:00 +00001567 {
1568 if (IS_ZEBRA_DEBUG_RIB)
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001569 {
1570 zlog_debug ("%s: %s/%d: adding dest to table", __func__,
1571 buf, rn->p.prefixlen);
1572 }
1573
1574 dest = XCALLOC (MTYPE_RIB_DEST, sizeof (rib_dest_t));
1575 route_lock_node (rn); /* rn route table reference */
1576 rn->info = dest;
1577 dest->rnode = rn;
1578 }
1579
1580 head = dest->routes;
1581 if (head)
1582 {
Paul Jakma6d691122006-07-27 21:49:00 +00001583 head->prev = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001584 }
paul718e3742002-12-13 20:15:29 +00001585 rib->next = head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001586 dest->routes = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001587 rib_queue_add (&zebrad, rn);
1588}
1589
1590static void
1591rib_addnode (struct route_node *rn, struct rib *rib)
1592{
1593 /* RIB node has been un-removed before route-node is processed.
1594 * route_node must hence already be on the queue for processing..
1595 */
1596 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1597 {
1598 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001599 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001600 char buf[INET6_ADDRSTRLEN];
1601 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001602 zlog_debug ("%s: %s/%d: rn %p, un-removed rib %p",
1603 __func__, buf, rn->p.prefixlen, rn, rib);
1604 }
Paul Jakma6d691122006-07-27 21:49:00 +00001605 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1606 return;
1607 }
1608 rib_link (rn, rib);
1609}
1610
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001611/*
1612 * rib_unlink
1613 *
1614 * Detach a rib structure from a route_node.
1615 *
1616 * Note that a call to rib_unlink() should be followed by a call to
1617 * rib_gc_dest() at some point. This allows a rib_dest_t that is no
1618 * longer required to be deleted.
1619 */
Paul Jakma6d691122006-07-27 21:49:00 +00001620static void
1621rib_unlink (struct route_node *rn, struct rib *rib)
1622{
1623 struct nexthop *nexthop, *next;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001624 char buf[INET6_ADDRSTRLEN];
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001625 rib_dest_t *dest;
Paul Jakma6d691122006-07-27 21:49:00 +00001626
1627 assert (rn && rib);
1628
1629 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001630 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001631 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001632 zlog_debug ("%s: %s/%d: rn %p, rib %p",
1633 __func__, buf, rn->p.prefixlen, rn, rib);
1634 }
Paul Jakma6d691122006-07-27 21:49:00 +00001635
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001636 dest = rib_dest_from_rnode (rn);
1637
Paul Jakma6d691122006-07-27 21:49:00 +00001638 if (rib->next)
1639 rib->next->prev = rib->prev;
1640
1641 if (rib->prev)
1642 rib->prev->next = rib->next;
1643 else
1644 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001645 dest->routes = rib->next;
Paul Jakma6d691122006-07-27 21:49:00 +00001646 }
1647
1648 /* free RIB and nexthops */
1649 for (nexthop = rib->nexthop; nexthop; nexthop = next)
1650 {
1651 next = nexthop->next;
1652 nexthop_free (nexthop);
1653 }
1654 XFREE (MTYPE_RIB, rib);
1655
paul718e3742002-12-13 20:15:29 +00001656}
1657
paula1ac18c2005-06-28 17:17:12 +00001658static void
paul718e3742002-12-13 20:15:29 +00001659rib_delnode (struct route_node *rn, struct rib *rib)
1660{
Paul Jakma6d691122006-07-27 21:49:00 +00001661 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001662 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001663 char buf[INET6_ADDRSTRLEN];
1664 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001665 zlog_debug ("%s: %s/%d: rn %p, rib %p, removing", __func__,
1666 buf, rn->p.prefixlen, rn, rib);
1667 }
Paul Jakma6d691122006-07-27 21:49:00 +00001668 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1669 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001670}
1671
1672int
1673rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001674 struct in_addr *gate, struct in_addr *src,
1675 unsigned int ifindex, u_int32_t vrf_id,
G.Balajicddf3912011-11-26 21:59:32 +04001676 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001677{
1678 struct rib *rib;
1679 struct rib *same = NULL;
1680 struct route_table *table;
1681 struct route_node *rn;
1682 struct nexthop *nexthop;
1683
1684 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04001685 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00001686 if (! table)
1687 return 0;
1688
1689 /* Make it sure prefixlen is applied to the prefix. */
1690 apply_mask_ipv4 (p);
1691
1692 /* Set default distance by route type. */
1693 if (distance == 0)
1694 {
Balaji.G837d16c2012-09-26 14:09:10 +05301695 if ((unsigned)type >= array_size(route_info))
David Lamparter7052f222009-08-27 00:28:28 +02001696 distance = 150;
1697 else
1698 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00001699
1700 /* iBGP distance is 200. */
1701 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1702 distance = 200;
1703 }
1704
1705 /* Lookup route node.*/
1706 rn = route_node_get (table, (struct prefix *) p);
1707
1708 /* If same type of route are installed, treat it as a implicit
1709 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001710 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00001711 {
Paul Jakma6d691122006-07-27 21:49:00 +00001712 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1713 continue;
1714
hassoebf1ead2005-09-21 14:58:20 +00001715 if (rib->type != type)
1716 continue;
1717 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001718 {
1719 same = rib;
1720 break;
1721 }
hassoebf1ead2005-09-21 14:58:20 +00001722 /* Duplicate connected route comes in. */
1723 else if ((nexthop = rib->nexthop) &&
1724 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001725 nexthop->ifindex == ifindex &&
1726 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001727 {
1728 rib->refcnt++;
1729 return 0 ;
1730 }
paul718e3742002-12-13 20:15:29 +00001731 }
1732
1733 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001734 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001735 rib->type = type;
1736 rib->distance = distance;
1737 rib->flags = flags;
1738 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001739 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001740 rib->nexthop_num = 0;
1741 rib->uptime = time (NULL);
1742
1743 /* Nexthop settings. */
1744 if (gate)
1745 {
1746 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001747 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001748 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001749 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001750 }
1751 else
1752 nexthop_ifindex_add (rib, ifindex);
1753
1754 /* If this route is kernel route, set FIB flag to the route. */
1755 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1756 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1757 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1758
1759 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001760 if (IS_ZEBRA_DEBUG_RIB)
1761 zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
paul718e3742002-12-13 20:15:29 +00001762 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001763
paul718e3742002-12-13 20:15:29 +00001764 /* Free implicit route.*/
1765 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001766 {
1767 if (IS_ZEBRA_DEBUG_RIB)
1768 zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001769 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001770 }
paul4d38fdb2005-04-28 17:35:14 +00001771
1772 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001773 return 0;
1774}
1775
Denis Ovsienkodc958242007-08-13 16:03:06 +00001776/* This function dumps the contents of a given RIB entry into
1777 * standard debug log. Calling function name and IP prefix in
1778 * question are passed as 1st and 2nd arguments.
1779 */
1780
1781void rib_dump (const char * func, const struct prefix_ipv4 * p, const struct rib * rib)
1782{
1783 char straddr1[INET_ADDRSTRLEN], straddr2[INET_ADDRSTRLEN];
1784 struct nexthop *nexthop;
1785
1786 inet_ntop (AF_INET, &p->prefix, straddr1, INET_ADDRSTRLEN);
1787 zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr1, p->prefixlen);
1788 zlog_debug
1789 (
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001790 "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
Denis Ovsienkodc958242007-08-13 16:03:06 +00001791 func,
1792 rib->refcnt,
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001793 (unsigned long) rib->uptime,
Denis Ovsienkodc958242007-08-13 16:03:06 +00001794 rib->type,
1795 rib->table
1796 );
1797 zlog_debug
1798 (
1799 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1800 func,
1801 rib->metric,
1802 rib->distance,
1803 rib->flags,
1804 rib->status
1805 );
1806 zlog_debug
1807 (
1808 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1809 func,
1810 rib->nexthop_num,
1811 rib->nexthop_active_num,
1812 rib->nexthop_fib_num
1813 );
1814 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1815 {
1816 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, straddr1, INET_ADDRSTRLEN);
1817 inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, straddr2, INET_ADDRSTRLEN);
1818 zlog_debug
1819 (
1820 "%s: NH %s (%s) with flags %s%s%s",
1821 func,
1822 straddr1,
1823 straddr2,
1824 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1825 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1826 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1827 );
1828 }
1829 zlog_debug ("%s: dump complete", func);
1830}
1831
1832/* This is an exported helper to rtm_read() to dump the strange
1833 * RIB entry found by rib_lookup_ipv4_route()
1834 */
1835
1836void rib_lookup_and_dump (struct prefix_ipv4 * p)
1837{
1838 struct route_table *table;
1839 struct route_node *rn;
1840 struct rib *rib;
1841 char prefix_buf[INET_ADDRSTRLEN];
1842
1843 /* Lookup table. */
1844 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1845 if (! table)
1846 {
1847 zlog_err ("%s: vrf_table() returned NULL", __func__);
1848 return;
1849 }
1850
1851 inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
1852 /* Scan the RIB table for exactly matching RIB entry. */
1853 rn = route_node_lookup (table, (struct prefix *) p);
1854
1855 /* No route for this prefix. */
1856 if (! rn)
1857 {
1858 zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
1859 return;
1860 }
1861
1862 /* Unlock node. */
1863 route_unlock_node (rn);
1864
1865 /* let's go */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001866 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001867 {
1868 zlog_debug
1869 (
1870 "%s: rn %p, rib %p: %s, %s",
1871 __func__,
1872 rn,
1873 rib,
1874 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
1875 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
1876 );
1877 rib_dump (__func__, p, rib);
1878 }
1879}
1880
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001881/* Check if requested address assignment will fail due to another
1882 * route being installed by zebra in FIB already. Take necessary
1883 * actions, if needed: remove such a route from FIB and deSELECT
1884 * corresponding RIB entry. Then put affected RN into RIBQ head.
1885 */
1886void rib_lookup_and_pushup (struct prefix_ipv4 * p)
1887{
1888 struct route_table *table;
1889 struct route_node *rn;
1890 struct rib *rib;
1891 unsigned changed = 0;
1892
1893 if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
1894 {
1895 zlog_err ("%s: vrf_table() returned NULL", __func__);
1896 return;
1897 }
1898
1899 /* No matches would be the simplest case. */
1900 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
1901 return;
1902
1903 /* Unlock node. */
1904 route_unlock_node (rn);
1905
1906 /* Check all RIB entries. In case any changes have to be done, requeue
1907 * the RN into RIBQ head. If the routing message about the new connected
1908 * route (generated by the IP address we are going to assign very soon)
1909 * comes before the RIBQ is processed, the new RIB entry will join
1910 * RIBQ record already on head. This is necessary for proper revalidation
1911 * of the rest of the RIB.
1912 */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001913 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001914 {
1915 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
1916 ! RIB_SYSTEM_ROUTE (rib))
1917 {
1918 changed = 1;
1919 if (IS_ZEBRA_DEBUG_RIB)
1920 {
1921 char buf[INET_ADDRSTRLEN];
1922 inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
1923 zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
1924 rib_dump (__func__, (struct prefix_ipv4 *)&rn->p, rib);
1925 }
1926 rib_uninstall (rn, rib);
1927 }
1928 }
1929 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001930 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001931}
1932
paul718e3742002-12-13 20:15:29 +00001933int
G.Balajicddf3912011-11-26 21:59:32 +04001934rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001935{
1936 struct route_table *table;
1937 struct route_node *rn;
1938 struct rib *same;
1939 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00001940
paul718e3742002-12-13 20:15:29 +00001941 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04001942 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00001943 if (! table)
1944 return 0;
G.Balajicddf3912011-11-26 21:59:32 +04001945
paul718e3742002-12-13 20:15:29 +00001946 /* Make it sure prefixlen is applied to the prefix. */
1947 apply_mask_ipv4 (p);
1948
1949 /* Set default distance by route type. */
1950 if (rib->distance == 0)
1951 {
1952 rib->distance = route_info[rib->type].distance;
1953
1954 /* iBGP distance is 200. */
1955 if (rib->type == ZEBRA_ROUTE_BGP
1956 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1957 rib->distance = 200;
1958 }
1959
1960 /* Lookup route node.*/
1961 rn = route_node_get (table, (struct prefix *) p);
1962
1963 /* If same type of route are installed, treat it as a implicit
1964 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001965 RNODE_FOREACH_RIB (rn, same)
paul718e3742002-12-13 20:15:29 +00001966 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00001967 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00001968 continue;
1969
paul718e3742002-12-13 20:15:29 +00001970 if (same->type == rib->type && same->table == rib->table
1971 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001972 break;
paul718e3742002-12-13 20:15:29 +00001973 }
paul4d38fdb2005-04-28 17:35:14 +00001974
paul718e3742002-12-13 20:15:29 +00001975 /* If this route is kernel route, set FIB flag to the route. */
1976 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
1977 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1978 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1979
1980 /* Link new rib to node.*/
1981 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001982 if (IS_ZEBRA_DEBUG_RIB)
1983 {
1984 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
1985 __func__, rn, rib);
1986 rib_dump (__func__, p, rib);
1987 }
paul718e3742002-12-13 20:15:29 +00001988
paul718e3742002-12-13 20:15:29 +00001989 /* Free implicit route.*/
1990 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001991 {
1992 if (IS_ZEBRA_DEBUG_RIB)
1993 {
1994 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
1995 __func__, rn, same);
1996 rib_dump (__func__, p, same);
1997 }
paul4d38fdb2005-04-28 17:35:14 +00001998 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001999 }
paul4d38fdb2005-04-28 17:35:14 +00002000
2001 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002002 return 0;
2003}
2004
hassoebf1ead2005-09-21 14:58:20 +00002005/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002006int
2007rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
G.Balajicddf3912011-11-26 21:59:32 +04002008 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002009{
2010 struct route_table *table;
2011 struct route_node *rn;
2012 struct rib *rib;
2013 struct rib *fib = NULL;
2014 struct rib *same = NULL;
2015 struct nexthop *nexthop;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002016 char buf1[INET_ADDRSTRLEN];
2017 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002018
2019 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04002020 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00002021 if (! table)
2022 return 0;
2023
2024 /* Apply mask. */
2025 apply_mask_ipv4 (p);
2026
paul5ec90d22003-06-19 01:41:37 +00002027 if (IS_ZEBRA_DEBUG_KERNEL && gate)
ajsb6178002004-12-07 21:12:56 +00002028 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002029 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul5ec90d22003-06-19 01:41:37 +00002030 p->prefixlen,
2031 inet_ntoa (*gate),
2032 ifindex);
2033
paul718e3742002-12-13 20:15:29 +00002034 /* Lookup route node. */
2035 rn = route_node_lookup (table, (struct prefix *) p);
2036 if (! rn)
2037 {
2038 if (IS_ZEBRA_DEBUG_KERNEL)
2039 {
2040 if (gate)
ajsb6178002004-12-07 21:12:56 +00002041 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002042 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002043 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002044 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002045 ifindex);
2046 else
ajsb6178002004-12-07 21:12:56 +00002047 zlog_debug ("route %s/%d 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,
2050 ifindex);
2051 }
2052 return ZEBRA_ERR_RTNOEXIST;
2053 }
2054
2055 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002056 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002057 {
Paul Jakma6d691122006-07-27 21:49:00 +00002058 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2059 continue;
2060
paul718e3742002-12-13 20:15:29 +00002061 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2062 fib = rib;
2063
hassoebf1ead2005-09-21 14:58:20 +00002064 if (rib->type != type)
2065 continue;
2066 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002067 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002068 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002069 if (nexthop->ifindex != ifindex)
2070 continue;
hassoebf1ead2005-09-21 14:58:20 +00002071 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002072 {
hassoebf1ead2005-09-21 14:58:20 +00002073 rib->refcnt--;
2074 route_unlock_node (rn);
2075 route_unlock_node (rn);
2076 return 0;
paul718e3742002-12-13 20:15:29 +00002077 }
hassoebf1ead2005-09-21 14:58:20 +00002078 same = rib;
2079 break;
paul718e3742002-12-13 20:15:29 +00002080 }
hassoebf1ead2005-09-21 14:58:20 +00002081 /* Make sure that the route found has the same gateway. */
2082 else if (gate == NULL ||
2083 ((nexthop = rib->nexthop) &&
2084 (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
2085 IPV4_ADDR_SAME (&nexthop->rgate.ipv4, gate))))
paul5ec90d22003-06-19 01:41:37 +00002086 {
hassoebf1ead2005-09-21 14:58:20 +00002087 same = rib;
2088 break;
paul718e3742002-12-13 20:15:29 +00002089 }
2090 }
2091
2092 /* If same type of route can't be found and this message is from
2093 kernel. */
2094 if (! same)
2095 {
2096 if (fib && type == ZEBRA_ROUTE_KERNEL)
2097 {
2098 /* Unset flags. */
2099 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2100 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2101
2102 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2103 }
2104 else
2105 {
2106 if (IS_ZEBRA_DEBUG_KERNEL)
2107 {
2108 if (gate)
ajsb6178002004-12-07 21:12:56 +00002109 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002110 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002111 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002112 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002113 ifindex,
2114 type);
2115 else
ajsb6178002004-12-07 21:12:56 +00002116 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002117 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002118 p->prefixlen,
2119 ifindex,
2120 type);
2121 }
2122 route_unlock_node (rn);
2123 return ZEBRA_ERR_RTNOEXIST;
2124 }
2125 }
paul4d38fdb2005-04-28 17:35:14 +00002126
paul718e3742002-12-13 20:15:29 +00002127 if (same)
2128 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002129
paul718e3742002-12-13 20:15:29 +00002130 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002131 return 0;
2132}
2133
2134/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002135static void
paul718e3742002-12-13 20:15:29 +00002136static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
2137{
2138 struct rib *rib;
2139 struct route_node *rn;
2140 struct route_table *table;
2141
2142 /* Lookup table. */
2143 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2144 if (! table)
2145 return;
2146
2147 /* Lookup existing route */
2148 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002149 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002150 {
2151 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2152 continue;
2153
2154 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2155 break;
2156 }
paul718e3742002-12-13 20:15:29 +00002157
2158 if (rib)
2159 {
2160 /* Same distance static route is there. Update it with new
2161 nexthop. */
paul718e3742002-12-13 20:15:29 +00002162 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002163 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002164 {
2165 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002166 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002167 break;
2168 case STATIC_IPV4_IFNAME:
2169 nexthop_ifname_add (rib, si->gate.ifname);
2170 break;
2171 case STATIC_IPV4_BLACKHOLE:
2172 nexthop_blackhole_add (rib);
2173 break;
paul4d38fdb2005-04-28 17:35:14 +00002174 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002175 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002176 }
2177 else
2178 {
2179 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002180 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2181
paul718e3742002-12-13 20:15:29 +00002182 rib->type = ZEBRA_ROUTE_STATIC;
2183 rib->distance = si->distance;
2184 rib->metric = 0;
Nolan Leakeb0145dd2012-09-13 17:17:31 +00002185 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002186 rib->nexthop_num = 0;
2187
2188 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002189 {
2190 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002191 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002192 break;
2193 case STATIC_IPV4_IFNAME:
2194 nexthop_ifname_add (rib, si->gate.ifname);
2195 break;
2196 case STATIC_IPV4_BLACKHOLE:
2197 nexthop_blackhole_add (rib);
2198 break;
2199 }
paul718e3742002-12-13 20:15:29 +00002200
hasso81dfcaa2003-05-25 19:21:25 +00002201 /* Save the flags of this static routes (reject, blackhole) */
2202 rib->flags = si->flags;
2203
paul718e3742002-12-13 20:15:29 +00002204 /* Link this rib to the tree. */
2205 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002206 }
2207}
2208
paula1ac18c2005-06-28 17:17:12 +00002209static int
paul718e3742002-12-13 20:15:29 +00002210static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2211{
2212 if (nexthop->type == NEXTHOP_TYPE_IPV4
2213 && si->type == STATIC_IPV4_GATEWAY
2214 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2215 return 1;
2216 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2217 && si->type == STATIC_IPV4_IFNAME
2218 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2219 return 1;
paul595db7f2003-05-25 21:35:06 +00002220 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2221 && si->type == STATIC_IPV4_BLACKHOLE)
2222 return 1;
paule8e19462006-01-19 20:16:55 +00002223 return 0;
paul718e3742002-12-13 20:15:29 +00002224}
2225
2226/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002227static void
paul718e3742002-12-13 20:15:29 +00002228static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
2229{
2230 struct route_node *rn;
2231 struct rib *rib;
2232 struct nexthop *nexthop;
2233 struct route_table *table;
2234
2235 /* Lookup table. */
2236 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2237 if (! table)
2238 return;
paul4d38fdb2005-04-28 17:35:14 +00002239
paul718e3742002-12-13 20:15:29 +00002240 /* Lookup existing route with type and distance. */
2241 rn = route_node_lookup (table, p);
2242 if (! rn)
2243 return;
2244
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002245 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002246 {
2247 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2248 continue;
2249
2250 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2251 break;
2252 }
paul718e3742002-12-13 20:15:29 +00002253
2254 if (! rib)
2255 {
2256 route_unlock_node (rn);
2257 return;
2258 }
2259
2260 /* Lookup nexthop. */
2261 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2262 if (static_ipv4_nexthop_same (nexthop, si))
2263 break;
2264
2265 /* Can't find nexthop. */
2266 if (! nexthop)
2267 {
2268 route_unlock_node (rn);
2269 return;
2270 }
2271
2272 /* Check nexthop. */
2273 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002274 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002275 else
2276 {
paul6baeb982003-10-28 03:47:15 +00002277 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2278 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002279 nexthop_delete (rib, nexthop);
2280 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002281 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002282 }
paul718e3742002-12-13 20:15:29 +00002283 /* Unlock node. */
2284 route_unlock_node (rn);
2285}
2286
2287/* Add static route into static route configuration. */
2288int
hasso39db97e2004-10-12 20:50:58 +00002289static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00002290 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002291{
2292 u_char type = 0;
2293 struct route_node *rn;
2294 struct static_ipv4 *si;
2295 struct static_ipv4 *pp;
2296 struct static_ipv4 *cp;
2297 struct static_ipv4 *update = NULL;
2298 struct route_table *stable;
2299
2300 /* Lookup table. */
2301 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2302 if (! stable)
2303 return -1;
2304
2305 /* Lookup static route prefix. */
2306 rn = route_node_get (stable, p);
2307
2308 /* Make flags. */
2309 if (gate)
2310 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002311 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002312 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002313 else
2314 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002315
2316 /* Do nothing if there is a same static route. */
2317 for (si = rn->info; si; si = si->next)
2318 {
2319 if (type == si->type
2320 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2321 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2322 {
2323 if (distance == si->distance)
2324 {
2325 route_unlock_node (rn);
2326 return 0;
2327 }
2328 else
2329 update = si;
2330 }
2331 }
2332
Paul Jakma3c0755d2006-12-08 00:53:14 +00002333 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002334 if (update)
2335 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
2336
2337 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002338 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
paul718e3742002-12-13 20:15:29 +00002339
2340 si->type = type;
2341 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002342 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002343
2344 if (gate)
2345 si->gate.ipv4 = *gate;
2346 if (ifname)
2347 si->gate.ifname = XSTRDUP (0, ifname);
2348
2349 /* Add new static route information to the tree with sort by
2350 distance value and gateway address. */
2351 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2352 {
2353 if (si->distance < cp->distance)
2354 break;
2355 if (si->distance > cp->distance)
2356 continue;
2357 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2358 {
2359 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2360 break;
2361 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2362 continue;
2363 }
2364 }
2365
2366 /* Make linked list. */
2367 if (pp)
2368 pp->next = si;
2369 else
2370 rn->info = si;
2371 if (cp)
2372 cp->prev = si;
2373 si->prev = pp;
2374 si->next = cp;
2375
2376 /* Install into rib. */
2377 static_install_ipv4 (p, si);
2378
2379 return 1;
2380}
2381
2382/* Delete static route from static route configuration. */
2383int
hasso39db97e2004-10-12 20:50:58 +00002384static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00002385 u_char distance, u_int32_t vrf_id)
2386{
2387 u_char type = 0;
2388 struct route_node *rn;
2389 struct static_ipv4 *si;
2390 struct route_table *stable;
2391
2392 /* Lookup table. */
2393 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2394 if (! stable)
2395 return -1;
2396
2397 /* Lookup static route prefix. */
2398 rn = route_node_lookup (stable, p);
2399 if (! rn)
2400 return 0;
2401
2402 /* Make flags. */
2403 if (gate)
2404 type = STATIC_IPV4_GATEWAY;
2405 else if (ifname)
2406 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002407 else
2408 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002409
2410 /* Find same static route is the tree */
2411 for (si = rn->info; si; si = si->next)
2412 if (type == si->type
2413 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2414 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2415 break;
2416
2417 /* Can't find static route. */
2418 if (! si)
2419 {
2420 route_unlock_node (rn);
2421 return 0;
2422 }
2423
2424 /* Install into rib. */
2425 static_uninstall_ipv4 (p, si);
2426
2427 /* Unlink static route from linked list. */
2428 if (si->prev)
2429 si->prev->next = si->next;
2430 else
2431 rn->info = si->next;
2432 if (si->next)
2433 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002434 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002435
2436 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002437 if (ifname)
2438 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002439 XFREE (MTYPE_STATIC_IPV4, si);
2440
paul143a3852003-09-29 20:06:13 +00002441 route_unlock_node (rn);
2442
paul718e3742002-12-13 20:15:29 +00002443 return 1;
2444}
2445
2446
2447#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00002448static int
paul718e3742002-12-13 20:15:29 +00002449rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2450 struct in6_addr *gate, unsigned int ifindex, int table)
2451{
hasso726f9b22003-05-25 21:04:54 +00002452 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2453#if defined (MUSICA) || defined (LINUX)
2454 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2455 if (p->prefixlen == 96)
2456 return 0;
2457#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00002458 return 1;
hasso726f9b22003-05-25 21:04:54 +00002459 }
paul718e3742002-12-13 20:15:29 +00002460 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
2461 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
2462 {
2463 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
2464 return 1;
2465 }
2466 return 0;
2467}
2468
2469int
2470rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00002471 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
G.Balajif768f362011-11-26 22:10:39 +04002472 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002473{
2474 struct rib *rib;
2475 struct rib *same = NULL;
2476 struct route_table *table;
2477 struct route_node *rn;
2478 struct nexthop *nexthop;
2479
paul718e3742002-12-13 20:15:29 +00002480 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002481 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002482 if (! table)
2483 return 0;
2484
2485 /* Make sure mask is applied. */
2486 apply_mask_ipv6 (p);
2487
2488 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002489 if (!distance)
2490 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002491
2492 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2493 distance = 200;
2494
2495 /* Filter bogus route. */
2496 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
2497 return 0;
2498
2499 /* Lookup route node.*/
2500 rn = route_node_get (table, (struct prefix *) p);
2501
2502 /* If same type of route are installed, treat it as a implicit
2503 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002504 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002505 {
Paul Jakma6d691122006-07-27 21:49:00 +00002506 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2507 continue;
2508
hassoebf1ead2005-09-21 14:58:20 +00002509 if (rib->type != type)
2510 continue;
2511 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002512 {
2513 same = rib;
paul718e3742002-12-13 20:15:29 +00002514 break;
2515 }
hassoebf1ead2005-09-21 14:58:20 +00002516 else if ((nexthop = rib->nexthop) &&
2517 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2518 nexthop->ifindex == ifindex)
2519 {
2520 rib->refcnt++;
2521 return 0;
2522 }
paul718e3742002-12-13 20:15:29 +00002523 }
2524
2525 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002526 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2527
paul718e3742002-12-13 20:15:29 +00002528 rib->type = type;
2529 rib->distance = distance;
2530 rib->flags = flags;
2531 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00002532 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00002533 rib->nexthop_num = 0;
2534 rib->uptime = time (NULL);
2535
2536 /* Nexthop settings. */
2537 if (gate)
2538 {
2539 if (ifindex)
2540 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2541 else
2542 nexthop_ipv6_add (rib, gate);
2543 }
2544 else
2545 nexthop_ifindex_add (rib, ifindex);
2546
2547 /* If this route is kernel route, set FIB flag to the route. */
2548 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2549 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2550 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2551
2552 /* Link new rib to node.*/
2553 rib_addnode (rn, rib);
2554
paul718e3742002-12-13 20:15:29 +00002555 /* Free implicit route.*/
2556 if (same)
paul4d38fdb2005-04-28 17:35:14 +00002557 rib_delnode (rn, same);
2558
2559 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002560 return 0;
2561}
2562
hassoebf1ead2005-09-21 14:58:20 +00002563/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002564int
2565rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
G.Balajif768f362011-11-26 22:10:39 +04002566 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002567{
2568 struct route_table *table;
2569 struct route_node *rn;
2570 struct rib *rib;
2571 struct rib *fib = NULL;
2572 struct rib *same = NULL;
2573 struct nexthop *nexthop;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002574 char buf1[INET6_ADDRSTRLEN];
2575 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002576
2577 /* Apply mask. */
2578 apply_mask_ipv6 (p);
2579
2580 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002581 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002582 if (! table)
2583 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002584
paul718e3742002-12-13 20:15:29 +00002585 /* Lookup route node. */
2586 rn = route_node_lookup (table, (struct prefix *) p);
2587 if (! rn)
2588 {
2589 if (IS_ZEBRA_DEBUG_KERNEL)
2590 {
2591 if (gate)
ajsb6178002004-12-07 21:12:56 +00002592 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002593 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002594 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002595 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002596 ifindex);
2597 else
ajsb6178002004-12-07 21:12:56 +00002598 zlog_debug ("route %s/%d 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,
2601 ifindex);
2602 }
2603 return ZEBRA_ERR_RTNOEXIST;
2604 }
2605
2606 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002607 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002608 {
Paul Jakma6d691122006-07-27 21:49:00 +00002609 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2610 continue;
2611
paul718e3742002-12-13 20:15:29 +00002612 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2613 fib = rib;
2614
hassoebf1ead2005-09-21 14:58:20 +00002615 if (rib->type != type)
2616 continue;
2617 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002618 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002619 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002620 if (nexthop->ifindex != ifindex)
2621 continue;
hassoebf1ead2005-09-21 14:58:20 +00002622 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002623 {
hassoebf1ead2005-09-21 14:58:20 +00002624 rib->refcnt--;
2625 route_unlock_node (rn);
2626 route_unlock_node (rn);
2627 return 0;
paul718e3742002-12-13 20:15:29 +00002628 }
hassoebf1ead2005-09-21 14:58:20 +00002629 same = rib;
2630 break;
paul718e3742002-12-13 20:15:29 +00002631 }
hassoebf1ead2005-09-21 14:58:20 +00002632 /* Make sure that the route found has the same gateway. */
2633 else if (gate == NULL ||
2634 ((nexthop = rib->nexthop) &&
2635 (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate) ||
2636 IPV6_ADDR_SAME (&nexthop->rgate.ipv6, gate))))
paul718e3742002-12-13 20:15:29 +00002637 {
hassoebf1ead2005-09-21 14:58:20 +00002638 same = rib;
2639 break;
paul718e3742002-12-13 20:15:29 +00002640 }
2641 }
2642
2643 /* If same type of route can't be found and this message is from
2644 kernel. */
2645 if (! same)
2646 {
2647 if (fib && type == ZEBRA_ROUTE_KERNEL)
2648 {
2649 /* Unset flags. */
2650 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2651 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2652
2653 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2654 }
2655 else
2656 {
2657 if (IS_ZEBRA_DEBUG_KERNEL)
2658 {
2659 if (gate)
ajsb6178002004-12-07 21:12:56 +00002660 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002661 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002662 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002663 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002664 ifindex,
2665 type);
2666 else
ajsb6178002004-12-07 21:12:56 +00002667 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002668 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002669 p->prefixlen,
2670 ifindex,
2671 type);
2672 }
2673 route_unlock_node (rn);
2674 return ZEBRA_ERR_RTNOEXIST;
2675 }
2676 }
2677
2678 if (same)
2679 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002680
paul718e3742002-12-13 20:15:29 +00002681 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002682 return 0;
2683}
2684
2685/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002686static void
paul718e3742002-12-13 20:15:29 +00002687static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2688{
2689 struct rib *rib;
2690 struct route_table *table;
2691 struct route_node *rn;
2692
2693 /* Lookup table. */
2694 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2695 if (! table)
2696 return;
2697
2698 /* Lookup existing route */
2699 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002700 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002701 {
2702 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2703 continue;
2704
2705 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2706 break;
2707 }
paul718e3742002-12-13 20:15:29 +00002708
2709 if (rib)
2710 {
2711 /* Same distance static route is there. Update it with new
2712 nexthop. */
paul718e3742002-12-13 20:15:29 +00002713 route_unlock_node (rn);
2714
2715 switch (si->type)
2716 {
2717 case STATIC_IPV6_GATEWAY:
2718 nexthop_ipv6_add (rib, &si->ipv6);
2719 break;
2720 case STATIC_IPV6_IFNAME:
2721 nexthop_ifname_add (rib, si->ifname);
2722 break;
2723 case STATIC_IPV6_GATEWAY_IFNAME:
2724 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2725 break;
2726 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002727 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002728 }
2729 else
2730 {
2731 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002732 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2733
paul718e3742002-12-13 20:15:29 +00002734 rib->type = ZEBRA_ROUTE_STATIC;
2735 rib->distance = si->distance;
2736 rib->metric = 0;
2737 rib->nexthop_num = 0;
2738
2739 switch (si->type)
2740 {
2741 case STATIC_IPV6_GATEWAY:
2742 nexthop_ipv6_add (rib, &si->ipv6);
2743 break;
2744 case STATIC_IPV6_IFNAME:
2745 nexthop_ifname_add (rib, si->ifname);
2746 break;
2747 case STATIC_IPV6_GATEWAY_IFNAME:
2748 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2749 break;
2750 }
2751
hasso81dfcaa2003-05-25 19:21:25 +00002752 /* Save the flags of this static routes (reject, blackhole) */
2753 rib->flags = si->flags;
2754
paul718e3742002-12-13 20:15:29 +00002755 /* Link this rib to the tree. */
2756 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002757 }
2758}
2759
paula1ac18c2005-06-28 17:17:12 +00002760static int
paul718e3742002-12-13 20:15:29 +00002761static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2762{
2763 if (nexthop->type == NEXTHOP_TYPE_IPV6
2764 && si->type == STATIC_IPV6_GATEWAY
2765 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2766 return 1;
2767 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2768 && si->type == STATIC_IPV6_IFNAME
2769 && strcmp (nexthop->ifname, si->ifname) == 0)
2770 return 1;
2771 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2772 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2773 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2774 && strcmp (nexthop->ifname, si->ifname) == 0)
2775 return 1;
paule8e19462006-01-19 20:16:55 +00002776 return 0;
paul718e3742002-12-13 20:15:29 +00002777}
2778
paula1ac18c2005-06-28 17:17:12 +00002779static void
paul718e3742002-12-13 20:15:29 +00002780static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2781{
2782 struct route_table *table;
2783 struct route_node *rn;
2784 struct rib *rib;
2785 struct nexthop *nexthop;
2786
2787 /* Lookup table. */
2788 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2789 if (! table)
2790 return;
2791
2792 /* Lookup existing route with type and distance. */
2793 rn = route_node_lookup (table, (struct prefix *) p);
2794 if (! rn)
2795 return;
2796
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002797 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002798 {
2799 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2800 continue;
2801
2802 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2803 break;
2804 }
2805
paul718e3742002-12-13 20:15:29 +00002806 if (! rib)
2807 {
2808 route_unlock_node (rn);
2809 return;
2810 }
2811
2812 /* Lookup nexthop. */
2813 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2814 if (static_ipv6_nexthop_same (nexthop, si))
2815 break;
2816
2817 /* Can't find nexthop. */
2818 if (! nexthop)
2819 {
2820 route_unlock_node (rn);
2821 return;
2822 }
2823
2824 /* Check nexthop. */
2825 if (rib->nexthop_num == 1)
2826 {
2827 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002828 }
2829 else
2830 {
paul6baeb982003-10-28 03:47:15 +00002831 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2832 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002833 nexthop_delete (rib, nexthop);
2834 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002835 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002836 }
paul718e3742002-12-13 20:15:29 +00002837 /* Unlock node. */
2838 route_unlock_node (rn);
2839}
2840
2841/* Add static route into static route configuration. */
2842int
2843static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002844 const char *ifname, u_char flags, u_char distance,
2845 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002846{
2847 struct route_node *rn;
2848 struct static_ipv6 *si;
2849 struct static_ipv6 *pp;
2850 struct static_ipv6 *cp;
2851 struct route_table *stable;
2852
2853 /* Lookup table. */
2854 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2855 if (! stable)
2856 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00002857
2858 if (!gate &&
2859 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
2860 return -1;
2861
2862 if (!ifname &&
2863 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
2864 return -1;
paul718e3742002-12-13 20:15:29 +00002865
2866 /* Lookup static route prefix. */
2867 rn = route_node_get (stable, p);
2868
2869 /* Do nothing if there is a same static route. */
2870 for (si = rn->info; si; si = si->next)
2871 {
2872 if (distance == si->distance
2873 && type == si->type
2874 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2875 && (! ifname || strcmp (ifname, si->ifname) == 0))
2876 {
2877 route_unlock_node (rn);
2878 return 0;
2879 }
2880 }
2881
2882 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002883 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
paul718e3742002-12-13 20:15:29 +00002884
2885 si->type = type;
2886 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002887 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002888
2889 switch (type)
2890 {
2891 case STATIC_IPV6_GATEWAY:
2892 si->ipv6 = *gate;
2893 break;
2894 case STATIC_IPV6_IFNAME:
2895 si->ifname = XSTRDUP (0, ifname);
2896 break;
2897 case STATIC_IPV6_GATEWAY_IFNAME:
2898 si->ipv6 = *gate;
2899 si->ifname = XSTRDUP (0, ifname);
2900 break;
2901 }
2902
2903 /* Add new static route information to the tree with sort by
2904 distance value and gateway address. */
2905 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2906 {
2907 if (si->distance < cp->distance)
2908 break;
2909 if (si->distance > cp->distance)
2910 continue;
2911 }
2912
2913 /* Make linked list. */
2914 if (pp)
2915 pp->next = si;
2916 else
2917 rn->info = si;
2918 if (cp)
2919 cp->prev = si;
2920 si->prev = pp;
2921 si->next = cp;
2922
2923 /* Install into rib. */
2924 static_install_ipv6 (p, si);
2925
2926 return 1;
2927}
2928
2929/* Delete static route from static route configuration. */
2930int
2931static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002932 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002933{
2934 struct route_node *rn;
2935 struct static_ipv6 *si;
2936 struct route_table *stable;
2937
2938 /* Lookup table. */
2939 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2940 if (! stable)
2941 return -1;
2942
2943 /* Lookup static route prefix. */
2944 rn = route_node_lookup (stable, p);
2945 if (! rn)
2946 return 0;
2947
2948 /* Find same static route is the tree */
2949 for (si = rn->info; si; si = si->next)
2950 if (distance == si->distance
2951 && type == si->type
2952 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2953 && (! ifname || strcmp (ifname, si->ifname) == 0))
2954 break;
2955
2956 /* Can't find static route. */
2957 if (! si)
2958 {
2959 route_unlock_node (rn);
2960 return 0;
2961 }
2962
2963 /* Install into rib. */
2964 static_uninstall_ipv6 (p, si);
2965
2966 /* Unlink static route from linked list. */
2967 if (si->prev)
2968 si->prev->next = si->next;
2969 else
2970 rn->info = si->next;
2971 if (si->next)
2972 si->next->prev = si->prev;
2973
2974 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002975 if (ifname)
2976 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00002977 XFREE (MTYPE_STATIC_IPV6, si);
2978
2979 return 1;
2980}
2981#endif /* HAVE_IPV6 */
2982
2983/* RIB update function. */
2984void
paula1ac18c2005-06-28 17:17:12 +00002985rib_update (void)
paul718e3742002-12-13 20:15:29 +00002986{
2987 struct route_node *rn;
2988 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00002989
paul718e3742002-12-13 20:15:29 +00002990 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2991 if (table)
2992 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002993 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00002994 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002995
2996 table = vrf_table (AFI_IP6, 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
paul718e3742002-12-13 20:15:29 +00003003
3004/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00003005static void
paul718e3742002-12-13 20:15:29 +00003006rib_weed_table (struct route_table *table)
3007{
3008 struct route_node *rn;
3009 struct rib *rib;
3010 struct rib *next;
3011
3012 if (table)
3013 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003014 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003015 {
Paul Jakma6d691122006-07-27 21:49:00 +00003016 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3017 continue;
3018
paulb21b19c2003-06-15 01:28:29 +00003019 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00003020 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00003021 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003022 }
3023}
3024
3025/* Delete all routes from non main table. */
3026void
paula1ac18c2005-06-28 17:17:12 +00003027rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00003028{
3029 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3030 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3031}
3032
3033/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00003034static void
paul718e3742002-12-13 20:15:29 +00003035rib_sweep_table (struct route_table *table)
3036{
3037 struct route_node *rn;
3038 struct rib *rib;
3039 struct rib *next;
3040 int ret = 0;
3041
3042 if (table)
3043 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003044 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00003045 {
Paul Jakma6d691122006-07-27 21:49:00 +00003046 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3047 continue;
3048
paul718e3742002-12-13 20:15:29 +00003049 if (rib->type == ZEBRA_ROUTE_KERNEL &&
3050 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
3051 {
3052 ret = rib_uninstall_kernel (rn, rib);
3053 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00003054 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00003055 }
3056 }
3057}
3058
3059/* Sweep all RIB tables. */
3060void
paula1ac18c2005-06-28 17:17:12 +00003061rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00003062{
3063 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3064 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3065}
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003066
3067/* Remove specific by protocol routes from 'table'. */
3068static unsigned long
3069rib_score_proto_table (u_char proto, struct route_table *table)
3070{
3071 struct route_node *rn;
3072 struct rib *rib;
3073 struct rib *next;
3074 unsigned long n = 0;
3075
3076 if (table)
3077 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003078 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003079 {
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003080 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3081 continue;
3082 if (rib->type == proto)
3083 {
3084 rib_delnode (rn, rib);
3085 n++;
3086 }
3087 }
3088
3089 return n;
3090}
3091
3092/* Remove specific by protocol routes. */
3093unsigned long
3094rib_score_proto (u_char proto)
3095{
3096 return rib_score_proto_table (proto, vrf_table (AFI_IP, SAFI_UNICAST, 0))
3097 +rib_score_proto_table (proto, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3098}
3099
paul718e3742002-12-13 20:15:29 +00003100/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00003101static void
paul718e3742002-12-13 20:15:29 +00003102rib_close_table (struct route_table *table)
3103{
3104 struct route_node *rn;
3105 struct rib *rib;
3106
3107 if (table)
3108 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003109 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00003110 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003111 if (!CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
3112 continue;
3113
Avneesh Sachdev5adc2522012-11-13 22:48:59 +00003114 zfpm_trigger_update (rn, NULL);
3115
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003116 if (! RIB_SYSTEM_ROUTE (rib))
3117 rib_uninstall_kernel (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00003118 }
paul718e3742002-12-13 20:15:29 +00003119}
3120
3121/* Close all RIB tables. */
3122void
paula1ac18c2005-06-28 17:17:12 +00003123rib_close (void)
paul718e3742002-12-13 20:15:29 +00003124{
3125 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3126 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3127}
3128
3129/* Routing information base initialize. */
3130void
paula1ac18c2005-06-28 17:17:12 +00003131rib_init (void)
paul718e3742002-12-13 20:15:29 +00003132{
paul4d38fdb2005-04-28 17:35:14 +00003133 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00003134 /* VRF initialization. */
3135 vrf_init ();
3136}
Avneesh Sachdev0915bb02012-11-13 22:48:55 +00003137
3138/*
3139 * vrf_id_get_next
3140 *
3141 * Get the first vrf id that is greater than the given vrf id if any.
3142 *
3143 * Returns TRUE if a vrf id was found, FALSE otherwise.
3144 */
3145static inline int
3146vrf_id_get_next (uint32_t id, uint32_t *next_id_p)
3147{
3148 while (++id < vector_active (vrf_vector))
3149 {
3150 if (vrf_lookup (id))
3151 {
3152 *next_id_p = id;
3153 return 1;
3154 }
3155 }
3156
3157 return 0;
3158}
3159
3160/*
3161 * rib_tables_iter_next
3162 *
3163 * Returns the next table in the iteration.
3164 */
3165struct route_table *
3166rib_tables_iter_next (rib_tables_iter_t *iter)
3167{
3168 struct route_table *table;
3169
3170 /*
3171 * Array that helps us go over all AFI/SAFI combinations via one
3172 * index.
3173 */
3174 static struct {
3175 afi_t afi;
3176 safi_t safi;
3177 } afi_safis[] = {
3178 { AFI_IP, SAFI_UNICAST },
3179 { AFI_IP, SAFI_MULTICAST },
3180 { AFI_IP6, SAFI_UNICAST },
3181 { AFI_IP6, SAFI_MULTICAST },
3182 };
3183
3184 table = NULL;
3185
3186 switch (iter->state)
3187 {
3188
3189 case RIB_TABLES_ITER_S_INIT:
3190 iter->vrf_id = 0;
3191 iter->afi_safi_ix = -1;
3192
3193 /* Fall through */
3194
3195 case RIB_TABLES_ITER_S_ITERATING:
3196 iter->afi_safi_ix++;
3197 while (1)
3198 {
3199
3200 while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
3201 {
3202 table = vrf_table (afi_safis[iter->afi_safi_ix].afi,
3203 afi_safis[iter->afi_safi_ix].safi,
3204 iter->vrf_id);
3205 if (table)
3206 break;
3207
3208 iter->afi_safi_ix++;
3209 }
3210
3211 /*
3212 * Found another table in this vrf.
3213 */
3214 if (table)
3215 break;
3216
3217 /*
3218 * Done with all tables in the current vrf, go to the next
3219 * one.
3220 */
3221 if (!vrf_id_get_next (iter->vrf_id, &iter->vrf_id))
3222 break;
3223
3224 iter->afi_safi_ix = 0;
3225 }
3226
3227 break;
3228
3229 case RIB_TABLES_ITER_S_DONE:
3230 return NULL;
3231 }
3232
3233 if (table)
3234 iter->state = RIB_TABLES_ITER_S_ITERATING;
3235 else
3236 iter->state = RIB_TABLES_ITER_S_DONE;
3237
3238 return table;
3239}