blob: f0d5c9d9318ba6fac588ac23380bf570a9b96172 [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"
43
44/* Default rtm_table for all clients */
paulb21b19c2003-06-15 01:28:29 +000045extern struct zebra_t zebrad;
paul718e3742002-12-13 20:15:29 +000046
Paul Jakma457eb9a2006-07-27 19:59:58 +000047/* Hold time for RIB process, should be very minimal.
48 * it is useful to able to set it otherwise for testing, hence exported
49 * as global here for test-rig code.
50 */
51int rib_process_hold_time = 10;
52
paul718e3742002-12-13 20:15:29 +000053/* Each route type's string and default distance value. */
Stephen Hemmingerd145bc02008-08-17 17:41:37 +010054static const struct
paul718e3742002-12-13 20:15:29 +000055{
56 int key;
57 int distance;
Paul Jakma57345092011-12-25 17:52:09 +010058} route_info[ZEBRA_ROUTE_MAX] =
paul718e3742002-12-13 20:15:29 +000059{
Paul Jakma57345092011-12-25 17:52:09 +010060 [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0},
61 [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0},
62 [ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0},
63 [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1},
64 [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120},
65 [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120},
66 [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110},
67 [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110},
68 [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115},
69 [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */},
70 [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 95},
David Lamparter7052f222009-08-27 00:28:28 +020071 /* no entry/default: 150 */
paul718e3742002-12-13 20:15:29 +000072};
73
74/* Vector for routing table. */
Stephen Hemmingerd145bc02008-08-17 17:41:37 +010075static vector vrf_vector;
paul718e3742002-12-13 20:15:29 +000076
77/* Allocate new VRF. */
paula1ac18c2005-06-28 17:17:12 +000078static struct vrf *
hassofce954f2004-10-07 20:29:24 +000079vrf_alloc (const char *name)
paul718e3742002-12-13 20:15:29 +000080{
81 struct vrf *vrf;
82
83 vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
84
85 /* Put name. */
86 if (name)
87 vrf->name = XSTRDUP (MTYPE_VRF_NAME, name);
88
89 /* Allocate routing table and static table. */
90 vrf->table[AFI_IP][SAFI_UNICAST] = route_table_init ();
91 vrf->table[AFI_IP6][SAFI_UNICAST] = route_table_init ();
92 vrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
93 vrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
G.Balajicddf3912011-11-26 21:59:32 +040094 vrf->table[AFI_IP][SAFI_MULTICAST] = route_table_init ();
95 vrf->table[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
96 vrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
97 vrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
98
paul718e3742002-12-13 20:15:29 +000099
100 return vrf;
101}
102
paul718e3742002-12-13 20:15:29 +0000103/* Lookup VRF by identifier. */
104struct vrf *
105vrf_lookup (u_int32_t id)
106{
107 return vector_lookup (vrf_vector, id);
108}
109
paul718e3742002-12-13 20:15:29 +0000110/* Initialize VRF. */
paula1ac18c2005-06-28 17:17:12 +0000111static void
112vrf_init (void)
paul718e3742002-12-13 20:15:29 +0000113{
114 struct vrf *default_table;
115
116 /* Allocate VRF vector. */
117 vrf_vector = vector_init (1);
118
119 /* Allocate default main table. */
120 default_table = vrf_alloc ("Default-IP-Routing-Table");
121
122 /* Default table index must be 0. */
123 vector_set_index (vrf_vector, 0, default_table);
124}
125
126/* Lookup route table. */
127struct route_table *
128vrf_table (afi_t afi, safi_t safi, u_int32_t id)
129{
130 struct vrf *vrf;
131
132 vrf = vrf_lookup (id);
133 if (! vrf)
134 return NULL;
135
136 return vrf->table[afi][safi];
137}
138
139/* Lookup static route table. */
140struct route_table *
141vrf_static_table (afi_t afi, safi_t safi, u_int32_t id)
142{
143 struct vrf *vrf;
144
145 vrf = vrf_lookup (id);
146 if (! vrf)
147 return NULL;
148
149 return vrf->stable[afi][safi];
150}
151
152/* Add nexthop to the end of the list. */
paula1ac18c2005-06-28 17:17:12 +0000153static void
paul718e3742002-12-13 20:15:29 +0000154nexthop_add (struct rib *rib, struct nexthop *nexthop)
155{
156 struct nexthop *last;
157
158 for (last = rib->nexthop; last && last->next; last = last->next)
159 ;
160 if (last)
161 last->next = nexthop;
162 else
163 rib->nexthop = nexthop;
164 nexthop->prev = last;
165
166 rib->nexthop_num++;
167}
168
169/* Delete specified nexthop from the list. */
paula1ac18c2005-06-28 17:17:12 +0000170static void
paul718e3742002-12-13 20:15:29 +0000171nexthop_delete (struct rib *rib, struct nexthop *nexthop)
172{
173 if (nexthop->next)
174 nexthop->next->prev = nexthop->prev;
175 if (nexthop->prev)
176 nexthop->prev->next = nexthop->next;
177 else
178 rib->nexthop = nexthop->next;
179 rib->nexthop_num--;
180}
181
182/* Free nexthop. */
paula1ac18c2005-06-28 17:17:12 +0000183static void
paul718e3742002-12-13 20:15:29 +0000184nexthop_free (struct nexthop *nexthop)
185{
paula4b70762003-05-16 17:19:48 +0000186 if (nexthop->ifname)
187 XFREE (0, nexthop->ifname);
paul718e3742002-12-13 20:15:29 +0000188 XFREE (MTYPE_NEXTHOP, nexthop);
189}
190
191struct nexthop *
192nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
193{
194 struct nexthop *nexthop;
195
Stephen Hemminger393deb92008-08-18 14:13:29 -0700196 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000197 nexthop->type = NEXTHOP_TYPE_IFINDEX;
198 nexthop->ifindex = ifindex;
199
200 nexthop_add (rib, nexthop);
201
202 return nexthop;
203}
204
205struct nexthop *
206nexthop_ifname_add (struct rib *rib, char *ifname)
207{
208 struct nexthop *nexthop;
209
Stephen Hemminger393deb92008-08-18 14:13:29 -0700210 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000211 nexthop->type = NEXTHOP_TYPE_IFNAME;
paula4b70762003-05-16 17:19:48 +0000212 nexthop->ifname = XSTRDUP (0, ifname);
paul718e3742002-12-13 20:15:29 +0000213
214 nexthop_add (rib, nexthop);
215
216 return nexthop;
217}
218
219struct nexthop *
Paul Jakma7514fb72007-05-02 16:05:35 +0000220nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src)
paul718e3742002-12-13 20:15:29 +0000221{
222 struct nexthop *nexthop;
223
Stephen Hemminger393deb92008-08-18 14:13:29 -0700224 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000225 nexthop->type = NEXTHOP_TYPE_IPV4;
226 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000227 if (src)
228 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000229
230 nexthop_add (rib, nexthop);
231
232 return nexthop;
233}
234
Josh Bailey26e2ae32012-03-22 01:09:21 -0700235struct nexthop *
paul718e3742002-12-13 20:15:29 +0000236nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
Paul Jakma7514fb72007-05-02 16:05:35 +0000237 struct in_addr *src, unsigned int ifindex)
paul718e3742002-12-13 20:15:29 +0000238{
239 struct nexthop *nexthop;
240
Stephen Hemminger393deb92008-08-18 14:13:29 -0700241 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000242 nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
243 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000244 if (src)
245 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000246 nexthop->ifindex = ifindex;
247
248 nexthop_add (rib, nexthop);
249
250 return nexthop;
251}
252
253#ifdef HAVE_IPV6
254struct nexthop *
255nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
256{
257 struct nexthop *nexthop;
258
Stephen Hemminger393deb92008-08-18 14:13:29 -0700259 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000260 nexthop->type = NEXTHOP_TYPE_IPV6;
261 nexthop->gate.ipv6 = *ipv6;
262
263 nexthop_add (rib, nexthop);
264
265 return nexthop;
266}
267
paula1ac18c2005-06-28 17:17:12 +0000268static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000269nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
270 char *ifname)
271{
272 struct nexthop *nexthop;
273
Stephen Hemminger393deb92008-08-18 14:13:29 -0700274 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000275 nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
276 nexthop->gate.ipv6 = *ipv6;
277 nexthop->ifname = XSTRDUP (0, ifname);
278
279 nexthop_add (rib, nexthop);
280
281 return nexthop;
282}
283
paula1ac18c2005-06-28 17:17:12 +0000284static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000285nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
286 unsigned int ifindex)
287{
288 struct nexthop *nexthop;
289
Stephen Hemminger393deb92008-08-18 14:13:29 -0700290 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000291 nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
292 nexthop->gate.ipv6 = *ipv6;
293 nexthop->ifindex = ifindex;
294
295 nexthop_add (rib, nexthop);
296
297 return nexthop;
298}
299#endif /* HAVE_IPV6 */
300
paul595db7f2003-05-25 21:35:06 +0000301struct nexthop *
302nexthop_blackhole_add (struct rib *rib)
303{
304 struct nexthop *nexthop;
305
Stephen Hemminger393deb92008-08-18 14:13:29 -0700306 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul595db7f2003-05-25 21:35:06 +0000307 nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
308 SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
309
310 nexthop_add (rib, nexthop);
311
312 return nexthop;
313}
314
paul718e3742002-12-13 20:15:29 +0000315/* If force flag is not set, do not modify falgs at all for uninstall
316 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000317static int
paul718e3742002-12-13 20:15:29 +0000318nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
319 struct route_node *top)
320{
321 struct prefix_ipv4 p;
322 struct route_table *table;
323 struct route_node *rn;
324 struct rib *match;
325 struct nexthop *newhop;
326
327 if (nexthop->type == NEXTHOP_TYPE_IPV4)
328 nexthop->ifindex = 0;
329
330 if (set)
331 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
332
333 /* Make lookup prefix. */
334 memset (&p, 0, sizeof (struct prefix_ipv4));
335 p.family = AF_INET;
336 p.prefixlen = IPV4_MAX_PREFIXLEN;
337 p.prefix = nexthop->gate.ipv4;
338
339 /* Lookup table. */
340 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
341 if (! table)
342 return 0;
343
344 rn = route_node_match (table, (struct prefix *) &p);
345 while (rn)
346 {
347 route_unlock_node (rn);
348
David Warda50c1072009-12-03 15:34:39 +0300349 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000350 if (rn == top)
351 return 0;
352
353 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000354 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100355 {
356 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
357 continue;
358 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
359 break;
360 }
paul718e3742002-12-13 20:15:29 +0000361
362 /* If there is no selected route or matched route is EGP, go up
363 tree. */
364 if (! match
365 || match->type == ZEBRA_ROUTE_BGP)
366 {
367 do {
368 rn = rn->parent;
369 } while (rn && rn->info == NULL);
370 if (rn)
371 route_lock_node (rn);
372 }
373 else
374 {
375 if (match->type == ZEBRA_ROUTE_CONNECT)
376 {
377 /* Directly point connected route. */
378 newhop = match->nexthop;
379 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
380 nexthop->ifindex = newhop->ifindex;
381
382 return 1;
383 }
384 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
385 {
386 for (newhop = match->nexthop; newhop; newhop = newhop->next)
387 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
388 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
389 {
390 if (set)
391 {
392 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
393 nexthop->rtype = newhop->type;
394 if (newhop->type == NEXTHOP_TYPE_IPV4 ||
395 newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
396 nexthop->rgate.ipv4 = newhop->gate.ipv4;
397 if (newhop->type == NEXTHOP_TYPE_IFINDEX
398 || newhop->type == NEXTHOP_TYPE_IFNAME
399 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
400 nexthop->rifindex = newhop->ifindex;
401 }
402 return 1;
403 }
404 return 0;
405 }
406 else
407 {
408 return 0;
409 }
410 }
411 }
412 return 0;
413}
414
415#ifdef HAVE_IPV6
416/* If force flag is not set, do not modify falgs at all for uninstall
417 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000418static int
paul718e3742002-12-13 20:15:29 +0000419nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
420 struct route_node *top)
421{
422 struct prefix_ipv6 p;
423 struct route_table *table;
424 struct route_node *rn;
425 struct rib *match;
426 struct nexthop *newhop;
427
428 if (nexthop->type == NEXTHOP_TYPE_IPV6)
429 nexthop->ifindex = 0;
430
431 if (set)
432 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
433
434 /* Make lookup prefix. */
435 memset (&p, 0, sizeof (struct prefix_ipv6));
436 p.family = AF_INET6;
437 p.prefixlen = IPV6_MAX_PREFIXLEN;
438 p.prefix = nexthop->gate.ipv6;
439
440 /* Lookup table. */
441 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
442 if (! table)
443 return 0;
444
445 rn = route_node_match (table, (struct prefix *) &p);
446 while (rn)
447 {
448 route_unlock_node (rn);
449
David Warda50c1072009-12-03 15:34:39 +0300450 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000451 if (rn == top)
452 return 0;
453
454 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000455 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100456 {
457 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
458 continue;
459 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
460 break;
461 }
paul718e3742002-12-13 20:15:29 +0000462
463 /* If there is no selected route or matched route is EGP, go up
464 tree. */
465 if (! match
466 || match->type == ZEBRA_ROUTE_BGP)
467 {
468 do {
469 rn = rn->parent;
470 } while (rn && rn->info == NULL);
471 if (rn)
472 route_lock_node (rn);
473 }
474 else
475 {
476 if (match->type == ZEBRA_ROUTE_CONNECT)
477 {
478 /* Directly point connected route. */
479 newhop = match->nexthop;
480
481 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
482 nexthop->ifindex = newhop->ifindex;
483
484 return 1;
485 }
486 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
487 {
488 for (newhop = match->nexthop; newhop; newhop = newhop->next)
489 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
490 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
491 {
492 if (set)
493 {
494 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
495 nexthop->rtype = newhop->type;
496 if (newhop->type == NEXTHOP_TYPE_IPV6
497 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
498 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
499 nexthop->rgate.ipv6 = newhop->gate.ipv6;
500 if (newhop->type == NEXTHOP_TYPE_IFINDEX
501 || newhop->type == NEXTHOP_TYPE_IFNAME
502 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
503 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
504 nexthop->rifindex = newhop->ifindex;
505 }
506 return 1;
507 }
508 return 0;
509 }
510 else
511 {
512 return 0;
513 }
514 }
515 }
516 return 0;
517}
518#endif /* HAVE_IPV6 */
519
520struct rib *
521rib_match_ipv4 (struct in_addr addr)
522{
523 struct prefix_ipv4 p;
524 struct route_table *table;
525 struct route_node *rn;
526 struct rib *match;
527 struct nexthop *newhop;
528
529 /* Lookup table. */
530 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
531 if (! table)
532 return 0;
533
534 memset (&p, 0, sizeof (struct prefix_ipv4));
535 p.family = AF_INET;
536 p.prefixlen = IPV4_MAX_PREFIXLEN;
537 p.prefix = addr;
538
539 rn = route_node_match (table, (struct prefix *) &p);
540
541 while (rn)
542 {
543 route_unlock_node (rn);
544
545 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000546 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100547 {
548 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
549 continue;
550 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
551 break;
552 }
paul718e3742002-12-13 20:15:29 +0000553
554 /* If there is no selected route or matched route is EGP, go up
555 tree. */
556 if (! match
557 || match->type == ZEBRA_ROUTE_BGP)
558 {
559 do {
560 rn = rn->parent;
561 } while (rn && rn->info == NULL);
562 if (rn)
563 route_lock_node (rn);
564 }
565 else
566 {
567 if (match->type == ZEBRA_ROUTE_CONNECT)
568 /* Directly point connected route. */
569 return match;
570 else
571 {
572 for (newhop = match->nexthop; newhop; newhop = newhop->next)
573 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
574 return match;
575 return NULL;
576 }
577 }
578 }
579 return NULL;
580}
581
582struct rib *
583rib_lookup_ipv4 (struct prefix_ipv4 *p)
584{
585 struct route_table *table;
586 struct route_node *rn;
587 struct rib *match;
588 struct nexthop *nexthop;
589
590 /* Lookup table. */
591 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
592 if (! table)
593 return 0;
594
595 rn = route_node_lookup (table, (struct prefix *) p);
596
597 /* No route for this prefix. */
598 if (! rn)
599 return NULL;
600
601 /* Unlock node. */
602 route_unlock_node (rn);
603
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000604 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100605 {
606 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
607 continue;
608 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
609 break;
610 }
paul718e3742002-12-13 20:15:29 +0000611
612 if (! match || match->type == ZEBRA_ROUTE_BGP)
613 return NULL;
614
615 if (match->type == ZEBRA_ROUTE_CONNECT)
616 return match;
617
618 for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
619 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
620 return match;
621
622 return NULL;
623}
624
Denis Ovsienkodc958242007-08-13 16:03:06 +0000625/*
626 * This clone function, unlike its original rib_lookup_ipv4(), checks
627 * if specified IPv4 route record (prefix/mask -> gate) exists in
628 * the whole RIB and has ZEBRA_FLAG_SELECTED set.
629 *
630 * Return values:
631 * -1: error
632 * 0: exact match found
633 * 1: a match was found with a different gate
634 * 2: connected route found
635 * 3: no matches found
636 */
637int
638rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
639{
640 struct route_table *table;
641 struct route_node *rn;
642 struct rib *match;
643 struct nexthop *nexthop;
644
645 /* Lookup table. */
646 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
647 if (! table)
648 return ZEBRA_RIB_LOOKUP_ERROR;
649
650 /* Scan the RIB table for exactly matching RIB entry. */
651 rn = route_node_lookup (table, (struct prefix *) p);
652
653 /* No route for this prefix. */
654 if (! rn)
655 return ZEBRA_RIB_NOTFOUND;
656
657 /* Unlock node. */
658 route_unlock_node (rn);
659
660 /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000661 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100662 {
663 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
664 continue;
665 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
666 break;
667 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000668
669 /* None such found :( */
670 if (!match)
671 return ZEBRA_RIB_NOTFOUND;
672
673 if (match->type == ZEBRA_ROUTE_CONNECT)
674 return ZEBRA_RIB_FOUND_CONNECTED;
675
676 /* Ok, we have a cood candidate, let's check it's nexthop list... */
677 for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
678 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
679 {
680 /* We are happy with either direct or recursive hexthop */
Jorge Boncompte [DTI2]12829322012-04-10 16:57:25 +0200681 if (nexthop->gate.ipv4.s_addr == sockunion2ip (qgate) ||
682 nexthop->rgate.ipv4.s_addr == sockunion2ip (qgate))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000683 return ZEBRA_RIB_FOUND_EXACT;
684 else
685 {
686 if (IS_ZEBRA_DEBUG_RIB)
687 {
688 char gate_buf[INET_ADDRSTRLEN], rgate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
689 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
690 inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, rgate_buf, INET_ADDRSTRLEN);
Jorge Boncompte [DTI2]12829322012-04-10 16:57:25 +0200691 inet_ntop (AF_INET, &sockunion2ip (qgate), qgate_buf, INET_ADDRSTRLEN);
Denis Ovsienkodc958242007-08-13 16:03:06 +0000692 zlog_debug ("%s: qgate == %s, gate == %s, rgate == %s", __func__, qgate_buf, gate_buf, rgate_buf);
693 }
694 return ZEBRA_RIB_FOUND_NOGATE;
695 }
696 }
697
698 return ZEBRA_RIB_NOTFOUND;
699}
700
paul718e3742002-12-13 20:15:29 +0000701#ifdef HAVE_IPV6
702struct rib *
703rib_match_ipv6 (struct in6_addr *addr)
704{
705 struct prefix_ipv6 p;
706 struct route_table *table;
707 struct route_node *rn;
708 struct rib *match;
709 struct nexthop *newhop;
710
711 /* Lookup table. */
712 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
713 if (! table)
714 return 0;
715
716 memset (&p, 0, sizeof (struct prefix_ipv6));
717 p.family = AF_INET6;
718 p.prefixlen = IPV6_MAX_PREFIXLEN;
719 IPV6_ADDR_COPY (&p.prefix, addr);
720
721 rn = route_node_match (table, (struct prefix *) &p);
722
723 while (rn)
724 {
725 route_unlock_node (rn);
726
727 /* Pick up selected route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000728 RNODE_FOREACH_RIB (rn, match)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100729 {
730 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
731 continue;
732 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
733 break;
734 }
paul718e3742002-12-13 20:15:29 +0000735
736 /* If there is no selected route or matched route is EGP, go up
737 tree. */
738 if (! match
739 || match->type == ZEBRA_ROUTE_BGP)
740 {
741 do {
742 rn = rn->parent;
743 } while (rn && rn->info == NULL);
744 if (rn)
745 route_lock_node (rn);
746 }
747 else
748 {
749 if (match->type == ZEBRA_ROUTE_CONNECT)
750 /* Directly point connected route. */
751 return match;
752 else
753 {
754 for (newhop = match->nexthop; newhop; newhop = newhop->next)
755 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
756 return match;
757 return NULL;
758 }
759 }
760 }
761 return NULL;
762}
763#endif /* HAVE_IPV6 */
764
Paul Jakma7514fb72007-05-02 16:05:35 +0000765#define RIB_SYSTEM_ROUTE(R) \
766 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
767
Denis Ovsienkodc958242007-08-13 16:03:06 +0000768/* This function verifies reachability of one given nexthop, which can be
769 * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
770 * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
771 * nexthop->ifindex will be updated appropriately as well.
772 * An existing route map can turn (otherwise active) nexthop into inactive, but
773 * not vice versa.
774 *
775 * The return value is the final value of 'ACTIVE' flag.
776 */
777
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300778static unsigned
paul718e3742002-12-13 20:15:29 +0000779nexthop_active_check (struct route_node *rn, struct rib *rib,
780 struct nexthop *nexthop, int set)
781{
782 struct interface *ifp;
Paul Jakma7514fb72007-05-02 16:05:35 +0000783 route_map_result_t ret = RMAP_MATCH;
784 extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
785 struct route_map *rmap;
786 int family;
paul718e3742002-12-13 20:15:29 +0000787
Paul Jakma7514fb72007-05-02 16:05:35 +0000788 family = 0;
paul718e3742002-12-13 20:15:29 +0000789 switch (nexthop->type)
790 {
791 case NEXTHOP_TYPE_IFINDEX:
792 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000793 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000794 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
795 else
796 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
797 break;
paul718e3742002-12-13 20:15:29 +0000798 case NEXTHOP_TYPE_IPV6_IFNAME:
Paul Jakma7514fb72007-05-02 16:05:35 +0000799 family = AFI_IP6;
800 case NEXTHOP_TYPE_IFNAME:
paul718e3742002-12-13 20:15:29 +0000801 ifp = if_lookup_by_name (nexthop->ifname);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000802 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000803 {
804 if (set)
805 nexthop->ifindex = ifp->ifindex;
806 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
807 }
808 else
809 {
810 if (set)
811 nexthop->ifindex = 0;
812 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
813 }
814 break;
815 case NEXTHOP_TYPE_IPV4:
816 case NEXTHOP_TYPE_IPV4_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000817 family = AFI_IP;
paul718e3742002-12-13 20:15:29 +0000818 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
819 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
820 else
821 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
822 break;
823#ifdef HAVE_IPV6
824 case NEXTHOP_TYPE_IPV6:
Paul Jakma7514fb72007-05-02 16:05:35 +0000825 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000826 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
827 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
828 else
829 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
830 break;
831 case NEXTHOP_TYPE_IPV6_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000832 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000833 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
834 {
835 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000836 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000837 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
838 else
839 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
840 }
841 else
842 {
843 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
844 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
845 else
846 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
847 }
848 break;
849#endif /* HAVE_IPV6 */
paul595db7f2003-05-25 21:35:06 +0000850 case NEXTHOP_TYPE_BLACKHOLE:
851 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
852 break;
paul718e3742002-12-13 20:15:29 +0000853 default:
854 break;
855 }
Paul Jakma7514fb72007-05-02 16:05:35 +0000856 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
857 return 0;
858
859 if (RIB_SYSTEM_ROUTE(rib) ||
860 (family == AFI_IP && rn->p.family != AF_INET) ||
861 (family == AFI_IP6 && rn->p.family != AF_INET6))
862 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
863
864 rmap = 0;
865 if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
866 proto_rm[family][rib->type])
867 rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
868 if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
869 rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
870 if (rmap) {
871 ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, nexthop);
872 }
873
874 if (ret == RMAP_DENYMATCH)
875 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
paul718e3742002-12-13 20:15:29 +0000876 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
877}
878
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000879/* Iterate over all nexthops of the given RIB entry and refresh their
880 * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
881 * nexthop is found to toggle the ACTIVE flag, the whole rib structure
882 * is flagged with ZEBRA_FLAG_CHANGED. The 4th 'set' argument is
883 * transparently passed to nexthop_active_check().
884 *
885 * Return value is the new number of active nexthops.
886 */
887
paula1ac18c2005-06-28 17:17:12 +0000888static int
paul718e3742002-12-13 20:15:29 +0000889nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
890{
891 struct nexthop *nexthop;
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300892 unsigned int prev_active, prev_index, new_active;
paul718e3742002-12-13 20:15:29 +0000893
894 rib->nexthop_active_num = 0;
895 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
896
897 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000898 {
899 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
Joakim Tjernlundc3a56062009-06-24 19:15:36 +0200900 prev_index = nexthop->ifindex;
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000901 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
902 rib->nexthop_active_num++;
Joakim Tjernlundc3a56062009-06-24 19:15:36 +0200903 if (prev_active != new_active ||
904 prev_index != nexthop->ifindex)
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000905 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
906 }
paul718e3742002-12-13 20:15:29 +0000907 return rib->nexthop_active_num;
908}
paul6baeb982003-10-28 03:47:15 +0000909
paul718e3742002-12-13 20:15:29 +0000910
paul718e3742002-12-13 20:15:29 +0000911
paula1ac18c2005-06-28 17:17:12 +0000912static void
paul718e3742002-12-13 20:15:29 +0000913rib_install_kernel (struct route_node *rn, struct rib *rib)
914{
915 int ret = 0;
916 struct nexthop *nexthop;
917
918 switch (PREFIX_FAMILY (&rn->p))
919 {
920 case AF_INET:
921 ret = kernel_add_ipv4 (&rn->p, rib);
922 break;
923#ifdef HAVE_IPV6
924 case AF_INET6:
925 ret = kernel_add_ipv6 (&rn->p, rib);
926 break;
927#endif /* HAVE_IPV6 */
928 }
929
Denis Ovsienkodc958242007-08-13 16:03:06 +0000930 /* This condition is never met, if we are using rt_socket.c */
paul718e3742002-12-13 20:15:29 +0000931 if (ret < 0)
932 {
933 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
934 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
935 }
936}
937
938/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +0000939static int
paul718e3742002-12-13 20:15:29 +0000940rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
941{
942 int ret = 0;
943 struct nexthop *nexthop;
944
945 switch (PREFIX_FAMILY (&rn->p))
946 {
947 case AF_INET:
948 ret = kernel_delete_ipv4 (&rn->p, rib);
949 break;
950#ifdef HAVE_IPV6
951 case AF_INET6:
952 ret = kernel_delete_ipv6 (&rn->p, rib);
953 break;
954#endif /* HAVE_IPV6 */
955 }
956
957 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
958 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
959
960 return ret;
961}
962
963/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +0000964static void
paul718e3742002-12-13 20:15:29 +0000965rib_uninstall (struct route_node *rn, struct rib *rib)
966{
967 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
968 {
969 redistribute_delete (&rn->p, rib);
970 if (! RIB_SYSTEM_ROUTE (rib))
971 rib_uninstall_kernel (rn, rib);
972 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
973 }
974}
975
Paul Jakma6d691122006-07-27 21:49:00 +0000976static void rib_unlink (struct route_node *, struct rib *);
977
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000978/*
979 * rib_can_delete_dest
980 *
981 * Returns TRUE if the given dest can be deleted from the table.
982 */
983static int
984rib_can_delete_dest (rib_dest_t *dest)
985{
986 if (dest->routes)
987 {
988 return 0;
989 }
990
991 return 1;
992}
993
994/*
995 * rib_gc_dest
996 *
997 * Garbage collect the rib dest corresponding to the given route node
998 * if appropriate.
999 *
1000 * Returns TRUE if the dest was deleted, FALSE otherwise.
1001 */
1002int
1003rib_gc_dest (struct route_node *rn)
1004{
1005 rib_dest_t *dest;
1006 char buf[INET6_ADDRSTRLEN];
1007
1008 dest = rib_dest_from_rnode (rn);
1009 if (!dest)
1010 return 0;
1011
1012 if (!rib_can_delete_dest (dest))
1013 return 0;
1014
1015 if (IS_ZEBRA_DEBUG_RIB)
1016 {
1017 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, sizeof (buf));
1018 zlog_debug ("%s: %s/%d: removing dest from table", __func__,
1019 buf, rn->p.prefixlen);
1020 }
1021
1022 dest->rnode = NULL;
1023 XFREE (MTYPE_RIB_DEST, dest);
1024 rn->info = NULL;
1025
1026 /*
1027 * Release the one reference that we keep on the route node.
1028 */
1029 route_unlock_node (rn);
1030 return 1;
1031}
1032
paul718e3742002-12-13 20:15:29 +00001033/* Core function for processing routing information base. */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001034static void
1035rib_process (struct route_node *rn)
paul718e3742002-12-13 20:15:29 +00001036{
1037 struct rib *rib;
1038 struct rib *next;
1039 struct rib *fib = NULL;
1040 struct rib *select = NULL;
Paul Jakma6d691122006-07-27 21:49:00 +00001041 struct rib *del = NULL;
pauld753e9e2003-01-22 19:45:50 +00001042 int installed = 0;
1043 struct nexthop *nexthop = NULL;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001044 char buf[INET6_ADDRSTRLEN];
paul4d38fdb2005-04-28 17:35:14 +00001045
1046 assert (rn);
1047
Paul Jakma93bdada2007-08-06 19:25:11 +00001048 if (IS_ZEBRA_DEBUG_RIB || IS_ZEBRA_DEBUG_RIB_Q)
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001049 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001050
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001051 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00001052 {
paul718e3742002-12-13 20:15:29 +00001053 /* Currently installed rib. */
1054 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Paul Jakma6d691122006-07-27 21:49:00 +00001055 {
1056 assert (fib == NULL);
1057 fib = rib;
1058 }
1059
1060 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1061 * which we need to do do further work with below.
1062 */
1063 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1064 {
1065 if (rib != fib)
1066 {
1067 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001068 zlog_debug ("%s: %s/%d: rn %p, removing rib %p", __func__,
1069 buf, rn->p.prefixlen, rn, rib);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001070 rib_unlink (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001071 }
1072 else
1073 del = rib;
1074
1075 continue;
1076 }
paul4d38fdb2005-04-28 17:35:14 +00001077
paul718e3742002-12-13 20:15:29 +00001078 /* Skip unreachable nexthop. */
1079 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +00001080 continue;
paul718e3742002-12-13 20:15:29 +00001081
1082 /* Infinit distance. */
1083 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +00001084 continue;
paul718e3742002-12-13 20:15:29 +00001085
paulaf887b52006-01-18 14:52:52 +00001086 /* Newly selected rib, the common case. */
1087 if (!select)
1088 {
1089 select = rib;
1090 continue;
1091 }
1092
1093 /* filter route selection in following order:
paulaf887b52006-01-18 14:52:52 +00001094 * - connected beats other types
paula8d9c1f2006-01-25 06:31:04 +00001095 * - lower distance beats higher
paulaf887b52006-01-18 14:52:52 +00001096 * - lower metric beats higher for equal distance
1097 * - last, hence oldest, route wins tie break.
1098 */
paula1038a12006-01-30 14:08:51 +00001099
1100 /* Connected routes. Pick the last connected
1101 * route of the set of lowest metric connected routes.
1102 */
paula8d9c1f2006-01-25 06:31:04 +00001103 if (rib->type == ZEBRA_ROUTE_CONNECT)
1104 {
paula1038a12006-01-30 14:08:51 +00001105 if (select->type != ZEBRA_ROUTE_CONNECT
paula8d9c1f2006-01-25 06:31:04 +00001106 || rib->metric <= select->metric)
paula1038a12006-01-30 14:08:51 +00001107 select = rib;
1108 continue;
paula8d9c1f2006-01-25 06:31:04 +00001109 }
1110 else if (select->type == ZEBRA_ROUTE_CONNECT)
1111 continue;
1112
1113 /* higher distance loses */
1114 if (rib->distance > select->distance)
1115 continue;
1116
1117 /* lower wins */
1118 if (rib->distance < select->distance)
1119 {
paulaf887b52006-01-18 14:52:52 +00001120 select = rib;
paula8d9c1f2006-01-25 06:31:04 +00001121 continue;
1122 }
1123
1124 /* metric tie-breaks equal distance */
1125 if (rib->metric <= select->metric)
1126 select = rib;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001127 } /* RNODE_FOREACH_RIB_SAFE */
Denis Ovsienkodc958242007-08-13 16:03:06 +00001128
1129 /* After the cycle is finished, the following pointers will be set:
1130 * select --- the winner RIB entry, if any was found, otherwise NULL
1131 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1132 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1133 * rib --- NULL
1134 */
1135
1136 /* Same RIB entry is selected. Update FIB and finish. */
paul718e3742002-12-13 20:15:29 +00001137 if (select && select == fib)
1138 {
Paul Jakma6d691122006-07-27 21:49:00 +00001139 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001140 zlog_debug ("%s: %s/%d: Updating existing route, select %p, fib %p",
1141 __func__, buf, rn->p.prefixlen, select, fib);
paul718e3742002-12-13 20:15:29 +00001142 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +00001143 {
1144 redistribute_delete (&rn->p, select);
1145 if (! RIB_SYSTEM_ROUTE (select))
1146 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001147
paul4d38fdb2005-04-28 17:35:14 +00001148 /* Set real nexthop. */
1149 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +00001150
paul4d38fdb2005-04-28 17:35:14 +00001151 if (! RIB_SYSTEM_ROUTE (select))
1152 rib_install_kernel (rn, select);
1153 redistribute_add (&rn->p, select);
1154 }
pauld753e9e2003-01-22 19:45:50 +00001155 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001156 {
1157 /* Housekeeping code to deal with
1158 race conditions in kernel with linux
1159 netlink reporting interface up before IPv4 or IPv6 protocol
1160 is ready to add routes.
1161 This makes sure the routes are IN the kernel.
1162 */
pauld753e9e2003-01-22 19:45:50 +00001163
paul4d38fdb2005-04-28 17:35:14 +00001164 for (nexthop = select->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001165 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
paul4d38fdb2005-04-28 17:35:14 +00001166 {
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001167 installed = 1;
1168 break;
paul4d38fdb2005-04-28 17:35:14 +00001169 }
1170 if (! installed)
1171 rib_install_kernel (rn, select);
1172 }
Paul Jakma6d691122006-07-27 21:49:00 +00001173 goto end;
paul718e3742002-12-13 20:15:29 +00001174 }
1175
Denis Ovsienkodc958242007-08-13 16:03:06 +00001176 /* At this point we either haven't found the best RIB entry or it is
1177 * different from what we currently intend to flag with SELECTED. In both
1178 * cases, if a RIB block is present in FIB, it should be withdrawn.
1179 */
paul718e3742002-12-13 20:15:29 +00001180 if (fib)
1181 {
Paul Jakma6d691122006-07-27 21:49:00 +00001182 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001183 zlog_debug ("%s: %s/%d: Removing existing route, fib %p", __func__,
1184 buf, rn->p.prefixlen, fib);
paul718e3742002-12-13 20:15:29 +00001185 redistribute_delete (&rn->p, fib);
1186 if (! RIB_SYSTEM_ROUTE (fib))
1187 rib_uninstall_kernel (rn, fib);
1188 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1189
1190 /* Set real nexthop. */
1191 nexthop_active_update (rn, fib, 1);
1192 }
1193
Denis Ovsienkodc958242007-08-13 16:03:06 +00001194 /* Regardless of some RIB entry being SELECTED or not before, now we can
1195 * tell, that if a new winner exists, FIB is still not updated with this
1196 * data, but ready to be.
1197 */
paul718e3742002-12-13 20:15:29 +00001198 if (select)
1199 {
Paul Jakma6d691122006-07-27 21:49:00 +00001200 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001201 zlog_debug ("%s: %s/%d: Adding route, select %p", __func__, buf,
1202 rn->p.prefixlen, select);
paul718e3742002-12-13 20:15:29 +00001203 /* Set real nexthop. */
1204 nexthop_active_update (rn, select, 1);
1205
1206 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001207 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001208 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1209 redistribute_add (&rn->p, select);
1210 }
paul4d38fdb2005-04-28 17:35:14 +00001211
Paul Jakma6d691122006-07-27 21:49:00 +00001212 /* FIB route was removed, should be deleted */
1213 if (del)
1214 {
1215 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001216 zlog_debug ("%s: %s/%d: Deleting fib %p, rn %p", __func__, buf,
1217 rn->p.prefixlen, del, rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001218 rib_unlink (rn, del);
1219 }
paul4d38fdb2005-04-28 17:35:14 +00001220
Paul Jakma6d691122006-07-27 21:49:00 +00001221end:
1222 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma93bdada2007-08-06 19:25:11 +00001223 zlog_debug ("%s: %s/%d: rn %p dequeued", __func__, buf, rn->p.prefixlen, rn);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001224
1225 /*
1226 * Check if the dest can be deleted now.
1227 */
1228 rib_gc_dest (rn);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001229}
1230
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001231/* Take a list of route_node structs and return 1, if there was a record
1232 * picked from it and processed by rib_process(). Don't process more,
1233 * than one RN record; operate only in the specified sub-queue.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001234 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001235static unsigned int
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001236process_subq (struct list * subq, u_char qindex)
1237{
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001238 struct listnode *lnode = listhead (subq);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001239 struct route_node *rnode;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001240
1241 if (!lnode)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001242 return 0;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001243
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001244 rnode = listgetdata (lnode);
1245 rib_process (rnode);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001246
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001247 if (rnode->info)
1248 UNSET_FLAG (rib_dest_from_rnode (rnode)->flags, RIB_ROUTE_QUEUED (qindex));
1249
Chris Caputo67b94672009-07-18 04:02:26 +00001250#if 0
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001251 else
1252 {
1253 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1254 __func__, rnode, rnode->lock);
1255 zlog_backtrace(LOG_DEBUG);
1256 }
Chris Caputo67b94672009-07-18 04:02:26 +00001257#endif
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001258 route_unlock_node (rnode);
1259 list_delete_node (subq, lnode);
1260 return 1;
1261}
1262
1263/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1264 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1265 * is pointed to the meta queue structure.
1266 */
1267static wq_item_status
1268meta_queue_process (struct work_queue *dummy, void *data)
1269{
1270 struct meta_queue * mq = data;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001271 unsigned i;
1272
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001273 for (i = 0; i < MQ_SIZE; i++)
1274 if (process_subq (mq->subq[i], i))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001275 {
1276 mq->size--;
1277 break;
1278 }
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001279 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1280}
1281
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001282/*
1283 * Map from rib types to queue type (priority) in meta queue
1284 */
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001285static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
1286 [ZEBRA_ROUTE_SYSTEM] = 4,
1287 [ZEBRA_ROUTE_KERNEL] = 0,
1288 [ZEBRA_ROUTE_CONNECT] = 0,
1289 [ZEBRA_ROUTE_STATIC] = 1,
1290 [ZEBRA_ROUTE_RIP] = 2,
1291 [ZEBRA_ROUTE_RIPNG] = 2,
1292 [ZEBRA_ROUTE_OSPF] = 2,
1293 [ZEBRA_ROUTE_OSPF6] = 2,
1294 [ZEBRA_ROUTE_ISIS] = 2,
1295 [ZEBRA_ROUTE_BGP] = 3,
1296 [ZEBRA_ROUTE_HSLS] = 4,
Paul Jakma57345092011-12-25 17:52:09 +01001297 [ZEBRA_ROUTE_BABEL] = 2,
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001298};
1299
1300/* Look into the RN and queue it into one or more priority queues,
1301 * increasing the size for each data push done.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001302 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001303static void
1304rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001305{
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001306 struct rib *rib;
1307 char buf[INET6_ADDRSTRLEN];
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001308
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001309 if (IS_ZEBRA_DEBUG_RIB_Q)
1310 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001311
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001312 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001313 {
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001314 u_char qindex = meta_queue_map[rib->type];
1315
1316 /* Invariant: at this point we always have rn->info set. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001317 if (CHECK_FLAG (rib_dest_from_rnode (rn)->flags,
1318 RIB_ROUTE_QUEUED (qindex)))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001319 {
1320 if (IS_ZEBRA_DEBUG_RIB_Q)
1321 zlog_debug ("%s: %s/%d: rn %p is already queued in sub-queue %u",
1322 __func__, buf, rn->p.prefixlen, rn, qindex);
1323 continue;
1324 }
1325
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001326 SET_FLAG (rib_dest_from_rnode (rn)->flags, RIB_ROUTE_QUEUED (qindex));
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001327 listnode_add (mq->subq[qindex], rn);
1328 route_lock_node (rn);
1329 mq->size++;
1330
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001331 if (IS_ZEBRA_DEBUG_RIB_Q)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001332 zlog_debug ("%s: %s/%d: queued rn %p into sub-queue %u",
1333 __func__, buf, rn->p.prefixlen, rn, qindex);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001334 }
paul4d38fdb2005-04-28 17:35:14 +00001335}
1336
Paul Jakma6d691122006-07-27 21:49:00 +00001337/* Add route_node to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001338static void
Paul Jakma6d691122006-07-27 21:49:00 +00001339rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
paul4d38fdb2005-04-28 17:35:14 +00001340{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001341 char buf[INET_ADDRSTRLEN];
1342 assert (zebra && rn);
paul4d38fdb2005-04-28 17:35:14 +00001343
Paul Jakma93bdada2007-08-06 19:25:11 +00001344 if (IS_ZEBRA_DEBUG_RIB_Q)
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001345 inet_ntop (AF_INET, &rn->p.u.prefix, buf, INET_ADDRSTRLEN);
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001346
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001347 /* Pointless to queue a route_node with no RIB entries to add or remove */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001348 if (!rnode_to_ribs (rn))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001349 {
1350 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1351 __func__, rn, rn->lock);
1352 zlog_backtrace(LOG_DEBUG);
1353 return;
1354 }
1355
1356 if (IS_ZEBRA_DEBUG_RIB_Q)
1357 zlog_info ("%s: %s/%d: work queue added", __func__, buf, rn->p.prefixlen);
1358
1359 assert (zebra);
1360
1361 if (zebra->ribq == NULL)
1362 {
1363 zlog_err ("%s: work_queue does not exist!", __func__);
1364 return;
Paul Jakma6d691122006-07-27 21:49:00 +00001365 }
paul4d38fdb2005-04-28 17:35:14 +00001366
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001367 /*
1368 * The RIB queue should normally be either empty or holding the only
1369 * work_queue_item element. In the latter case this element would
1370 * hold a pointer to the meta queue structure, which must be used to
1371 * actually queue the route nodes to process. So create the MQ
1372 * holder, if necessary, then push the work into it in any case.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001373 * This semantics was introduced after 0.99.9 release.
1374 */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001375 if (!zebra->ribq->items->count)
1376 work_queue_add (zebra->ribq, zebra->mq);
1377
1378 rib_meta_queue_add (zebra->mq, rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001379
1380 if (IS_ZEBRA_DEBUG_RIB_Q)
1381 zlog_debug ("%s: %s/%d: rn %p queued", __func__, buf, rn->p.prefixlen, rn);
1382
1383 return;
paul4d38fdb2005-04-28 17:35:14 +00001384}
1385
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001386/* Create new meta queue.
1387 A destructor function doesn't seem to be necessary here.
1388 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001389static struct meta_queue *
1390meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001391{
1392 struct meta_queue *new;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001393 unsigned i;
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001394
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001395 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1396 assert(new);
1397
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001398 for (i = 0; i < MQ_SIZE; i++)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001399 {
1400 new->subq[i] = list_new ();
1401 assert(new->subq[i]);
1402 }
1403
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001404 return new;
1405}
1406
paul4d38fdb2005-04-28 17:35:14 +00001407/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001408static void
paul4d38fdb2005-04-28 17:35:14 +00001409rib_queue_init (struct zebra_t *zebra)
1410{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001411 assert (zebra);
1412
paul4d38fdb2005-04-28 17:35:14 +00001413 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001414 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001415 {
Paul Jakma6d691122006-07-27 21:49:00 +00001416 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001417 return;
1418 }
1419
1420 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001421 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001422 zebra->ribq->spec.errorfunc = NULL;
paul4d38fdb2005-04-28 17:35:14 +00001423 /* XXX: TODO: These should be runtime configurable via vty */
1424 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001425 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001426
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001427 if (!(zebra->mq = meta_queue_new ()))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001428 {
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001429 zlog_err ("%s: could not initialise meta queue!", __func__);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001430 return;
1431 }
1432 return;
paul718e3742002-12-13 20:15:29 +00001433}
1434
Paul Jakma6d691122006-07-27 21:49:00 +00001435/* RIB updates are processed via a queue of pointers to route_nodes.
1436 *
1437 * The queue length is bounded by the maximal size of the routing table,
1438 * as a route_node will not be requeued, if already queued.
1439 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001440 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1441 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1442 * and then submit route_node to queue for best-path selection later.
1443 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001444 *
1445 * Deleted RIBs are reaped during best-path selection.
1446 *
1447 * rib_addnode
1448 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001449 * |-------->| | best RIB, if required
1450 * | |
1451 * static_install->|->rib_addqueue...... -> rib_process
1452 * | |
1453 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001454 * |-> set RIB_ENTRY_REMOVE |
1455 * rib_delnode (RIB freed)
1456 *
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001457 * The 'info' pointer of a route_node points to a rib_dest_t
1458 * ('dest'). Queueing state for a route_node is kept on the dest. The
1459 * dest is created on-demand by rib_link() and is kept around at least
1460 * as long as there are ribs hanging off it (@see rib_gc_dest()).
Paul Jakma6d691122006-07-27 21:49:00 +00001461 *
1462 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1463 *
1464 * - route_nodes: refcounted by:
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001465 * - dest attached to route_node:
1466 * - managed by: rib_link/rib_gc_dest
Paul Jakma6d691122006-07-27 21:49:00 +00001467 * - route_node processing queue
1468 * - managed by: rib_addqueue, rib_process.
1469 *
1470 */
1471
paul718e3742002-12-13 20:15:29 +00001472/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001473static void
Paul Jakma6d691122006-07-27 21:49:00 +00001474rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001475{
1476 struct rib *head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001477 rib_dest_t *dest;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001478 char buf[INET6_ADDRSTRLEN];
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001479
paul4d38fdb2005-04-28 17:35:14 +00001480 assert (rib && rn);
1481
Paul Jakma6d691122006-07-27 21:49:00 +00001482 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001483 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001484 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001485 zlog_debug ("%s: %s/%d: rn %p, rib %p", __func__,
1486 buf, rn->p.prefixlen, rn, rib);
1487 }
Paul Jakma6d691122006-07-27 21:49:00 +00001488
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001489 dest = rib_dest_from_rnode (rn);
1490 if (!dest)
Paul Jakma6d691122006-07-27 21:49:00 +00001491 {
1492 if (IS_ZEBRA_DEBUG_RIB)
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001493 {
1494 zlog_debug ("%s: %s/%d: adding dest to table", __func__,
1495 buf, rn->p.prefixlen);
1496 }
1497
1498 dest = XCALLOC (MTYPE_RIB_DEST, sizeof (rib_dest_t));
1499 route_lock_node (rn); /* rn route table reference */
1500 rn->info = dest;
1501 dest->rnode = rn;
1502 }
1503
1504 head = dest->routes;
1505 if (head)
1506 {
Paul Jakma6d691122006-07-27 21:49:00 +00001507 head->prev = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001508 }
paul718e3742002-12-13 20:15:29 +00001509 rib->next = head;
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001510 dest->routes = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001511 rib_queue_add (&zebrad, rn);
1512}
1513
1514static void
1515rib_addnode (struct route_node *rn, struct rib *rib)
1516{
1517 /* RIB node has been un-removed before route-node is processed.
1518 * route_node must hence already be on the queue for processing..
1519 */
1520 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1521 {
1522 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001523 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001524 char buf[INET6_ADDRSTRLEN];
1525 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001526 zlog_debug ("%s: %s/%d: rn %p, un-removed rib %p",
1527 __func__, buf, rn->p.prefixlen, rn, rib);
1528 }
Paul Jakma6d691122006-07-27 21:49:00 +00001529 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1530 return;
1531 }
1532 rib_link (rn, rib);
1533}
1534
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001535/*
1536 * rib_unlink
1537 *
1538 * Detach a rib structure from a route_node.
1539 *
1540 * Note that a call to rib_unlink() should be followed by a call to
1541 * rib_gc_dest() at some point. This allows a rib_dest_t that is no
1542 * longer required to be deleted.
1543 */
Paul Jakma6d691122006-07-27 21:49:00 +00001544static void
1545rib_unlink (struct route_node *rn, struct rib *rib)
1546{
1547 struct nexthop *nexthop, *next;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001548 char buf[INET6_ADDRSTRLEN];
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001549 rib_dest_t *dest;
Paul Jakma6d691122006-07-27 21:49:00 +00001550
1551 assert (rn && rib);
1552
1553 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001554 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001555 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001556 zlog_debug ("%s: %s/%d: rn %p, rib %p",
1557 __func__, buf, rn->p.prefixlen, rn, rib);
1558 }
Paul Jakma6d691122006-07-27 21:49:00 +00001559
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001560 dest = rib_dest_from_rnode (rn);
1561
Paul Jakma6d691122006-07-27 21:49:00 +00001562 if (rib->next)
1563 rib->next->prev = rib->prev;
1564
1565 if (rib->prev)
1566 rib->prev->next = rib->next;
1567 else
1568 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001569 dest->routes = rib->next;
Paul Jakma6d691122006-07-27 21:49:00 +00001570 }
1571
1572 /* free RIB and nexthops */
1573 for (nexthop = rib->nexthop; nexthop; nexthop = next)
1574 {
1575 next = nexthop->next;
1576 nexthop_free (nexthop);
1577 }
1578 XFREE (MTYPE_RIB, rib);
1579
paul718e3742002-12-13 20:15:29 +00001580}
1581
paula1ac18c2005-06-28 17:17:12 +00001582static void
paul718e3742002-12-13 20:15:29 +00001583rib_delnode (struct route_node *rn, struct rib *rib)
1584{
Paul Jakma6d691122006-07-27 21:49:00 +00001585 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001586 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001587 char buf[INET6_ADDRSTRLEN];
1588 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001589 zlog_debug ("%s: %s/%d: rn %p, rib %p, removing", __func__,
1590 buf, rn->p.prefixlen, rn, rib);
1591 }
Paul Jakma6d691122006-07-27 21:49:00 +00001592 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1593 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001594}
1595
1596int
1597rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001598 struct in_addr *gate, struct in_addr *src,
1599 unsigned int ifindex, u_int32_t vrf_id,
G.Balajicddf3912011-11-26 21:59:32 +04001600 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001601{
1602 struct rib *rib;
1603 struct rib *same = NULL;
1604 struct route_table *table;
1605 struct route_node *rn;
1606 struct nexthop *nexthop;
1607
1608 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04001609 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00001610 if (! table)
1611 return 0;
1612
1613 /* Make it sure prefixlen is applied to the prefix. */
1614 apply_mask_ipv4 (p);
1615
1616 /* Set default distance by route type. */
1617 if (distance == 0)
1618 {
Balaji.G837d16c2012-09-26 14:09:10 +05301619 if ((unsigned)type >= array_size(route_info))
David Lamparter7052f222009-08-27 00:28:28 +02001620 distance = 150;
1621 else
1622 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00001623
1624 /* iBGP distance is 200. */
1625 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1626 distance = 200;
1627 }
1628
1629 /* Lookup route node.*/
1630 rn = route_node_get (table, (struct prefix *) p);
1631
1632 /* If same type of route are installed, treat it as a implicit
1633 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001634 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00001635 {
Paul Jakma6d691122006-07-27 21:49:00 +00001636 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1637 continue;
1638
hassoebf1ead2005-09-21 14:58:20 +00001639 if (rib->type != type)
1640 continue;
1641 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001642 {
1643 same = rib;
1644 break;
1645 }
hassoebf1ead2005-09-21 14:58:20 +00001646 /* Duplicate connected route comes in. */
1647 else if ((nexthop = rib->nexthop) &&
1648 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001649 nexthop->ifindex == ifindex &&
1650 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001651 {
1652 rib->refcnt++;
1653 return 0 ;
1654 }
paul718e3742002-12-13 20:15:29 +00001655 }
1656
1657 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001658 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001659 rib->type = type;
1660 rib->distance = distance;
1661 rib->flags = flags;
1662 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001663 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001664 rib->nexthop_num = 0;
1665 rib->uptime = time (NULL);
1666
1667 /* Nexthop settings. */
1668 if (gate)
1669 {
1670 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001671 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001672 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001673 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001674 }
1675 else
1676 nexthop_ifindex_add (rib, ifindex);
1677
1678 /* If this route is kernel route, set FIB flag to the route. */
1679 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1680 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1681 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1682
1683 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001684 if (IS_ZEBRA_DEBUG_RIB)
1685 zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
paul718e3742002-12-13 20:15:29 +00001686 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001687
paul718e3742002-12-13 20:15:29 +00001688 /* Free implicit route.*/
1689 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001690 {
1691 if (IS_ZEBRA_DEBUG_RIB)
1692 zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001693 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001694 }
paul4d38fdb2005-04-28 17:35:14 +00001695
1696 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001697 return 0;
1698}
1699
Denis Ovsienkodc958242007-08-13 16:03:06 +00001700/* This function dumps the contents of a given RIB entry into
1701 * standard debug log. Calling function name and IP prefix in
1702 * question are passed as 1st and 2nd arguments.
1703 */
1704
1705void rib_dump (const char * func, const struct prefix_ipv4 * p, const struct rib * rib)
1706{
1707 char straddr1[INET_ADDRSTRLEN], straddr2[INET_ADDRSTRLEN];
1708 struct nexthop *nexthop;
1709
1710 inet_ntop (AF_INET, &p->prefix, straddr1, INET_ADDRSTRLEN);
1711 zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr1, p->prefixlen);
1712 zlog_debug
1713 (
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001714 "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
Denis Ovsienkodc958242007-08-13 16:03:06 +00001715 func,
1716 rib->refcnt,
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001717 (unsigned long) rib->uptime,
Denis Ovsienkodc958242007-08-13 16:03:06 +00001718 rib->type,
1719 rib->table
1720 );
1721 zlog_debug
1722 (
1723 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1724 func,
1725 rib->metric,
1726 rib->distance,
1727 rib->flags,
1728 rib->status
1729 );
1730 zlog_debug
1731 (
1732 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1733 func,
1734 rib->nexthop_num,
1735 rib->nexthop_active_num,
1736 rib->nexthop_fib_num
1737 );
1738 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1739 {
1740 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, straddr1, INET_ADDRSTRLEN);
1741 inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, straddr2, INET_ADDRSTRLEN);
1742 zlog_debug
1743 (
1744 "%s: NH %s (%s) with flags %s%s%s",
1745 func,
1746 straddr1,
1747 straddr2,
1748 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1749 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1750 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1751 );
1752 }
1753 zlog_debug ("%s: dump complete", func);
1754}
1755
1756/* This is an exported helper to rtm_read() to dump the strange
1757 * RIB entry found by rib_lookup_ipv4_route()
1758 */
1759
1760void rib_lookup_and_dump (struct prefix_ipv4 * p)
1761{
1762 struct route_table *table;
1763 struct route_node *rn;
1764 struct rib *rib;
1765 char prefix_buf[INET_ADDRSTRLEN];
1766
1767 /* Lookup table. */
1768 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1769 if (! table)
1770 {
1771 zlog_err ("%s: vrf_table() returned NULL", __func__);
1772 return;
1773 }
1774
1775 inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
1776 /* Scan the RIB table for exactly matching RIB entry. */
1777 rn = route_node_lookup (table, (struct prefix *) p);
1778
1779 /* No route for this prefix. */
1780 if (! rn)
1781 {
1782 zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
1783 return;
1784 }
1785
1786 /* Unlock node. */
1787 route_unlock_node (rn);
1788
1789 /* let's go */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001790 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001791 {
1792 zlog_debug
1793 (
1794 "%s: rn %p, rib %p: %s, %s",
1795 __func__,
1796 rn,
1797 rib,
1798 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
1799 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
1800 );
1801 rib_dump (__func__, p, rib);
1802 }
1803}
1804
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001805/* Check if requested address assignment will fail due to another
1806 * route being installed by zebra in FIB already. Take necessary
1807 * actions, if needed: remove such a route from FIB and deSELECT
1808 * corresponding RIB entry. Then put affected RN into RIBQ head.
1809 */
1810void rib_lookup_and_pushup (struct prefix_ipv4 * p)
1811{
1812 struct route_table *table;
1813 struct route_node *rn;
1814 struct rib *rib;
1815 unsigned changed = 0;
1816
1817 if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
1818 {
1819 zlog_err ("%s: vrf_table() returned NULL", __func__);
1820 return;
1821 }
1822
1823 /* No matches would be the simplest case. */
1824 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
1825 return;
1826
1827 /* Unlock node. */
1828 route_unlock_node (rn);
1829
1830 /* Check all RIB entries. In case any changes have to be done, requeue
1831 * the RN into RIBQ head. If the routing message about the new connected
1832 * route (generated by the IP address we are going to assign very soon)
1833 * comes before the RIBQ is processed, the new RIB entry will join
1834 * RIBQ record already on head. This is necessary for proper revalidation
1835 * of the rest of the RIB.
1836 */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001837 RNODE_FOREACH_RIB (rn, rib)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001838 {
1839 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
1840 ! RIB_SYSTEM_ROUTE (rib))
1841 {
1842 changed = 1;
1843 if (IS_ZEBRA_DEBUG_RIB)
1844 {
1845 char buf[INET_ADDRSTRLEN];
1846 inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
1847 zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
1848 rib_dump (__func__, (struct prefix_ipv4 *)&rn->p, rib);
1849 }
1850 rib_uninstall (rn, rib);
1851 }
1852 }
1853 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001854 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001855}
1856
paul718e3742002-12-13 20:15:29 +00001857int
G.Balajicddf3912011-11-26 21:59:32 +04001858rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001859{
1860 struct route_table *table;
1861 struct route_node *rn;
1862 struct rib *same;
1863 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00001864
paul718e3742002-12-13 20:15:29 +00001865 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04001866 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00001867 if (! table)
1868 return 0;
G.Balajicddf3912011-11-26 21:59:32 +04001869
paul718e3742002-12-13 20:15:29 +00001870 /* Make it sure prefixlen is applied to the prefix. */
1871 apply_mask_ipv4 (p);
1872
1873 /* Set default distance by route type. */
1874 if (rib->distance == 0)
1875 {
1876 rib->distance = route_info[rib->type].distance;
1877
1878 /* iBGP distance is 200. */
1879 if (rib->type == ZEBRA_ROUTE_BGP
1880 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1881 rib->distance = 200;
1882 }
1883
1884 /* Lookup route node.*/
1885 rn = route_node_get (table, (struct prefix *) p);
1886
1887 /* If same type of route are installed, treat it as a implicit
1888 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001889 RNODE_FOREACH_RIB (rn, same)
paul718e3742002-12-13 20:15:29 +00001890 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00001891 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00001892 continue;
1893
paul718e3742002-12-13 20:15:29 +00001894 if (same->type == rib->type && same->table == rib->table
1895 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001896 break;
paul718e3742002-12-13 20:15:29 +00001897 }
paul4d38fdb2005-04-28 17:35:14 +00001898
paul718e3742002-12-13 20:15:29 +00001899 /* If this route is kernel route, set FIB flag to the route. */
1900 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
1901 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1902 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1903
1904 /* Link new rib to node.*/
1905 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001906 if (IS_ZEBRA_DEBUG_RIB)
1907 {
1908 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
1909 __func__, rn, rib);
1910 rib_dump (__func__, p, rib);
1911 }
paul718e3742002-12-13 20:15:29 +00001912
paul718e3742002-12-13 20:15:29 +00001913 /* Free implicit route.*/
1914 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001915 {
1916 if (IS_ZEBRA_DEBUG_RIB)
1917 {
1918 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
1919 __func__, rn, same);
1920 rib_dump (__func__, p, same);
1921 }
paul4d38fdb2005-04-28 17:35:14 +00001922 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001923 }
paul4d38fdb2005-04-28 17:35:14 +00001924
1925 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001926 return 0;
1927}
1928
hassoebf1ead2005-09-21 14:58:20 +00001929/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00001930int
1931rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
G.Balajicddf3912011-11-26 21:59:32 +04001932 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001933{
1934 struct route_table *table;
1935 struct route_node *rn;
1936 struct rib *rib;
1937 struct rib *fib = NULL;
1938 struct rib *same = NULL;
1939 struct nexthop *nexthop;
Stephen Hemminger81cce012009-04-28 14:28:00 -07001940 char buf1[INET_ADDRSTRLEN];
1941 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00001942
1943 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04001944 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00001945 if (! table)
1946 return 0;
1947
1948 /* Apply mask. */
1949 apply_mask_ipv4 (p);
1950
paul5ec90d22003-06-19 01:41:37 +00001951 if (IS_ZEBRA_DEBUG_KERNEL && gate)
ajsb6178002004-12-07 21:12:56 +00001952 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001953 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul5ec90d22003-06-19 01:41:37 +00001954 p->prefixlen,
1955 inet_ntoa (*gate),
1956 ifindex);
1957
paul718e3742002-12-13 20:15:29 +00001958 /* Lookup route node. */
1959 rn = route_node_lookup (table, (struct prefix *) p);
1960 if (! rn)
1961 {
1962 if (IS_ZEBRA_DEBUG_KERNEL)
1963 {
1964 if (gate)
ajsb6178002004-12-07 21:12:56 +00001965 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001966 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001967 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07001968 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001969 ifindex);
1970 else
ajsb6178002004-12-07 21:12:56 +00001971 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001972 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001973 p->prefixlen,
1974 ifindex);
1975 }
1976 return ZEBRA_ERR_RTNOEXIST;
1977 }
1978
1979 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001980 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00001981 {
Paul Jakma6d691122006-07-27 21:49:00 +00001982 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1983 continue;
1984
paul718e3742002-12-13 20:15:29 +00001985 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1986 fib = rib;
1987
hassoebf1ead2005-09-21 14:58:20 +00001988 if (rib->type != type)
1989 continue;
1990 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04001991 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00001992 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04001993 if (nexthop->ifindex != ifindex)
1994 continue;
hassoebf1ead2005-09-21 14:58:20 +00001995 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00001996 {
hassoebf1ead2005-09-21 14:58:20 +00001997 rib->refcnt--;
1998 route_unlock_node (rn);
1999 route_unlock_node (rn);
2000 return 0;
paul718e3742002-12-13 20:15:29 +00002001 }
hassoebf1ead2005-09-21 14:58:20 +00002002 same = rib;
2003 break;
paul718e3742002-12-13 20:15:29 +00002004 }
hassoebf1ead2005-09-21 14:58:20 +00002005 /* Make sure that the route found has the same gateway. */
2006 else if (gate == NULL ||
2007 ((nexthop = rib->nexthop) &&
2008 (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
2009 IPV4_ADDR_SAME (&nexthop->rgate.ipv4, gate))))
paul5ec90d22003-06-19 01:41:37 +00002010 {
hassoebf1ead2005-09-21 14:58:20 +00002011 same = rib;
2012 break;
paul718e3742002-12-13 20:15:29 +00002013 }
2014 }
2015
2016 /* If same type of route can't be found and this message is from
2017 kernel. */
2018 if (! same)
2019 {
2020 if (fib && type == ZEBRA_ROUTE_KERNEL)
2021 {
2022 /* Unset flags. */
2023 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2024 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2025
2026 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2027 }
2028 else
2029 {
2030 if (IS_ZEBRA_DEBUG_KERNEL)
2031 {
2032 if (gate)
ajsb6178002004-12-07 21:12:56 +00002033 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002034 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002035 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002036 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002037 ifindex,
2038 type);
2039 else
ajsb6178002004-12-07 21:12:56 +00002040 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002041 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002042 p->prefixlen,
2043 ifindex,
2044 type);
2045 }
2046 route_unlock_node (rn);
2047 return ZEBRA_ERR_RTNOEXIST;
2048 }
2049 }
paul4d38fdb2005-04-28 17:35:14 +00002050
paul718e3742002-12-13 20:15:29 +00002051 if (same)
2052 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002053
paul718e3742002-12-13 20:15:29 +00002054 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002055 return 0;
2056}
2057
2058/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002059static void
paul718e3742002-12-13 20:15:29 +00002060static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
2061{
2062 struct rib *rib;
2063 struct route_node *rn;
2064 struct route_table *table;
2065
2066 /* Lookup table. */
2067 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2068 if (! table)
2069 return;
2070
2071 /* Lookup existing route */
2072 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002073 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002074 {
2075 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2076 continue;
2077
2078 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2079 break;
2080 }
paul718e3742002-12-13 20:15:29 +00002081
2082 if (rib)
2083 {
2084 /* Same distance static route is there. Update it with new
2085 nexthop. */
paul718e3742002-12-13 20:15:29 +00002086 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002087 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002088 {
2089 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002090 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002091 break;
2092 case STATIC_IPV4_IFNAME:
2093 nexthop_ifname_add (rib, si->gate.ifname);
2094 break;
2095 case STATIC_IPV4_BLACKHOLE:
2096 nexthop_blackhole_add (rib);
2097 break;
paul4d38fdb2005-04-28 17:35:14 +00002098 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002099 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002100 }
2101 else
2102 {
2103 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002104 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2105
paul718e3742002-12-13 20:15:29 +00002106 rib->type = ZEBRA_ROUTE_STATIC;
2107 rib->distance = si->distance;
2108 rib->metric = 0;
Nolan Leakeb0145dd2012-09-13 17:17:31 +00002109 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002110 rib->nexthop_num = 0;
2111
2112 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002113 {
2114 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002115 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002116 break;
2117 case STATIC_IPV4_IFNAME:
2118 nexthop_ifname_add (rib, si->gate.ifname);
2119 break;
2120 case STATIC_IPV4_BLACKHOLE:
2121 nexthop_blackhole_add (rib);
2122 break;
2123 }
paul718e3742002-12-13 20:15:29 +00002124
hasso81dfcaa2003-05-25 19:21:25 +00002125 /* Save the flags of this static routes (reject, blackhole) */
2126 rib->flags = si->flags;
2127
paul718e3742002-12-13 20:15:29 +00002128 /* Link this rib to the tree. */
2129 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002130 }
2131}
2132
paula1ac18c2005-06-28 17:17:12 +00002133static int
paul718e3742002-12-13 20:15:29 +00002134static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2135{
2136 if (nexthop->type == NEXTHOP_TYPE_IPV4
2137 && si->type == STATIC_IPV4_GATEWAY
2138 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2139 return 1;
2140 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2141 && si->type == STATIC_IPV4_IFNAME
2142 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2143 return 1;
paul595db7f2003-05-25 21:35:06 +00002144 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2145 && si->type == STATIC_IPV4_BLACKHOLE)
2146 return 1;
paule8e19462006-01-19 20:16:55 +00002147 return 0;
paul718e3742002-12-13 20:15:29 +00002148}
2149
2150/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002151static void
paul718e3742002-12-13 20:15:29 +00002152static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
2153{
2154 struct route_node *rn;
2155 struct rib *rib;
2156 struct nexthop *nexthop;
2157 struct route_table *table;
2158
2159 /* Lookup table. */
2160 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2161 if (! table)
2162 return;
paul4d38fdb2005-04-28 17:35:14 +00002163
paul718e3742002-12-13 20:15:29 +00002164 /* Lookup existing route with type and distance. */
2165 rn = route_node_lookup (table, p);
2166 if (! rn)
2167 return;
2168
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002169 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002170 {
2171 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2172 continue;
2173
2174 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2175 break;
2176 }
paul718e3742002-12-13 20:15:29 +00002177
2178 if (! rib)
2179 {
2180 route_unlock_node (rn);
2181 return;
2182 }
2183
2184 /* Lookup nexthop. */
2185 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2186 if (static_ipv4_nexthop_same (nexthop, si))
2187 break;
2188
2189 /* Can't find nexthop. */
2190 if (! nexthop)
2191 {
2192 route_unlock_node (rn);
2193 return;
2194 }
2195
2196 /* Check nexthop. */
2197 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002198 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002199 else
2200 {
paul6baeb982003-10-28 03:47:15 +00002201 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2202 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002203 nexthop_delete (rib, nexthop);
2204 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002205 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002206 }
paul718e3742002-12-13 20:15:29 +00002207 /* Unlock node. */
2208 route_unlock_node (rn);
2209}
2210
2211/* Add static route into static route configuration. */
2212int
hasso39db97e2004-10-12 20:50:58 +00002213static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00002214 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002215{
2216 u_char type = 0;
2217 struct route_node *rn;
2218 struct static_ipv4 *si;
2219 struct static_ipv4 *pp;
2220 struct static_ipv4 *cp;
2221 struct static_ipv4 *update = NULL;
2222 struct route_table *stable;
2223
2224 /* Lookup table. */
2225 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2226 if (! stable)
2227 return -1;
2228
2229 /* Lookup static route prefix. */
2230 rn = route_node_get (stable, p);
2231
2232 /* Make flags. */
2233 if (gate)
2234 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002235 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002236 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002237 else
2238 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002239
2240 /* Do nothing if there is a same static route. */
2241 for (si = rn->info; si; si = si->next)
2242 {
2243 if (type == si->type
2244 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2245 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2246 {
2247 if (distance == si->distance)
2248 {
2249 route_unlock_node (rn);
2250 return 0;
2251 }
2252 else
2253 update = si;
2254 }
2255 }
2256
Paul Jakma3c0755d2006-12-08 00:53:14 +00002257 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002258 if (update)
2259 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
2260
2261 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002262 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
paul718e3742002-12-13 20:15:29 +00002263
2264 si->type = type;
2265 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002266 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002267
2268 if (gate)
2269 si->gate.ipv4 = *gate;
2270 if (ifname)
2271 si->gate.ifname = XSTRDUP (0, ifname);
2272
2273 /* Add new static route information to the tree with sort by
2274 distance value and gateway address. */
2275 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2276 {
2277 if (si->distance < cp->distance)
2278 break;
2279 if (si->distance > cp->distance)
2280 continue;
2281 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2282 {
2283 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2284 break;
2285 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2286 continue;
2287 }
2288 }
2289
2290 /* Make linked list. */
2291 if (pp)
2292 pp->next = si;
2293 else
2294 rn->info = si;
2295 if (cp)
2296 cp->prev = si;
2297 si->prev = pp;
2298 si->next = cp;
2299
2300 /* Install into rib. */
2301 static_install_ipv4 (p, si);
2302
2303 return 1;
2304}
2305
2306/* Delete static route from static route configuration. */
2307int
hasso39db97e2004-10-12 20:50:58 +00002308static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00002309 u_char distance, u_int32_t vrf_id)
2310{
2311 u_char type = 0;
2312 struct route_node *rn;
2313 struct static_ipv4 *si;
2314 struct route_table *stable;
2315
2316 /* Lookup table. */
2317 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2318 if (! stable)
2319 return -1;
2320
2321 /* Lookup static route prefix. */
2322 rn = route_node_lookup (stable, p);
2323 if (! rn)
2324 return 0;
2325
2326 /* Make flags. */
2327 if (gate)
2328 type = STATIC_IPV4_GATEWAY;
2329 else if (ifname)
2330 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002331 else
2332 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002333
2334 /* Find same static route is the tree */
2335 for (si = rn->info; si; si = si->next)
2336 if (type == si->type
2337 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2338 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2339 break;
2340
2341 /* Can't find static route. */
2342 if (! si)
2343 {
2344 route_unlock_node (rn);
2345 return 0;
2346 }
2347
2348 /* Install into rib. */
2349 static_uninstall_ipv4 (p, si);
2350
2351 /* Unlink static route from linked list. */
2352 if (si->prev)
2353 si->prev->next = si->next;
2354 else
2355 rn->info = si->next;
2356 if (si->next)
2357 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002358 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002359
2360 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002361 if (ifname)
2362 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002363 XFREE (MTYPE_STATIC_IPV4, si);
2364
paul143a3852003-09-29 20:06:13 +00002365 route_unlock_node (rn);
2366
paul718e3742002-12-13 20:15:29 +00002367 return 1;
2368}
2369
2370
2371#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00002372static int
paul718e3742002-12-13 20:15:29 +00002373rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2374 struct in6_addr *gate, unsigned int ifindex, int table)
2375{
hasso726f9b22003-05-25 21:04:54 +00002376 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2377#if defined (MUSICA) || defined (LINUX)
2378 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2379 if (p->prefixlen == 96)
2380 return 0;
2381#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00002382 return 1;
hasso726f9b22003-05-25 21:04:54 +00002383 }
paul718e3742002-12-13 20:15:29 +00002384 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
2385 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
2386 {
2387 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
2388 return 1;
2389 }
2390 return 0;
2391}
2392
2393int
2394rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00002395 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
G.Balajif768f362011-11-26 22:10:39 +04002396 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002397{
2398 struct rib *rib;
2399 struct rib *same = NULL;
2400 struct route_table *table;
2401 struct route_node *rn;
2402 struct nexthop *nexthop;
2403
paul718e3742002-12-13 20:15:29 +00002404 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002405 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002406 if (! table)
2407 return 0;
2408
2409 /* Make sure mask is applied. */
2410 apply_mask_ipv6 (p);
2411
2412 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002413 if (!distance)
2414 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002415
2416 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2417 distance = 200;
2418
2419 /* Filter bogus route. */
2420 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
2421 return 0;
2422
2423 /* Lookup route node.*/
2424 rn = route_node_get (table, (struct prefix *) p);
2425
2426 /* If same type of route are installed, treat it as a implicit
2427 withdraw. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002428 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002429 {
Paul Jakma6d691122006-07-27 21:49:00 +00002430 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2431 continue;
2432
hassoebf1ead2005-09-21 14:58:20 +00002433 if (rib->type != type)
2434 continue;
2435 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002436 {
2437 same = rib;
paul718e3742002-12-13 20:15:29 +00002438 break;
2439 }
hassoebf1ead2005-09-21 14:58:20 +00002440 else if ((nexthop = rib->nexthop) &&
2441 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2442 nexthop->ifindex == ifindex)
2443 {
2444 rib->refcnt++;
2445 return 0;
2446 }
paul718e3742002-12-13 20:15:29 +00002447 }
2448
2449 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002450 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2451
paul718e3742002-12-13 20:15:29 +00002452 rib->type = type;
2453 rib->distance = distance;
2454 rib->flags = flags;
2455 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00002456 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00002457 rib->nexthop_num = 0;
2458 rib->uptime = time (NULL);
2459
2460 /* Nexthop settings. */
2461 if (gate)
2462 {
2463 if (ifindex)
2464 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2465 else
2466 nexthop_ipv6_add (rib, gate);
2467 }
2468 else
2469 nexthop_ifindex_add (rib, ifindex);
2470
2471 /* If this route is kernel route, set FIB flag to the route. */
2472 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2473 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2474 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2475
2476 /* Link new rib to node.*/
2477 rib_addnode (rn, rib);
2478
paul718e3742002-12-13 20:15:29 +00002479 /* Free implicit route.*/
2480 if (same)
paul4d38fdb2005-04-28 17:35:14 +00002481 rib_delnode (rn, same);
2482
2483 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002484 return 0;
2485}
2486
hassoebf1ead2005-09-21 14:58:20 +00002487/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002488int
2489rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
G.Balajif768f362011-11-26 22:10:39 +04002490 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002491{
2492 struct route_table *table;
2493 struct route_node *rn;
2494 struct rib *rib;
2495 struct rib *fib = NULL;
2496 struct rib *same = NULL;
2497 struct nexthop *nexthop;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002498 char buf1[INET6_ADDRSTRLEN];
2499 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002500
2501 /* Apply mask. */
2502 apply_mask_ipv6 (p);
2503
2504 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002505 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002506 if (! table)
2507 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002508
paul718e3742002-12-13 20:15:29 +00002509 /* Lookup route node. */
2510 rn = route_node_lookup (table, (struct prefix *) p);
2511 if (! rn)
2512 {
2513 if (IS_ZEBRA_DEBUG_KERNEL)
2514 {
2515 if (gate)
ajsb6178002004-12-07 21:12:56 +00002516 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002517 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002518 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002519 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002520 ifindex);
2521 else
ajsb6178002004-12-07 21:12:56 +00002522 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002523 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002524 p->prefixlen,
2525 ifindex);
2526 }
2527 return ZEBRA_ERR_RTNOEXIST;
2528 }
2529
2530 /* Lookup same type route. */
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002531 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00002532 {
Paul Jakma6d691122006-07-27 21:49:00 +00002533 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2534 continue;
2535
paul718e3742002-12-13 20:15:29 +00002536 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2537 fib = rib;
2538
hassoebf1ead2005-09-21 14:58:20 +00002539 if (rib->type != type)
2540 continue;
2541 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002542 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002543 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002544 if (nexthop->ifindex != ifindex)
2545 continue;
hassoebf1ead2005-09-21 14:58:20 +00002546 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002547 {
hassoebf1ead2005-09-21 14:58:20 +00002548 rib->refcnt--;
2549 route_unlock_node (rn);
2550 route_unlock_node (rn);
2551 return 0;
paul718e3742002-12-13 20:15:29 +00002552 }
hassoebf1ead2005-09-21 14:58:20 +00002553 same = rib;
2554 break;
paul718e3742002-12-13 20:15:29 +00002555 }
hassoebf1ead2005-09-21 14:58:20 +00002556 /* Make sure that the route found has the same gateway. */
2557 else if (gate == NULL ||
2558 ((nexthop = rib->nexthop) &&
2559 (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate) ||
2560 IPV6_ADDR_SAME (&nexthop->rgate.ipv6, gate))))
paul718e3742002-12-13 20:15:29 +00002561 {
hassoebf1ead2005-09-21 14:58:20 +00002562 same = rib;
2563 break;
paul718e3742002-12-13 20:15:29 +00002564 }
2565 }
2566
2567 /* If same type of route can't be found and this message is from
2568 kernel. */
2569 if (! same)
2570 {
2571 if (fib && type == ZEBRA_ROUTE_KERNEL)
2572 {
2573 /* Unset flags. */
2574 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2575 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2576
2577 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2578 }
2579 else
2580 {
2581 if (IS_ZEBRA_DEBUG_KERNEL)
2582 {
2583 if (gate)
ajsb6178002004-12-07 21:12:56 +00002584 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002585 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002586 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002587 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002588 ifindex,
2589 type);
2590 else
ajsb6178002004-12-07 21:12:56 +00002591 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002592 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002593 p->prefixlen,
2594 ifindex,
2595 type);
2596 }
2597 route_unlock_node (rn);
2598 return ZEBRA_ERR_RTNOEXIST;
2599 }
2600 }
2601
2602 if (same)
2603 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002604
paul718e3742002-12-13 20:15:29 +00002605 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002606 return 0;
2607}
2608
2609/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002610static void
paul718e3742002-12-13 20:15:29 +00002611static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2612{
2613 struct rib *rib;
2614 struct route_table *table;
2615 struct route_node *rn;
2616
2617 /* Lookup table. */
2618 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2619 if (! table)
2620 return;
2621
2622 /* Lookup existing route */
2623 rn = route_node_get (table, p);
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002624 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002625 {
2626 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2627 continue;
2628
2629 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2630 break;
2631 }
paul718e3742002-12-13 20:15:29 +00002632
2633 if (rib)
2634 {
2635 /* Same distance static route is there. Update it with new
2636 nexthop. */
paul718e3742002-12-13 20:15:29 +00002637 route_unlock_node (rn);
2638
2639 switch (si->type)
2640 {
2641 case STATIC_IPV6_GATEWAY:
2642 nexthop_ipv6_add (rib, &si->ipv6);
2643 break;
2644 case STATIC_IPV6_IFNAME:
2645 nexthop_ifname_add (rib, si->ifname);
2646 break;
2647 case STATIC_IPV6_GATEWAY_IFNAME:
2648 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2649 break;
2650 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002651 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002652 }
2653 else
2654 {
2655 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002656 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2657
paul718e3742002-12-13 20:15:29 +00002658 rib->type = ZEBRA_ROUTE_STATIC;
2659 rib->distance = si->distance;
2660 rib->metric = 0;
2661 rib->nexthop_num = 0;
2662
2663 switch (si->type)
2664 {
2665 case STATIC_IPV6_GATEWAY:
2666 nexthop_ipv6_add (rib, &si->ipv6);
2667 break;
2668 case STATIC_IPV6_IFNAME:
2669 nexthop_ifname_add (rib, si->ifname);
2670 break;
2671 case STATIC_IPV6_GATEWAY_IFNAME:
2672 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2673 break;
2674 }
2675
hasso81dfcaa2003-05-25 19:21:25 +00002676 /* Save the flags of this static routes (reject, blackhole) */
2677 rib->flags = si->flags;
2678
paul718e3742002-12-13 20:15:29 +00002679 /* Link this rib to the tree. */
2680 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002681 }
2682}
2683
paula1ac18c2005-06-28 17:17:12 +00002684static int
paul718e3742002-12-13 20:15:29 +00002685static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2686{
2687 if (nexthop->type == NEXTHOP_TYPE_IPV6
2688 && si->type == STATIC_IPV6_GATEWAY
2689 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2690 return 1;
2691 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2692 && si->type == STATIC_IPV6_IFNAME
2693 && strcmp (nexthop->ifname, si->ifname) == 0)
2694 return 1;
2695 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2696 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2697 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2698 && strcmp (nexthop->ifname, si->ifname) == 0)
2699 return 1;
paule8e19462006-01-19 20:16:55 +00002700 return 0;
paul718e3742002-12-13 20:15:29 +00002701}
2702
paula1ac18c2005-06-28 17:17:12 +00002703static void
paul718e3742002-12-13 20:15:29 +00002704static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2705{
2706 struct route_table *table;
2707 struct route_node *rn;
2708 struct rib *rib;
2709 struct nexthop *nexthop;
2710
2711 /* Lookup table. */
2712 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2713 if (! table)
2714 return;
2715
2716 /* Lookup existing route with type and distance. */
2717 rn = route_node_lookup (table, (struct prefix *) p);
2718 if (! rn)
2719 return;
2720
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002721 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00002722 {
2723 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2724 continue;
2725
2726 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2727 break;
2728 }
2729
paul718e3742002-12-13 20:15:29 +00002730 if (! rib)
2731 {
2732 route_unlock_node (rn);
2733 return;
2734 }
2735
2736 /* Lookup nexthop. */
2737 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2738 if (static_ipv6_nexthop_same (nexthop, si))
2739 break;
2740
2741 /* Can't find nexthop. */
2742 if (! nexthop)
2743 {
2744 route_unlock_node (rn);
2745 return;
2746 }
2747
2748 /* Check nexthop. */
2749 if (rib->nexthop_num == 1)
2750 {
2751 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002752 }
2753 else
2754 {
paul6baeb982003-10-28 03:47:15 +00002755 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2756 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002757 nexthop_delete (rib, nexthop);
2758 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002759 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002760 }
paul718e3742002-12-13 20:15:29 +00002761 /* Unlock node. */
2762 route_unlock_node (rn);
2763}
2764
2765/* Add static route into static route configuration. */
2766int
2767static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002768 const char *ifname, u_char flags, u_char distance,
2769 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002770{
2771 struct route_node *rn;
2772 struct static_ipv6 *si;
2773 struct static_ipv6 *pp;
2774 struct static_ipv6 *cp;
2775 struct route_table *stable;
2776
2777 /* Lookup table. */
2778 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2779 if (! stable)
2780 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00002781
2782 if (!gate &&
2783 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
2784 return -1;
2785
2786 if (!ifname &&
2787 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
2788 return -1;
paul718e3742002-12-13 20:15:29 +00002789
2790 /* Lookup static route prefix. */
2791 rn = route_node_get (stable, p);
2792
2793 /* Do nothing if there is a same static route. */
2794 for (si = rn->info; si; si = si->next)
2795 {
2796 if (distance == si->distance
2797 && type == si->type
2798 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2799 && (! ifname || strcmp (ifname, si->ifname) == 0))
2800 {
2801 route_unlock_node (rn);
2802 return 0;
2803 }
2804 }
2805
2806 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002807 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
paul718e3742002-12-13 20:15:29 +00002808
2809 si->type = type;
2810 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002811 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002812
2813 switch (type)
2814 {
2815 case STATIC_IPV6_GATEWAY:
2816 si->ipv6 = *gate;
2817 break;
2818 case STATIC_IPV6_IFNAME:
2819 si->ifname = XSTRDUP (0, ifname);
2820 break;
2821 case STATIC_IPV6_GATEWAY_IFNAME:
2822 si->ipv6 = *gate;
2823 si->ifname = XSTRDUP (0, ifname);
2824 break;
2825 }
2826
2827 /* Add new static route information to the tree with sort by
2828 distance value and gateway address. */
2829 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2830 {
2831 if (si->distance < cp->distance)
2832 break;
2833 if (si->distance > cp->distance)
2834 continue;
2835 }
2836
2837 /* Make linked list. */
2838 if (pp)
2839 pp->next = si;
2840 else
2841 rn->info = si;
2842 if (cp)
2843 cp->prev = si;
2844 si->prev = pp;
2845 si->next = cp;
2846
2847 /* Install into rib. */
2848 static_install_ipv6 (p, si);
2849
2850 return 1;
2851}
2852
2853/* Delete static route from static route configuration. */
2854int
2855static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002856 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002857{
2858 struct route_node *rn;
2859 struct static_ipv6 *si;
2860 struct route_table *stable;
2861
2862 /* Lookup table. */
2863 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2864 if (! stable)
2865 return -1;
2866
2867 /* Lookup static route prefix. */
2868 rn = route_node_lookup (stable, p);
2869 if (! rn)
2870 return 0;
2871
2872 /* Find same static route is the tree */
2873 for (si = rn->info; si; si = si->next)
2874 if (distance == si->distance
2875 && type == si->type
2876 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2877 && (! ifname || strcmp (ifname, si->ifname) == 0))
2878 break;
2879
2880 /* Can't find static route. */
2881 if (! si)
2882 {
2883 route_unlock_node (rn);
2884 return 0;
2885 }
2886
2887 /* Install into rib. */
2888 static_uninstall_ipv6 (p, si);
2889
2890 /* Unlink static route from linked list. */
2891 if (si->prev)
2892 si->prev->next = si->next;
2893 else
2894 rn->info = si->next;
2895 if (si->next)
2896 si->next->prev = si->prev;
2897
2898 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002899 if (ifname)
2900 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00002901 XFREE (MTYPE_STATIC_IPV6, si);
2902
2903 return 1;
2904}
2905#endif /* HAVE_IPV6 */
2906
2907/* RIB update function. */
2908void
paula1ac18c2005-06-28 17:17:12 +00002909rib_update (void)
paul718e3742002-12-13 20:15:29 +00002910{
2911 struct route_node *rn;
2912 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00002913
paul718e3742002-12-13 20:15:29 +00002914 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2915 if (table)
2916 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002917 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00002918 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002919
2920 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2921 if (table)
2922 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002923 if (rnode_to_ribs (rn))
Paul Jakma6d691122006-07-27 21:49:00 +00002924 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002925}
2926
paul718e3742002-12-13 20:15:29 +00002927
2928/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00002929static void
paul718e3742002-12-13 20:15:29 +00002930rib_weed_table (struct route_table *table)
2931{
2932 struct route_node *rn;
2933 struct rib *rib;
2934 struct rib *next;
2935
2936 if (table)
2937 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002938 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00002939 {
Paul Jakma6d691122006-07-27 21:49:00 +00002940 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2941 continue;
2942
paulb21b19c2003-06-15 01:28:29 +00002943 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00002944 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00002945 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002946 }
2947}
2948
2949/* Delete all routes from non main table. */
2950void
paula1ac18c2005-06-28 17:17:12 +00002951rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00002952{
2953 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2954 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2955}
2956
2957/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00002958static void
paul718e3742002-12-13 20:15:29 +00002959rib_sweep_table (struct route_table *table)
2960{
2961 struct route_node *rn;
2962 struct rib *rib;
2963 struct rib *next;
2964 int ret = 0;
2965
2966 if (table)
2967 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002968 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
paul718e3742002-12-13 20:15:29 +00002969 {
Paul Jakma6d691122006-07-27 21:49:00 +00002970 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2971 continue;
2972
paul718e3742002-12-13 20:15:29 +00002973 if (rib->type == ZEBRA_ROUTE_KERNEL &&
2974 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
2975 {
2976 ret = rib_uninstall_kernel (rn, rib);
2977 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00002978 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002979 }
2980 }
2981}
2982
2983/* Sweep all RIB tables. */
2984void
paula1ac18c2005-06-28 17:17:12 +00002985rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00002986{
2987 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2988 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2989}
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04002990
2991/* Remove specific by protocol routes from 'table'. */
2992static unsigned long
2993rib_score_proto_table (u_char proto, struct route_table *table)
2994{
2995 struct route_node *rn;
2996 struct rib *rib;
2997 struct rib *next;
2998 unsigned long n = 0;
2999
3000 if (table)
3001 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003002 RNODE_FOREACH_RIB_SAFE (rn, rib, next)
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003003 {
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04003004 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3005 continue;
3006 if (rib->type == proto)
3007 {
3008 rib_delnode (rn, rib);
3009 n++;
3010 }
3011 }
3012
3013 return n;
3014}
3015
3016/* Remove specific by protocol routes. */
3017unsigned long
3018rib_score_proto (u_char proto)
3019{
3020 return rib_score_proto_table (proto, vrf_table (AFI_IP, SAFI_UNICAST, 0))
3021 +rib_score_proto_table (proto, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3022}
3023
paul718e3742002-12-13 20:15:29 +00003024/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00003025static void
paul718e3742002-12-13 20:15:29 +00003026rib_close_table (struct route_table *table)
3027{
3028 struct route_node *rn;
3029 struct rib *rib;
3030
3031 if (table)
3032 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003033 RNODE_FOREACH_RIB (rn, rib)
Paul Jakma6d691122006-07-27 21:49:00 +00003034 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00003035 if (!CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
3036 continue;
3037
3038 if (! RIB_SYSTEM_ROUTE (rib))
3039 rib_uninstall_kernel (rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00003040 }
paul718e3742002-12-13 20:15:29 +00003041}
3042
3043/* Close all RIB tables. */
3044void
paula1ac18c2005-06-28 17:17:12 +00003045rib_close (void)
paul718e3742002-12-13 20:15:29 +00003046{
3047 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3048 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3049}
3050
3051/* Routing information base initialize. */
3052void
paula1ac18c2005-06-28 17:17:12 +00003053rib_init (void)
paul718e3742002-12-13 20:15:29 +00003054{
paul4d38fdb2005-04-28 17:35:14 +00003055 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00003056 /* VRF initialization. */
3057 vrf_init ();
3058}