blob: a366cf1fa2423a6ff018a61cf88631d5105dd576 [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;
58} route_info[] =
59{
60 {ZEBRA_ROUTE_SYSTEM, 0},
61 {ZEBRA_ROUTE_KERNEL, 0},
62 {ZEBRA_ROUTE_CONNECT, 0},
63 {ZEBRA_ROUTE_STATIC, 1},
64 {ZEBRA_ROUTE_RIP, 120},
65 {ZEBRA_ROUTE_RIPNG, 120},
66 {ZEBRA_ROUTE_OSPF, 110},
67 {ZEBRA_ROUTE_OSPF6, 110},
jardin9e867fe2003-12-23 08:56:18 +000068 {ZEBRA_ROUTE_ISIS, 115},
paul718e3742002-12-13 20:15:29 +000069 {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */}
David Lamparter7052f222009-08-27 00:28:28 +020070 /* no entry/default: 150 */
paul718e3742002-12-13 20:15:29 +000071};
72
73/* Vector for routing table. */
Stephen Hemmingerd145bc02008-08-17 17:41:37 +010074static vector vrf_vector;
paul718e3742002-12-13 20:15:29 +000075
76/* Allocate new VRF. */
paula1ac18c2005-06-28 17:17:12 +000077static struct vrf *
hassofce954f2004-10-07 20:29:24 +000078vrf_alloc (const char *name)
paul718e3742002-12-13 20:15:29 +000079{
80 struct vrf *vrf;
81
82 vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
83
84 /* Put name. */
85 if (name)
86 vrf->name = XSTRDUP (MTYPE_VRF_NAME, name);
87
88 /* Allocate routing table and static table. */
89 vrf->table[AFI_IP][SAFI_UNICAST] = route_table_init ();
90 vrf->table[AFI_IP6][SAFI_UNICAST] = route_table_init ();
91 vrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
92 vrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
G.Balajicddf3912011-11-26 21:59:32 +040093 vrf->table[AFI_IP][SAFI_MULTICAST] = route_table_init ();
94 vrf->table[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
95 vrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
96 vrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
97
paul718e3742002-12-13 20:15:29 +000098
99 return vrf;
100}
101
paul718e3742002-12-13 20:15:29 +0000102/* Lookup VRF by identifier. */
103struct vrf *
104vrf_lookup (u_int32_t id)
105{
106 return vector_lookup (vrf_vector, id);
107}
108
paul718e3742002-12-13 20:15:29 +0000109/* Initialize VRF. */
paula1ac18c2005-06-28 17:17:12 +0000110static void
111vrf_init (void)
paul718e3742002-12-13 20:15:29 +0000112{
113 struct vrf *default_table;
114
115 /* Allocate VRF vector. */
116 vrf_vector = vector_init (1);
117
118 /* Allocate default main table. */
119 default_table = vrf_alloc ("Default-IP-Routing-Table");
120
121 /* Default table index must be 0. */
122 vector_set_index (vrf_vector, 0, default_table);
123}
124
125/* Lookup route table. */
126struct route_table *
127vrf_table (afi_t afi, safi_t safi, u_int32_t id)
128{
129 struct vrf *vrf;
130
131 vrf = vrf_lookup (id);
132 if (! vrf)
133 return NULL;
134
135 return vrf->table[afi][safi];
136}
137
138/* Lookup static route table. */
139struct route_table *
140vrf_static_table (afi_t afi, safi_t safi, u_int32_t id)
141{
142 struct vrf *vrf;
143
144 vrf = vrf_lookup (id);
145 if (! vrf)
146 return NULL;
147
148 return vrf->stable[afi][safi];
149}
150
151/* Add nexthop to the end of the list. */
paula1ac18c2005-06-28 17:17:12 +0000152static void
paul718e3742002-12-13 20:15:29 +0000153nexthop_add (struct rib *rib, struct nexthop *nexthop)
154{
155 struct nexthop *last;
156
157 for (last = rib->nexthop; last && last->next; last = last->next)
158 ;
159 if (last)
160 last->next = nexthop;
161 else
162 rib->nexthop = nexthop;
163 nexthop->prev = last;
164
165 rib->nexthop_num++;
166}
167
168/* Delete specified nexthop from the list. */
paula1ac18c2005-06-28 17:17:12 +0000169static void
paul718e3742002-12-13 20:15:29 +0000170nexthop_delete (struct rib *rib, struct nexthop *nexthop)
171{
172 if (nexthop->next)
173 nexthop->next->prev = nexthop->prev;
174 if (nexthop->prev)
175 nexthop->prev->next = nexthop->next;
176 else
177 rib->nexthop = nexthop->next;
178 rib->nexthop_num--;
179}
180
181/* Free nexthop. */
paula1ac18c2005-06-28 17:17:12 +0000182static void
paul718e3742002-12-13 20:15:29 +0000183nexthop_free (struct nexthop *nexthop)
184{
paula4b70762003-05-16 17:19:48 +0000185 if (nexthop->ifname)
186 XFREE (0, nexthop->ifname);
paul718e3742002-12-13 20:15:29 +0000187 XFREE (MTYPE_NEXTHOP, nexthop);
188}
189
190struct nexthop *
191nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
192{
193 struct nexthop *nexthop;
194
Stephen Hemminger393deb92008-08-18 14:13:29 -0700195 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000196 nexthop->type = NEXTHOP_TYPE_IFINDEX;
197 nexthop->ifindex = ifindex;
198
199 nexthop_add (rib, nexthop);
200
201 return nexthop;
202}
203
204struct nexthop *
205nexthop_ifname_add (struct rib *rib, char *ifname)
206{
207 struct nexthop *nexthop;
208
Stephen Hemminger393deb92008-08-18 14:13:29 -0700209 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000210 nexthop->type = NEXTHOP_TYPE_IFNAME;
paula4b70762003-05-16 17:19:48 +0000211 nexthop->ifname = XSTRDUP (0, ifname);
paul718e3742002-12-13 20:15:29 +0000212
213 nexthop_add (rib, nexthop);
214
215 return nexthop;
216}
217
218struct nexthop *
Paul Jakma7514fb72007-05-02 16:05:35 +0000219nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src)
paul718e3742002-12-13 20:15:29 +0000220{
221 struct nexthop *nexthop;
222
Stephen Hemminger393deb92008-08-18 14:13:29 -0700223 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000224 nexthop->type = NEXTHOP_TYPE_IPV4;
225 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000226 if (src)
227 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000228
229 nexthop_add (rib, nexthop);
230
231 return nexthop;
232}
233
paula1ac18c2005-06-28 17:17:12 +0000234static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000235nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
Paul Jakma7514fb72007-05-02 16:05:35 +0000236 struct in_addr *src, unsigned int ifindex)
paul718e3742002-12-13 20:15:29 +0000237{
238 struct nexthop *nexthop;
239
Stephen Hemminger393deb92008-08-18 14:13:29 -0700240 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000241 nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
242 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000243 if (src)
244 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000245 nexthop->ifindex = ifindex;
246
247 nexthop_add (rib, nexthop);
248
249 return nexthop;
250}
251
252#ifdef HAVE_IPV6
253struct nexthop *
254nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
255{
256 struct nexthop *nexthop;
257
Stephen Hemminger393deb92008-08-18 14:13:29 -0700258 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000259 nexthop->type = NEXTHOP_TYPE_IPV6;
260 nexthop->gate.ipv6 = *ipv6;
261
262 nexthop_add (rib, nexthop);
263
264 return nexthop;
265}
266
paula1ac18c2005-06-28 17:17:12 +0000267static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000268nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
269 char *ifname)
270{
271 struct nexthop *nexthop;
272
Stephen Hemminger393deb92008-08-18 14:13:29 -0700273 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000274 nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
275 nexthop->gate.ipv6 = *ipv6;
276 nexthop->ifname = XSTRDUP (0, ifname);
277
278 nexthop_add (rib, nexthop);
279
280 return nexthop;
281}
282
paula1ac18c2005-06-28 17:17:12 +0000283static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000284nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
285 unsigned int ifindex)
286{
287 struct nexthop *nexthop;
288
Stephen Hemminger393deb92008-08-18 14:13:29 -0700289 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000290 nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
291 nexthop->gate.ipv6 = *ipv6;
292 nexthop->ifindex = ifindex;
293
294 nexthop_add (rib, nexthop);
295
296 return nexthop;
297}
298#endif /* HAVE_IPV6 */
299
paul595db7f2003-05-25 21:35:06 +0000300struct nexthop *
301nexthop_blackhole_add (struct rib *rib)
302{
303 struct nexthop *nexthop;
304
Stephen Hemminger393deb92008-08-18 14:13:29 -0700305 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul595db7f2003-05-25 21:35:06 +0000306 nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
307 SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
308
309 nexthop_add (rib, nexthop);
310
311 return nexthop;
312}
313
paul718e3742002-12-13 20:15:29 +0000314/* If force flag is not set, do not modify falgs at all for uninstall
315 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000316static int
paul718e3742002-12-13 20:15:29 +0000317nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
318 struct route_node *top)
319{
320 struct prefix_ipv4 p;
321 struct route_table *table;
322 struct route_node *rn;
323 struct rib *match;
324 struct nexthop *newhop;
325
326 if (nexthop->type == NEXTHOP_TYPE_IPV4)
327 nexthop->ifindex = 0;
328
329 if (set)
330 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
331
332 /* Make lookup prefix. */
333 memset (&p, 0, sizeof (struct prefix_ipv4));
334 p.family = AF_INET;
335 p.prefixlen = IPV4_MAX_PREFIXLEN;
336 p.prefix = nexthop->gate.ipv4;
337
338 /* Lookup table. */
339 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
340 if (! table)
341 return 0;
342
343 rn = route_node_match (table, (struct prefix *) &p);
344 while (rn)
345 {
346 route_unlock_node (rn);
347
David Warda50c1072009-12-03 15:34:39 +0300348 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000349 if (rn == top)
350 return 0;
351
352 /* Pick up selected route. */
353 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100354 {
355 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
356 continue;
357 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
358 break;
359 }
paul718e3742002-12-13 20:15:29 +0000360
361 /* If there is no selected route or matched route is EGP, go up
362 tree. */
363 if (! match
364 || match->type == ZEBRA_ROUTE_BGP)
365 {
366 do {
367 rn = rn->parent;
368 } while (rn && rn->info == NULL);
369 if (rn)
370 route_lock_node (rn);
371 }
372 else
373 {
374 if (match->type == ZEBRA_ROUTE_CONNECT)
375 {
376 /* Directly point connected route. */
377 newhop = match->nexthop;
378 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
379 nexthop->ifindex = newhop->ifindex;
380
381 return 1;
382 }
383 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
384 {
385 for (newhop = match->nexthop; newhop; newhop = newhop->next)
386 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
387 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
388 {
389 if (set)
390 {
391 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
392 nexthop->rtype = newhop->type;
393 if (newhop->type == NEXTHOP_TYPE_IPV4 ||
394 newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
395 nexthop->rgate.ipv4 = newhop->gate.ipv4;
396 if (newhop->type == NEXTHOP_TYPE_IFINDEX
397 || newhop->type == NEXTHOP_TYPE_IFNAME
398 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
399 nexthop->rifindex = newhop->ifindex;
400 }
401 return 1;
402 }
403 return 0;
404 }
405 else
406 {
407 return 0;
408 }
409 }
410 }
411 return 0;
412}
413
414#ifdef HAVE_IPV6
415/* If force flag is not set, do not modify falgs at all for uninstall
416 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000417static int
paul718e3742002-12-13 20:15:29 +0000418nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
419 struct route_node *top)
420{
421 struct prefix_ipv6 p;
422 struct route_table *table;
423 struct route_node *rn;
424 struct rib *match;
425 struct nexthop *newhop;
426
427 if (nexthop->type == NEXTHOP_TYPE_IPV6)
428 nexthop->ifindex = 0;
429
430 if (set)
431 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
432
433 /* Make lookup prefix. */
434 memset (&p, 0, sizeof (struct prefix_ipv6));
435 p.family = AF_INET6;
436 p.prefixlen = IPV6_MAX_PREFIXLEN;
437 p.prefix = nexthop->gate.ipv6;
438
439 /* Lookup table. */
440 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
441 if (! table)
442 return 0;
443
444 rn = route_node_match (table, (struct prefix *) &p);
445 while (rn)
446 {
447 route_unlock_node (rn);
448
David Warda50c1072009-12-03 15:34:39 +0300449 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000450 if (rn == top)
451 return 0;
452
453 /* Pick up selected route. */
454 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100455 {
456 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
457 continue;
458 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
459 break;
460 }
paul718e3742002-12-13 20:15:29 +0000461
462 /* If there is no selected route or matched route is EGP, go up
463 tree. */
464 if (! match
465 || match->type == ZEBRA_ROUTE_BGP)
466 {
467 do {
468 rn = rn->parent;
469 } while (rn && rn->info == NULL);
470 if (rn)
471 route_lock_node (rn);
472 }
473 else
474 {
475 if (match->type == ZEBRA_ROUTE_CONNECT)
476 {
477 /* Directly point connected route. */
478 newhop = match->nexthop;
479
480 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
481 nexthop->ifindex = newhop->ifindex;
482
483 return 1;
484 }
485 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
486 {
487 for (newhop = match->nexthop; newhop; newhop = newhop->next)
488 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
489 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
490 {
491 if (set)
492 {
493 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
494 nexthop->rtype = newhop->type;
495 if (newhop->type == NEXTHOP_TYPE_IPV6
496 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
497 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
498 nexthop->rgate.ipv6 = newhop->gate.ipv6;
499 if (newhop->type == NEXTHOP_TYPE_IFINDEX
500 || newhop->type == NEXTHOP_TYPE_IFNAME
501 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
502 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
503 nexthop->rifindex = newhop->ifindex;
504 }
505 return 1;
506 }
507 return 0;
508 }
509 else
510 {
511 return 0;
512 }
513 }
514 }
515 return 0;
516}
517#endif /* HAVE_IPV6 */
518
519struct rib *
520rib_match_ipv4 (struct in_addr addr)
521{
522 struct prefix_ipv4 p;
523 struct route_table *table;
524 struct route_node *rn;
525 struct rib *match;
526 struct nexthop *newhop;
527
528 /* Lookup table. */
529 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
530 if (! table)
531 return 0;
532
533 memset (&p, 0, sizeof (struct prefix_ipv4));
534 p.family = AF_INET;
535 p.prefixlen = IPV4_MAX_PREFIXLEN;
536 p.prefix = addr;
537
538 rn = route_node_match (table, (struct prefix *) &p);
539
540 while (rn)
541 {
542 route_unlock_node (rn);
543
544 /* Pick up selected route. */
545 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100546 {
547 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
548 continue;
549 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
550 break;
551 }
paul718e3742002-12-13 20:15:29 +0000552
553 /* If there is no selected route or matched route is EGP, go up
554 tree. */
555 if (! match
556 || match->type == ZEBRA_ROUTE_BGP)
557 {
558 do {
559 rn = rn->parent;
560 } while (rn && rn->info == NULL);
561 if (rn)
562 route_lock_node (rn);
563 }
564 else
565 {
566 if (match->type == ZEBRA_ROUTE_CONNECT)
567 /* Directly point connected route. */
568 return match;
569 else
570 {
571 for (newhop = match->nexthop; newhop; newhop = newhop->next)
572 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
573 return match;
574 return NULL;
575 }
576 }
577 }
578 return NULL;
579}
580
581struct rib *
582rib_lookup_ipv4 (struct prefix_ipv4 *p)
583{
584 struct route_table *table;
585 struct route_node *rn;
586 struct rib *match;
587 struct nexthop *nexthop;
588
589 /* Lookup table. */
590 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
591 if (! table)
592 return 0;
593
594 rn = route_node_lookup (table, (struct prefix *) p);
595
596 /* No route for this prefix. */
597 if (! rn)
598 return NULL;
599
600 /* Unlock node. */
601 route_unlock_node (rn);
602
paul718e3742002-12-13 20:15:29 +0000603 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100604 {
605 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
606 continue;
607 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
608 break;
609 }
paul718e3742002-12-13 20:15:29 +0000610
611 if (! match || match->type == ZEBRA_ROUTE_BGP)
612 return NULL;
613
614 if (match->type == ZEBRA_ROUTE_CONNECT)
615 return match;
616
617 for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
618 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
619 return match;
620
621 return NULL;
622}
623
Denis Ovsienkodc958242007-08-13 16:03:06 +0000624/*
625 * This clone function, unlike its original rib_lookup_ipv4(), checks
626 * if specified IPv4 route record (prefix/mask -> gate) exists in
627 * the whole RIB and has ZEBRA_FLAG_SELECTED set.
628 *
629 * Return values:
630 * -1: error
631 * 0: exact match found
632 * 1: a match was found with a different gate
633 * 2: connected route found
634 * 3: no matches found
635 */
636int
637rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
638{
639 struct route_table *table;
640 struct route_node *rn;
641 struct rib *match;
642 struct nexthop *nexthop;
643
644 /* Lookup table. */
645 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
646 if (! table)
647 return ZEBRA_RIB_LOOKUP_ERROR;
648
649 /* Scan the RIB table for exactly matching RIB entry. */
650 rn = route_node_lookup (table, (struct prefix *) p);
651
652 /* No route for this prefix. */
653 if (! rn)
654 return ZEBRA_RIB_NOTFOUND;
655
656 /* Unlock node. */
657 route_unlock_node (rn);
658
659 /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
660 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100661 {
662 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
663 continue;
664 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
665 break;
666 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000667
668 /* None such found :( */
669 if (!match)
670 return ZEBRA_RIB_NOTFOUND;
671
672 if (match->type == ZEBRA_ROUTE_CONNECT)
673 return ZEBRA_RIB_FOUND_CONNECTED;
674
675 /* Ok, we have a cood candidate, let's check it's nexthop list... */
676 for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
677 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
678 {
679 /* We are happy with either direct or recursive hexthop */
680 if (nexthop->gate.ipv4.s_addr == qgate->sin.sin_addr.s_addr ||
681 nexthop->rgate.ipv4.s_addr == qgate->sin.sin_addr.s_addr)
682 return ZEBRA_RIB_FOUND_EXACT;
683 else
684 {
685 if (IS_ZEBRA_DEBUG_RIB)
686 {
687 char gate_buf[INET_ADDRSTRLEN], rgate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
688 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
689 inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, rgate_buf, INET_ADDRSTRLEN);
690 inet_ntop (AF_INET, &qgate->sin.sin_addr.s_addr, qgate_buf, INET_ADDRSTRLEN);
691 zlog_debug ("%s: qgate == %s, gate == %s, rgate == %s", __func__, qgate_buf, gate_buf, rgate_buf);
692 }
693 return ZEBRA_RIB_FOUND_NOGATE;
694 }
695 }
696
697 return ZEBRA_RIB_NOTFOUND;
698}
699
paul718e3742002-12-13 20:15:29 +0000700#ifdef HAVE_IPV6
701struct rib *
702rib_match_ipv6 (struct in6_addr *addr)
703{
704 struct prefix_ipv6 p;
705 struct route_table *table;
706 struct route_node *rn;
707 struct rib *match;
708 struct nexthop *newhop;
709
710 /* Lookup table. */
711 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
712 if (! table)
713 return 0;
714
715 memset (&p, 0, sizeof (struct prefix_ipv6));
716 p.family = AF_INET6;
717 p.prefixlen = IPV6_MAX_PREFIXLEN;
718 IPV6_ADDR_COPY (&p.prefix, addr);
719
720 rn = route_node_match (table, (struct prefix *) &p);
721
722 while (rn)
723 {
724 route_unlock_node (rn);
725
726 /* Pick up selected route. */
727 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100728 {
729 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
730 continue;
731 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
732 break;
733 }
paul718e3742002-12-13 20:15:29 +0000734
735 /* If there is no selected route or matched route is EGP, go up
736 tree. */
737 if (! match
738 || match->type == ZEBRA_ROUTE_BGP)
739 {
740 do {
741 rn = rn->parent;
742 } while (rn && rn->info == NULL);
743 if (rn)
744 route_lock_node (rn);
745 }
746 else
747 {
748 if (match->type == ZEBRA_ROUTE_CONNECT)
749 /* Directly point connected route. */
750 return match;
751 else
752 {
753 for (newhop = match->nexthop; newhop; newhop = newhop->next)
754 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
755 return match;
756 return NULL;
757 }
758 }
759 }
760 return NULL;
761}
762#endif /* HAVE_IPV6 */
763
Paul Jakma7514fb72007-05-02 16:05:35 +0000764#define RIB_SYSTEM_ROUTE(R) \
765 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
766
Denis Ovsienkodc958242007-08-13 16:03:06 +0000767/* This function verifies reachability of one given nexthop, which can be
768 * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
769 * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
770 * nexthop->ifindex will be updated appropriately as well.
771 * An existing route map can turn (otherwise active) nexthop into inactive, but
772 * not vice versa.
773 *
774 * The return value is the final value of 'ACTIVE' flag.
775 */
776
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300777static unsigned
paul718e3742002-12-13 20:15:29 +0000778nexthop_active_check (struct route_node *rn, struct rib *rib,
779 struct nexthop *nexthop, int set)
780{
781 struct interface *ifp;
Paul Jakma7514fb72007-05-02 16:05:35 +0000782 route_map_result_t ret = RMAP_MATCH;
783 extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
784 struct route_map *rmap;
785 int family;
paul718e3742002-12-13 20:15:29 +0000786
Paul Jakma7514fb72007-05-02 16:05:35 +0000787 family = 0;
paul718e3742002-12-13 20:15:29 +0000788 switch (nexthop->type)
789 {
790 case NEXTHOP_TYPE_IFINDEX:
791 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000792 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000793 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
794 else
795 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
796 break;
paul718e3742002-12-13 20:15:29 +0000797 case NEXTHOP_TYPE_IPV6_IFNAME:
Paul Jakma7514fb72007-05-02 16:05:35 +0000798 family = AFI_IP6;
799 case NEXTHOP_TYPE_IFNAME:
paul718e3742002-12-13 20:15:29 +0000800 ifp = if_lookup_by_name (nexthop->ifname);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000801 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000802 {
803 if (set)
804 nexthop->ifindex = ifp->ifindex;
805 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
806 }
807 else
808 {
809 if (set)
810 nexthop->ifindex = 0;
811 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
812 }
813 break;
814 case NEXTHOP_TYPE_IPV4:
815 case NEXTHOP_TYPE_IPV4_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000816 family = AFI_IP;
paul718e3742002-12-13 20:15:29 +0000817 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
818 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
819 else
820 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
821 break;
822#ifdef HAVE_IPV6
823 case NEXTHOP_TYPE_IPV6:
Paul Jakma7514fb72007-05-02 16:05:35 +0000824 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000825 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
826 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
827 else
828 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
829 break;
830 case NEXTHOP_TYPE_IPV6_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000831 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000832 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
833 {
834 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000835 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000836 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
837 else
838 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
839 }
840 else
841 {
842 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
843 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
844 else
845 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
846 }
847 break;
848#endif /* HAVE_IPV6 */
paul595db7f2003-05-25 21:35:06 +0000849 case NEXTHOP_TYPE_BLACKHOLE:
850 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
851 break;
paul718e3742002-12-13 20:15:29 +0000852 default:
853 break;
854 }
Paul Jakma7514fb72007-05-02 16:05:35 +0000855 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
856 return 0;
857
858 if (RIB_SYSTEM_ROUTE(rib) ||
859 (family == AFI_IP && rn->p.family != AF_INET) ||
860 (family == AFI_IP6 && rn->p.family != AF_INET6))
861 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
862
863 rmap = 0;
864 if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
865 proto_rm[family][rib->type])
866 rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
867 if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
868 rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
869 if (rmap) {
870 ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, nexthop);
871 }
872
873 if (ret == RMAP_DENYMATCH)
874 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
paul718e3742002-12-13 20:15:29 +0000875 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
876}
877
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000878/* Iterate over all nexthops of the given RIB entry and refresh their
879 * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
880 * nexthop is found to toggle the ACTIVE flag, the whole rib structure
881 * is flagged with ZEBRA_FLAG_CHANGED. The 4th 'set' argument is
882 * transparently passed to nexthop_active_check().
883 *
884 * Return value is the new number of active nexthops.
885 */
886
paula1ac18c2005-06-28 17:17:12 +0000887static int
paul718e3742002-12-13 20:15:29 +0000888nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
889{
890 struct nexthop *nexthop;
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300891 unsigned int prev_active, prev_index, new_active;
paul718e3742002-12-13 20:15:29 +0000892
893 rib->nexthop_active_num = 0;
894 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
895
896 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000897 {
898 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
Joakim Tjernlundc3a56062009-06-24 19:15:36 +0200899 prev_index = nexthop->ifindex;
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000900 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
901 rib->nexthop_active_num++;
Joakim Tjernlundc3a56062009-06-24 19:15:36 +0200902 if (prev_active != new_active ||
903 prev_index != nexthop->ifindex)
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000904 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
905 }
paul718e3742002-12-13 20:15:29 +0000906 return rib->nexthop_active_num;
907}
paul6baeb982003-10-28 03:47:15 +0000908
paul718e3742002-12-13 20:15:29 +0000909
paul718e3742002-12-13 20:15:29 +0000910
paula1ac18c2005-06-28 17:17:12 +0000911static void
paul718e3742002-12-13 20:15:29 +0000912rib_install_kernel (struct route_node *rn, struct rib *rib)
913{
914 int ret = 0;
915 struct nexthop *nexthop;
916
917 switch (PREFIX_FAMILY (&rn->p))
918 {
919 case AF_INET:
920 ret = kernel_add_ipv4 (&rn->p, rib);
921 break;
922#ifdef HAVE_IPV6
923 case AF_INET6:
924 ret = kernel_add_ipv6 (&rn->p, rib);
925 break;
926#endif /* HAVE_IPV6 */
927 }
928
Denis Ovsienkodc958242007-08-13 16:03:06 +0000929 /* This condition is never met, if we are using rt_socket.c */
paul718e3742002-12-13 20:15:29 +0000930 if (ret < 0)
931 {
932 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
933 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
934 }
935}
936
937/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +0000938static int
paul718e3742002-12-13 20:15:29 +0000939rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
940{
941 int ret = 0;
942 struct nexthop *nexthop;
943
944 switch (PREFIX_FAMILY (&rn->p))
945 {
946 case AF_INET:
947 ret = kernel_delete_ipv4 (&rn->p, rib);
948 break;
949#ifdef HAVE_IPV6
950 case AF_INET6:
951 ret = kernel_delete_ipv6 (&rn->p, rib);
952 break;
953#endif /* HAVE_IPV6 */
954 }
955
956 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
957 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
958
959 return ret;
960}
961
962/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +0000963static void
paul718e3742002-12-13 20:15:29 +0000964rib_uninstall (struct route_node *rn, struct rib *rib)
965{
966 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
967 {
968 redistribute_delete (&rn->p, rib);
969 if (! RIB_SYSTEM_ROUTE (rib))
970 rib_uninstall_kernel (rn, rib);
971 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
972 }
973}
974
Paul Jakma6d691122006-07-27 21:49:00 +0000975static void rib_unlink (struct route_node *, struct rib *);
976
paul718e3742002-12-13 20:15:29 +0000977/* Core function for processing routing information base. */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +0000978static void
979rib_process (struct route_node *rn)
paul718e3742002-12-13 20:15:29 +0000980{
981 struct rib *rib;
982 struct rib *next;
983 struct rib *fib = NULL;
984 struct rib *select = NULL;
Paul Jakma6d691122006-07-27 21:49:00 +0000985 struct rib *del = NULL;
pauld753e9e2003-01-22 19:45:50 +0000986 int installed = 0;
987 struct nexthop *nexthop = NULL;
Denis Ovsienkof304cb42007-10-03 12:27:16 +0000988 char buf[INET6_ADDRSTRLEN];
paul4d38fdb2005-04-28 17:35:14 +0000989
990 assert (rn);
991
Paul Jakma93bdada2007-08-06 19:25:11 +0000992 if (IS_ZEBRA_DEBUG_RIB || IS_ZEBRA_DEBUG_RIB_Q)
Denis Ovsienkof304cb42007-10-03 12:27:16 +0000993 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +0000994
paul718e3742002-12-13 20:15:29 +0000995 for (rib = rn->info; rib; rib = next)
996 {
Denis Ovsienkodc958242007-08-13 16:03:06 +0000997 /* The next pointer is saved, because current pointer
998 * may be passed to rib_unlink() in the middle of iteration.
999 */
paul718e3742002-12-13 20:15:29 +00001000 next = rib->next;
pauld753e9e2003-01-22 19:45:50 +00001001
paul718e3742002-12-13 20:15:29 +00001002 /* Currently installed rib. */
1003 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Paul Jakma6d691122006-07-27 21:49:00 +00001004 {
1005 assert (fib == NULL);
1006 fib = rib;
1007 }
1008
1009 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1010 * which we need to do do further work with below.
1011 */
1012 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1013 {
1014 if (rib != fib)
1015 {
1016 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001017 zlog_debug ("%s: %s/%d: rn %p, removing rib %p", __func__,
1018 buf, rn->p.prefixlen, rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001019 rib_unlink (rn, rib);
1020 }
1021 else
1022 del = rib;
1023
1024 continue;
1025 }
paul4d38fdb2005-04-28 17:35:14 +00001026
paul718e3742002-12-13 20:15:29 +00001027 /* Skip unreachable nexthop. */
1028 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +00001029 continue;
paul718e3742002-12-13 20:15:29 +00001030
1031 /* Infinit distance. */
1032 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +00001033 continue;
paul718e3742002-12-13 20:15:29 +00001034
paulaf887b52006-01-18 14:52:52 +00001035 /* Newly selected rib, the common case. */
1036 if (!select)
1037 {
1038 select = rib;
1039 continue;
1040 }
1041
1042 /* filter route selection in following order:
paulaf887b52006-01-18 14:52:52 +00001043 * - connected beats other types
paula8d9c1f2006-01-25 06:31:04 +00001044 * - lower distance beats higher
paulaf887b52006-01-18 14:52:52 +00001045 * - lower metric beats higher for equal distance
1046 * - last, hence oldest, route wins tie break.
1047 */
paula1038a12006-01-30 14:08:51 +00001048
1049 /* Connected routes. Pick the last connected
1050 * route of the set of lowest metric connected routes.
1051 */
paula8d9c1f2006-01-25 06:31:04 +00001052 if (rib->type == ZEBRA_ROUTE_CONNECT)
1053 {
paula1038a12006-01-30 14:08:51 +00001054 if (select->type != ZEBRA_ROUTE_CONNECT
paula8d9c1f2006-01-25 06:31:04 +00001055 || rib->metric <= select->metric)
paula1038a12006-01-30 14:08:51 +00001056 select = rib;
1057 continue;
paula8d9c1f2006-01-25 06:31:04 +00001058 }
1059 else if (select->type == ZEBRA_ROUTE_CONNECT)
1060 continue;
1061
1062 /* higher distance loses */
1063 if (rib->distance > select->distance)
1064 continue;
1065
1066 /* lower wins */
1067 if (rib->distance < select->distance)
1068 {
paulaf887b52006-01-18 14:52:52 +00001069 select = rib;
paula8d9c1f2006-01-25 06:31:04 +00001070 continue;
1071 }
1072
1073 /* metric tie-breaks equal distance */
1074 if (rib->metric <= select->metric)
1075 select = rib;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001076 } /* for (rib = rn->info; rib; rib = next) */
1077
1078 /* After the cycle is finished, the following pointers will be set:
1079 * select --- the winner RIB entry, if any was found, otherwise NULL
1080 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1081 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1082 * rib --- NULL
1083 */
1084
1085 /* Same RIB entry is selected. Update FIB and finish. */
paul718e3742002-12-13 20:15:29 +00001086 if (select && select == fib)
1087 {
Paul Jakma6d691122006-07-27 21:49:00 +00001088 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001089 zlog_debug ("%s: %s/%d: Updating existing route, select %p, fib %p",
1090 __func__, buf, rn->p.prefixlen, select, fib);
paul718e3742002-12-13 20:15:29 +00001091 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +00001092 {
1093 redistribute_delete (&rn->p, select);
1094 if (! RIB_SYSTEM_ROUTE (select))
1095 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001096
paul4d38fdb2005-04-28 17:35:14 +00001097 /* Set real nexthop. */
1098 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +00001099
paul4d38fdb2005-04-28 17:35:14 +00001100 if (! RIB_SYSTEM_ROUTE (select))
1101 rib_install_kernel (rn, select);
1102 redistribute_add (&rn->p, select);
1103 }
pauld753e9e2003-01-22 19:45:50 +00001104 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001105 {
1106 /* Housekeeping code to deal with
1107 race conditions in kernel with linux
1108 netlink reporting interface up before IPv4 or IPv6 protocol
1109 is ready to add routes.
1110 This makes sure the routes are IN the kernel.
1111 */
pauld753e9e2003-01-22 19:45:50 +00001112
paul4d38fdb2005-04-28 17:35:14 +00001113 for (nexthop = select->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001114 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
paul4d38fdb2005-04-28 17:35:14 +00001115 {
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001116 installed = 1;
1117 break;
paul4d38fdb2005-04-28 17:35:14 +00001118 }
1119 if (! installed)
1120 rib_install_kernel (rn, select);
1121 }
Paul Jakma6d691122006-07-27 21:49:00 +00001122 goto end;
paul718e3742002-12-13 20:15:29 +00001123 }
1124
Denis Ovsienkodc958242007-08-13 16:03:06 +00001125 /* At this point we either haven't found the best RIB entry or it is
1126 * different from what we currently intend to flag with SELECTED. In both
1127 * cases, if a RIB block is present in FIB, it should be withdrawn.
1128 */
paul718e3742002-12-13 20:15:29 +00001129 if (fib)
1130 {
Paul Jakma6d691122006-07-27 21:49:00 +00001131 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001132 zlog_debug ("%s: %s/%d: Removing existing route, fib %p", __func__,
1133 buf, rn->p.prefixlen, fib);
paul718e3742002-12-13 20:15:29 +00001134 redistribute_delete (&rn->p, fib);
1135 if (! RIB_SYSTEM_ROUTE (fib))
1136 rib_uninstall_kernel (rn, fib);
1137 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1138
1139 /* Set real nexthop. */
1140 nexthop_active_update (rn, fib, 1);
1141 }
1142
Denis Ovsienkodc958242007-08-13 16:03:06 +00001143 /* Regardless of some RIB entry being SELECTED or not before, now we can
1144 * tell, that if a new winner exists, FIB is still not updated with this
1145 * data, but ready to be.
1146 */
paul718e3742002-12-13 20:15:29 +00001147 if (select)
1148 {
Paul Jakma6d691122006-07-27 21:49:00 +00001149 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001150 zlog_debug ("%s: %s/%d: Adding route, select %p", __func__, buf,
1151 rn->p.prefixlen, select);
paul718e3742002-12-13 20:15:29 +00001152 /* Set real nexthop. */
1153 nexthop_active_update (rn, select, 1);
1154
1155 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001156 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001157 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1158 redistribute_add (&rn->p, select);
1159 }
paul4d38fdb2005-04-28 17:35:14 +00001160
Paul Jakma6d691122006-07-27 21:49:00 +00001161 /* FIB route was removed, should be deleted */
1162 if (del)
1163 {
1164 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001165 zlog_debug ("%s: %s/%d: Deleting fib %p, rn %p", __func__, buf,
1166 rn->p.prefixlen, del, rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001167 rib_unlink (rn, del);
1168 }
paul4d38fdb2005-04-28 17:35:14 +00001169
Paul Jakma6d691122006-07-27 21:49:00 +00001170end:
1171 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma93bdada2007-08-06 19:25:11 +00001172 zlog_debug ("%s: %s/%d: rn %p dequeued", __func__, buf, rn->p.prefixlen, rn);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001173}
1174
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001175/* Take a list of route_node structs and return 1, if there was a record
1176 * picked from it and processed by rib_process(). Don't process more,
1177 * than one RN record; operate only in the specified sub-queue.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001178 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001179static unsigned int
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001180process_subq (struct list * subq, u_char qindex)
1181{
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001182 struct listnode *lnode = listhead (subq);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001183 struct route_node *rnode;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001184
1185 if (!lnode)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001186 return 0;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001187
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001188 rnode = listgetdata (lnode);
1189 rib_process (rnode);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001190
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001191 if (rnode->info) /* The first RIB record is holding the flags bitmask. */
1192 UNSET_FLAG (((struct rib *)rnode->info)->rn_status, RIB_ROUTE_QUEUED(qindex));
Chris Caputo67b94672009-07-18 04:02:26 +00001193#if 0
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001194 else
1195 {
1196 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1197 __func__, rnode, rnode->lock);
1198 zlog_backtrace(LOG_DEBUG);
1199 }
Chris Caputo67b94672009-07-18 04:02:26 +00001200#endif
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001201 route_unlock_node (rnode);
1202 list_delete_node (subq, lnode);
1203 return 1;
1204}
1205
1206/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1207 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1208 * is pointed to the meta queue structure.
1209 */
1210static wq_item_status
1211meta_queue_process (struct work_queue *dummy, void *data)
1212{
1213 struct meta_queue * mq = data;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001214 unsigned i;
1215
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001216 for (i = 0; i < MQ_SIZE; i++)
1217 if (process_subq (mq->subq[i], i))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001218 {
1219 mq->size--;
1220 break;
1221 }
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001222 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1223}
1224
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001225/* Map from rib types to queue type (priority) in meta queue */
1226static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
1227 [ZEBRA_ROUTE_SYSTEM] = 4,
1228 [ZEBRA_ROUTE_KERNEL] = 0,
1229 [ZEBRA_ROUTE_CONNECT] = 0,
1230 [ZEBRA_ROUTE_STATIC] = 1,
1231 [ZEBRA_ROUTE_RIP] = 2,
1232 [ZEBRA_ROUTE_RIPNG] = 2,
1233 [ZEBRA_ROUTE_OSPF] = 2,
1234 [ZEBRA_ROUTE_OSPF6] = 2,
1235 [ZEBRA_ROUTE_ISIS] = 2,
1236 [ZEBRA_ROUTE_BGP] = 3,
1237 [ZEBRA_ROUTE_HSLS] = 4,
1238};
1239
1240/* Look into the RN and queue it into one or more priority queues,
1241 * increasing the size for each data push done.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001242 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001243static void
1244rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001245{
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001246 struct rib *rib;
1247 char buf[INET6_ADDRSTRLEN];
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001248
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001249 if (IS_ZEBRA_DEBUG_RIB_Q)
1250 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001251
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001252 for (rib = rn->info; rib; rib = rib->next)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001253 {
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001254 u_char qindex = meta_queue_map[rib->type];
1255
1256 /* Invariant: at this point we always have rn->info set. */
1257 if (CHECK_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED(qindex)))
1258 {
1259 if (IS_ZEBRA_DEBUG_RIB_Q)
1260 zlog_debug ("%s: %s/%d: rn %p is already queued in sub-queue %u",
1261 __func__, buf, rn->p.prefixlen, rn, qindex);
1262 continue;
1263 }
1264
1265 SET_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED(qindex));
1266 listnode_add (mq->subq[qindex], rn);
1267 route_lock_node (rn);
1268 mq->size++;
1269
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001270 if (IS_ZEBRA_DEBUG_RIB_Q)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001271 zlog_debug ("%s: %s/%d: queued rn %p into sub-queue %u",
1272 __func__, buf, rn->p.prefixlen, rn, qindex);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001273 }
paul4d38fdb2005-04-28 17:35:14 +00001274}
1275
Paul Jakma6d691122006-07-27 21:49:00 +00001276/* Add route_node to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001277static void
Paul Jakma6d691122006-07-27 21:49:00 +00001278rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
paul4d38fdb2005-04-28 17:35:14 +00001279{
paul4d38fdb2005-04-28 17:35:14 +00001280
Paul Jakma93bdada2007-08-06 19:25:11 +00001281 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma6d691122006-07-27 21:49:00 +00001282 {
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001283 char buf[INET6_ADDRSTRLEN];
1284
1285 zlog_info ("%s: %s/%d: work queue added", __func__,
1286 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN),
1287 rn->p.prefixlen);
Paul Jakma6d691122006-07-27 21:49:00 +00001288 }
paul4d38fdb2005-04-28 17:35:14 +00001289
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001290 /*
1291 * The RIB queue should normally be either empty or holding the only
1292 * work_queue_item element. In the latter case this element would
1293 * hold a pointer to the meta queue structure, which must be used to
1294 * actually queue the route nodes to process. So create the MQ
1295 * holder, if necessary, then push the work into it in any case.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001296 * This semantics was introduced after 0.99.9 release.
1297 */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001298 if (!zebra->ribq->items->count)
1299 work_queue_add (zebra->ribq, zebra->mq);
1300
1301 rib_meta_queue_add (zebra->mq, rn);
paul4d38fdb2005-04-28 17:35:14 +00001302}
1303
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001304/* Create new meta queue.
1305 A destructor function doesn't seem to be necessary here.
1306 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001307static struct meta_queue *
1308meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001309{
1310 struct meta_queue *new;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001311 unsigned i;
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001312
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001313 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1314 assert(new);
1315
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001316 for (i = 0; i < MQ_SIZE; i++)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001317 {
1318 new->subq[i] = list_new ();
1319 assert(new->subq[i]);
1320 }
1321
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001322 return new;
1323}
1324
paul4d38fdb2005-04-28 17:35:14 +00001325/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001326static void
paul4d38fdb2005-04-28 17:35:14 +00001327rib_queue_init (struct zebra_t *zebra)
1328{
paul4d38fdb2005-04-28 17:35:14 +00001329 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001330 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001331 {
Paul Jakma6d691122006-07-27 21:49:00 +00001332 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001333 return;
1334 }
1335
1336 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001337 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001338 zebra->ribq->spec.errorfunc = NULL;
paul4d38fdb2005-04-28 17:35:14 +00001339 /* XXX: TODO: These should be runtime configurable via vty */
1340 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001341 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001342
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001343 if (!(zebra->mq = meta_queue_new ()))
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001344 zlog_err ("%s: could not initialise meta queue!", __func__);
paul718e3742002-12-13 20:15:29 +00001345}
1346
Paul Jakma6d691122006-07-27 21:49:00 +00001347/* RIB updates are processed via a queue of pointers to route_nodes.
1348 *
1349 * The queue length is bounded by the maximal size of the routing table,
1350 * as a route_node will not be requeued, if already queued.
1351 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001352 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1353 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1354 * and then submit route_node to queue for best-path selection later.
1355 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001356 *
1357 * Deleted RIBs are reaped during best-path selection.
1358 *
1359 * rib_addnode
1360 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001361 * |-------->| | best RIB, if required
1362 * | |
1363 * static_install->|->rib_addqueue...... -> rib_process
1364 * | |
1365 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001366 * |-> set RIB_ENTRY_REMOVE |
1367 * rib_delnode (RIB freed)
1368 *
1369 *
1370 * Queueing state for a route_node is kept in the head RIB entry, this
1371 * state must be preserved as and when the head RIB entry of a
1372 * route_node is changed by rib_unlink / rib_link. A small complication,
1373 * but saves having to allocate a dedicated object for this.
1374 *
1375 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1376 *
1377 * - route_nodes: refcounted by:
1378 * - RIBs attached to route_node:
1379 * - managed by: rib_link/unlink
1380 * - route_node processing queue
1381 * - managed by: rib_addqueue, rib_process.
1382 *
1383 */
1384
paul718e3742002-12-13 20:15:29 +00001385/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001386static void
Paul Jakma6d691122006-07-27 21:49:00 +00001387rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001388{
1389 struct rib *head;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001390 char buf[INET6_ADDRSTRLEN];
paul4d38fdb2005-04-28 17:35:14 +00001391
1392 assert (rib && rn);
1393
Paul Jakma6d691122006-07-27 21:49:00 +00001394 route_lock_node (rn); /* rn route table reference */
1395
1396 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001397 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001398 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001399 zlog_debug ("%s: %s/%d: rn %p, rib %p", __func__,
1400 buf, rn->p.prefixlen, rn, rib);
1401 }
Paul Jakma6d691122006-07-27 21:49:00 +00001402
paul718e3742002-12-13 20:15:29 +00001403 head = rn->info;
1404 if (head)
Paul Jakma6d691122006-07-27 21:49:00 +00001405 {
1406 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001407 zlog_debug ("%s: %s/%d: new head, rn_status copied over", __func__,
1408 buf, rn->p.prefixlen);
Paul Jakma6d691122006-07-27 21:49:00 +00001409 head->prev = rib;
1410 /* Transfer the rn status flags to the new head RIB */
1411 rib->rn_status = head->rn_status;
1412 }
paul718e3742002-12-13 20:15:29 +00001413 rib->next = head;
1414 rn->info = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001415 rib_queue_add (&zebrad, rn);
1416}
1417
1418static void
1419rib_addnode (struct route_node *rn, struct rib *rib)
1420{
1421 /* RIB node has been un-removed before route-node is processed.
1422 * route_node must hence already be on the queue for processing..
1423 */
1424 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1425 {
1426 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001427 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001428 char buf[INET6_ADDRSTRLEN];
1429 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001430 zlog_debug ("%s: %s/%d: rn %p, un-removed rib %p",
1431 __func__, buf, rn->p.prefixlen, rn, rib);
1432 }
Paul Jakma6d691122006-07-27 21:49:00 +00001433 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1434 return;
1435 }
1436 rib_link (rn, rib);
1437}
1438
1439static void
1440rib_unlink (struct route_node *rn, struct rib *rib)
1441{
1442 struct nexthop *nexthop, *next;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001443 char buf[INET6_ADDRSTRLEN];
Paul Jakma6d691122006-07-27 21:49:00 +00001444
1445 assert (rn && rib);
1446
1447 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001448 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001449 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001450 zlog_debug ("%s: %s/%d: rn %p, rib %p",
1451 __func__, buf, rn->p.prefixlen, rn, rib);
1452 }
Paul Jakma6d691122006-07-27 21:49:00 +00001453
1454 if (rib->next)
1455 rib->next->prev = rib->prev;
1456
1457 if (rib->prev)
1458 rib->prev->next = rib->next;
1459 else
1460 {
1461 rn->info = rib->next;
1462
1463 if (rn->info)
1464 {
1465 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001466 zlog_debug ("%s: %s/%d: rn %p, rib %p, new head copy",
1467 __func__, buf, rn->p.prefixlen, rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001468 rib->next->rn_status = rib->rn_status;
1469 }
1470 }
1471
1472 /* free RIB and nexthops */
1473 for (nexthop = rib->nexthop; nexthop; nexthop = next)
1474 {
1475 next = nexthop->next;
1476 nexthop_free (nexthop);
1477 }
1478 XFREE (MTYPE_RIB, rib);
1479
1480 route_unlock_node (rn); /* rn route table reference */
paul718e3742002-12-13 20:15:29 +00001481}
1482
paula1ac18c2005-06-28 17:17:12 +00001483static void
paul718e3742002-12-13 20:15:29 +00001484rib_delnode (struct route_node *rn, struct rib *rib)
1485{
Paul Jakma6d691122006-07-27 21:49:00 +00001486 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001487 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001488 char buf[INET6_ADDRSTRLEN];
1489 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001490 zlog_debug ("%s: %s/%d: rn %p, rib %p, removing", __func__,
1491 buf, rn->p.prefixlen, rn, rib);
1492 }
Paul Jakma6d691122006-07-27 21:49:00 +00001493 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1494 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001495}
1496
1497int
1498rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001499 struct in_addr *gate, struct in_addr *src,
1500 unsigned int ifindex, u_int32_t vrf_id,
G.Balajicddf3912011-11-26 21:59:32 +04001501 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001502{
1503 struct rib *rib;
1504 struct rib *same = NULL;
1505 struct route_table *table;
1506 struct route_node *rn;
1507 struct nexthop *nexthop;
1508
1509 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04001510 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00001511 if (! table)
1512 return 0;
1513
1514 /* Make it sure prefixlen is applied to the prefix. */
1515 apply_mask_ipv4 (p);
1516
1517 /* Set default distance by route type. */
1518 if (distance == 0)
1519 {
David Lamparter7052f222009-08-27 00:28:28 +02001520 if ((unsigned)type >= sizeof(route_info) / sizeof(route_info[0]))
1521 distance = 150;
1522 else
1523 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00001524
1525 /* iBGP distance is 200. */
1526 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1527 distance = 200;
1528 }
1529
1530 /* Lookup route node.*/
1531 rn = route_node_get (table, (struct prefix *) p);
1532
1533 /* If same type of route are installed, treat it as a implicit
1534 withdraw. */
1535 for (rib = rn->info; rib; rib = rib->next)
1536 {
Paul Jakma6d691122006-07-27 21:49:00 +00001537 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1538 continue;
1539
hassoebf1ead2005-09-21 14:58:20 +00001540 if (rib->type != type)
1541 continue;
1542 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001543 {
1544 same = rib;
1545 break;
1546 }
hassoebf1ead2005-09-21 14:58:20 +00001547 /* Duplicate connected route comes in. */
1548 else if ((nexthop = rib->nexthop) &&
1549 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001550 nexthop->ifindex == ifindex &&
1551 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001552 {
1553 rib->refcnt++;
1554 return 0 ;
1555 }
paul718e3742002-12-13 20:15:29 +00001556 }
1557
1558 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001559 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001560 rib->type = type;
1561 rib->distance = distance;
1562 rib->flags = flags;
1563 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001564 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001565 rib->nexthop_num = 0;
1566 rib->uptime = time (NULL);
1567
1568 /* Nexthop settings. */
1569 if (gate)
1570 {
1571 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001572 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001573 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001574 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001575 }
1576 else
1577 nexthop_ifindex_add (rib, ifindex);
1578
1579 /* If this route is kernel route, set FIB flag to the route. */
1580 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1581 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1582 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1583
1584 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001585 if (IS_ZEBRA_DEBUG_RIB)
1586 zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
paul718e3742002-12-13 20:15:29 +00001587 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001588
paul718e3742002-12-13 20:15:29 +00001589 /* Free implicit route.*/
1590 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001591 {
1592 if (IS_ZEBRA_DEBUG_RIB)
1593 zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001594 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001595 }
paul4d38fdb2005-04-28 17:35:14 +00001596
1597 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001598 return 0;
1599}
1600
Denis Ovsienkodc958242007-08-13 16:03:06 +00001601/* This function dumps the contents of a given RIB entry into
1602 * standard debug log. Calling function name and IP prefix in
1603 * question are passed as 1st and 2nd arguments.
1604 */
1605
1606void rib_dump (const char * func, const struct prefix_ipv4 * p, const struct rib * rib)
1607{
1608 char straddr1[INET_ADDRSTRLEN], straddr2[INET_ADDRSTRLEN];
1609 struct nexthop *nexthop;
1610
1611 inet_ntop (AF_INET, &p->prefix, straddr1, INET_ADDRSTRLEN);
1612 zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr1, p->prefixlen);
1613 zlog_debug
1614 (
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001615 "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
Denis Ovsienkodc958242007-08-13 16:03:06 +00001616 func,
1617 rib->refcnt,
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001618 (unsigned long) rib->uptime,
Denis Ovsienkodc958242007-08-13 16:03:06 +00001619 rib->type,
1620 rib->table
1621 );
1622 zlog_debug
1623 (
1624 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1625 func,
1626 rib->metric,
1627 rib->distance,
1628 rib->flags,
1629 rib->status
1630 );
1631 zlog_debug
1632 (
1633 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1634 func,
1635 rib->nexthop_num,
1636 rib->nexthop_active_num,
1637 rib->nexthop_fib_num
1638 );
1639 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1640 {
1641 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, straddr1, INET_ADDRSTRLEN);
1642 inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, straddr2, INET_ADDRSTRLEN);
1643 zlog_debug
1644 (
1645 "%s: NH %s (%s) with flags %s%s%s",
1646 func,
1647 straddr1,
1648 straddr2,
1649 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1650 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1651 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1652 );
1653 }
1654 zlog_debug ("%s: dump complete", func);
1655}
1656
1657/* This is an exported helper to rtm_read() to dump the strange
1658 * RIB entry found by rib_lookup_ipv4_route()
1659 */
1660
1661void rib_lookup_and_dump (struct prefix_ipv4 * p)
1662{
1663 struct route_table *table;
1664 struct route_node *rn;
1665 struct rib *rib;
1666 char prefix_buf[INET_ADDRSTRLEN];
1667
1668 /* Lookup table. */
1669 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1670 if (! table)
1671 {
1672 zlog_err ("%s: vrf_table() returned NULL", __func__);
1673 return;
1674 }
1675
1676 inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
1677 /* Scan the RIB table for exactly matching RIB entry. */
1678 rn = route_node_lookup (table, (struct prefix *) p);
1679
1680 /* No route for this prefix. */
1681 if (! rn)
1682 {
1683 zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
1684 return;
1685 }
1686
1687 /* Unlock node. */
1688 route_unlock_node (rn);
1689
1690 /* let's go */
1691 for (rib = rn->info; rib; rib = rib->next)
1692 {
1693 zlog_debug
1694 (
1695 "%s: rn %p, rib %p: %s, %s",
1696 __func__,
1697 rn,
1698 rib,
1699 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
1700 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
1701 );
1702 rib_dump (__func__, p, rib);
1703 }
1704}
1705
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001706/* Check if requested address assignment will fail due to another
1707 * route being installed by zebra in FIB already. Take necessary
1708 * actions, if needed: remove such a route from FIB and deSELECT
1709 * corresponding RIB entry. Then put affected RN into RIBQ head.
1710 */
1711void rib_lookup_and_pushup (struct prefix_ipv4 * p)
1712{
1713 struct route_table *table;
1714 struct route_node *rn;
1715 struct rib *rib;
1716 unsigned changed = 0;
1717
1718 if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
1719 {
1720 zlog_err ("%s: vrf_table() returned NULL", __func__);
1721 return;
1722 }
1723
1724 /* No matches would be the simplest case. */
1725 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
1726 return;
1727
1728 /* Unlock node. */
1729 route_unlock_node (rn);
1730
1731 /* Check all RIB entries. In case any changes have to be done, requeue
1732 * the RN into RIBQ head. If the routing message about the new connected
1733 * route (generated by the IP address we are going to assign very soon)
1734 * comes before the RIBQ is processed, the new RIB entry will join
1735 * RIBQ record already on head. This is necessary for proper revalidation
1736 * of the rest of the RIB.
1737 */
1738 for (rib = rn->info; rib; rib = rib->next)
1739 {
1740 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
1741 ! RIB_SYSTEM_ROUTE (rib))
1742 {
1743 changed = 1;
1744 if (IS_ZEBRA_DEBUG_RIB)
1745 {
1746 char buf[INET_ADDRSTRLEN];
1747 inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
1748 zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
1749 rib_dump (__func__, (struct prefix_ipv4 *)&rn->p, rib);
1750 }
1751 rib_uninstall (rn, rib);
1752 }
1753 }
1754 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001755 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001756}
1757
paul718e3742002-12-13 20:15:29 +00001758int
G.Balajicddf3912011-11-26 21:59:32 +04001759rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001760{
1761 struct route_table *table;
1762 struct route_node *rn;
1763 struct rib *same;
1764 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00001765
paul718e3742002-12-13 20:15:29 +00001766 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04001767 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00001768 if (! table)
1769 return 0;
G.Balajicddf3912011-11-26 21:59:32 +04001770
paul718e3742002-12-13 20:15:29 +00001771 /* Make it sure prefixlen is applied to the prefix. */
1772 apply_mask_ipv4 (p);
1773
1774 /* Set default distance by route type. */
1775 if (rib->distance == 0)
1776 {
1777 rib->distance = route_info[rib->type].distance;
1778
1779 /* iBGP distance is 200. */
1780 if (rib->type == ZEBRA_ROUTE_BGP
1781 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1782 rib->distance = 200;
1783 }
1784
1785 /* Lookup route node.*/
1786 rn = route_node_get (table, (struct prefix *) p);
1787
1788 /* If same type of route are installed, treat it as a implicit
1789 withdraw. */
1790 for (same = rn->info; same; same = same->next)
1791 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00001792 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00001793 continue;
1794
paul718e3742002-12-13 20:15:29 +00001795 if (same->type == rib->type && same->table == rib->table
1796 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001797 break;
paul718e3742002-12-13 20:15:29 +00001798 }
paul4d38fdb2005-04-28 17:35:14 +00001799
paul718e3742002-12-13 20:15:29 +00001800 /* If this route is kernel route, set FIB flag to the route. */
1801 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
1802 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1803 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1804
1805 /* Link new rib to node.*/
1806 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001807 if (IS_ZEBRA_DEBUG_RIB)
1808 {
1809 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
1810 __func__, rn, rib);
1811 rib_dump (__func__, p, rib);
1812 }
paul718e3742002-12-13 20:15:29 +00001813
paul718e3742002-12-13 20:15:29 +00001814 /* Free implicit route.*/
1815 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001816 {
1817 if (IS_ZEBRA_DEBUG_RIB)
1818 {
1819 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
1820 __func__, rn, same);
1821 rib_dump (__func__, p, same);
1822 }
paul4d38fdb2005-04-28 17:35:14 +00001823 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001824 }
paul4d38fdb2005-04-28 17:35:14 +00001825
1826 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001827 return 0;
1828}
1829
hassoebf1ead2005-09-21 14:58:20 +00001830/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00001831int
1832rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
G.Balajicddf3912011-11-26 21:59:32 +04001833 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001834{
1835 struct route_table *table;
1836 struct route_node *rn;
1837 struct rib *rib;
1838 struct rib *fib = NULL;
1839 struct rib *same = NULL;
1840 struct nexthop *nexthop;
Stephen Hemminger81cce012009-04-28 14:28:00 -07001841 char buf1[INET_ADDRSTRLEN];
1842 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00001843
1844 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04001845 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00001846 if (! table)
1847 return 0;
1848
1849 /* Apply mask. */
1850 apply_mask_ipv4 (p);
1851
paul5ec90d22003-06-19 01:41:37 +00001852 if (IS_ZEBRA_DEBUG_KERNEL && gate)
ajsb6178002004-12-07 21:12:56 +00001853 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001854 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul5ec90d22003-06-19 01:41:37 +00001855 p->prefixlen,
1856 inet_ntoa (*gate),
1857 ifindex);
1858
paul718e3742002-12-13 20:15:29 +00001859 /* Lookup route node. */
1860 rn = route_node_lookup (table, (struct prefix *) p);
1861 if (! rn)
1862 {
1863 if (IS_ZEBRA_DEBUG_KERNEL)
1864 {
1865 if (gate)
ajsb6178002004-12-07 21:12:56 +00001866 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001867 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001868 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07001869 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001870 ifindex);
1871 else
ajsb6178002004-12-07 21:12:56 +00001872 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001873 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001874 p->prefixlen,
1875 ifindex);
1876 }
1877 return ZEBRA_ERR_RTNOEXIST;
1878 }
1879
1880 /* Lookup same type route. */
1881 for (rib = rn->info; rib; rib = rib->next)
1882 {
Paul Jakma6d691122006-07-27 21:49:00 +00001883 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1884 continue;
1885
paul718e3742002-12-13 20:15:29 +00001886 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1887 fib = rib;
1888
hassoebf1ead2005-09-21 14:58:20 +00001889 if (rib->type != type)
1890 continue;
1891 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04001892 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00001893 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04001894 if (nexthop->ifindex != ifindex)
1895 continue;
hassoebf1ead2005-09-21 14:58:20 +00001896 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00001897 {
hassoebf1ead2005-09-21 14:58:20 +00001898 rib->refcnt--;
1899 route_unlock_node (rn);
1900 route_unlock_node (rn);
1901 return 0;
paul718e3742002-12-13 20:15:29 +00001902 }
hassoebf1ead2005-09-21 14:58:20 +00001903 same = rib;
1904 break;
paul718e3742002-12-13 20:15:29 +00001905 }
hassoebf1ead2005-09-21 14:58:20 +00001906 /* Make sure that the route found has the same gateway. */
1907 else if (gate == NULL ||
1908 ((nexthop = rib->nexthop) &&
1909 (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
1910 IPV4_ADDR_SAME (&nexthop->rgate.ipv4, gate))))
paul5ec90d22003-06-19 01:41:37 +00001911 {
hassoebf1ead2005-09-21 14:58:20 +00001912 same = rib;
1913 break;
paul718e3742002-12-13 20:15:29 +00001914 }
1915 }
1916
1917 /* If same type of route can't be found and this message is from
1918 kernel. */
1919 if (! same)
1920 {
1921 if (fib && type == ZEBRA_ROUTE_KERNEL)
1922 {
1923 /* Unset flags. */
1924 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1925 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1926
1927 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1928 }
1929 else
1930 {
1931 if (IS_ZEBRA_DEBUG_KERNEL)
1932 {
1933 if (gate)
ajsb6178002004-12-07 21:12:56 +00001934 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001935 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001936 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07001937 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001938 ifindex,
1939 type);
1940 else
ajsb6178002004-12-07 21:12:56 +00001941 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001942 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001943 p->prefixlen,
1944 ifindex,
1945 type);
1946 }
1947 route_unlock_node (rn);
1948 return ZEBRA_ERR_RTNOEXIST;
1949 }
1950 }
paul4d38fdb2005-04-28 17:35:14 +00001951
paul718e3742002-12-13 20:15:29 +00001952 if (same)
1953 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00001954
paul718e3742002-12-13 20:15:29 +00001955 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001956 return 0;
1957}
1958
1959/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00001960static void
paul718e3742002-12-13 20:15:29 +00001961static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
1962{
1963 struct rib *rib;
1964 struct route_node *rn;
1965 struct route_table *table;
1966
1967 /* Lookup table. */
1968 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1969 if (! table)
1970 return;
1971
1972 /* Lookup existing route */
1973 rn = route_node_get (table, p);
1974 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00001975 {
1976 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1977 continue;
1978
1979 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1980 break;
1981 }
paul718e3742002-12-13 20:15:29 +00001982
1983 if (rib)
1984 {
1985 /* Same distance static route is there. Update it with new
1986 nexthop. */
paul718e3742002-12-13 20:15:29 +00001987 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001988 switch (si->type)
paul7021c422003-07-15 12:52:22 +00001989 {
1990 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00001991 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00001992 break;
1993 case STATIC_IPV4_IFNAME:
1994 nexthop_ifname_add (rib, si->gate.ifname);
1995 break;
1996 case STATIC_IPV4_BLACKHOLE:
1997 nexthop_blackhole_add (rib);
1998 break;
paul4d38fdb2005-04-28 17:35:14 +00001999 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002000 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002001 }
2002 else
2003 {
2004 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002005 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2006
paul718e3742002-12-13 20:15:29 +00002007 rib->type = ZEBRA_ROUTE_STATIC;
2008 rib->distance = si->distance;
2009 rib->metric = 0;
2010 rib->nexthop_num = 0;
2011
2012 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002013 {
2014 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002015 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002016 break;
2017 case STATIC_IPV4_IFNAME:
2018 nexthop_ifname_add (rib, si->gate.ifname);
2019 break;
2020 case STATIC_IPV4_BLACKHOLE:
2021 nexthop_blackhole_add (rib);
2022 break;
2023 }
paul718e3742002-12-13 20:15:29 +00002024
hasso81dfcaa2003-05-25 19:21:25 +00002025 /* Save the flags of this static routes (reject, blackhole) */
2026 rib->flags = si->flags;
2027
paul718e3742002-12-13 20:15:29 +00002028 /* Link this rib to the tree. */
2029 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002030 }
2031}
2032
paula1ac18c2005-06-28 17:17:12 +00002033static int
paul718e3742002-12-13 20:15:29 +00002034static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2035{
2036 if (nexthop->type == NEXTHOP_TYPE_IPV4
2037 && si->type == STATIC_IPV4_GATEWAY
2038 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2039 return 1;
2040 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2041 && si->type == STATIC_IPV4_IFNAME
2042 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2043 return 1;
paul595db7f2003-05-25 21:35:06 +00002044 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2045 && si->type == STATIC_IPV4_BLACKHOLE)
2046 return 1;
paule8e19462006-01-19 20:16:55 +00002047 return 0;
paul718e3742002-12-13 20:15:29 +00002048}
2049
2050/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002051static void
paul718e3742002-12-13 20:15:29 +00002052static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
2053{
2054 struct route_node *rn;
2055 struct rib *rib;
2056 struct nexthop *nexthop;
2057 struct route_table *table;
2058
2059 /* Lookup table. */
2060 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2061 if (! table)
2062 return;
paul4d38fdb2005-04-28 17:35:14 +00002063
paul718e3742002-12-13 20:15:29 +00002064 /* Lookup existing route with type and distance. */
2065 rn = route_node_lookup (table, p);
2066 if (! rn)
2067 return;
2068
2069 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002070 {
2071 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2072 continue;
2073
2074 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2075 break;
2076 }
paul718e3742002-12-13 20:15:29 +00002077
2078 if (! rib)
2079 {
2080 route_unlock_node (rn);
2081 return;
2082 }
2083
2084 /* Lookup nexthop. */
2085 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2086 if (static_ipv4_nexthop_same (nexthop, si))
2087 break;
2088
2089 /* Can't find nexthop. */
2090 if (! nexthop)
2091 {
2092 route_unlock_node (rn);
2093 return;
2094 }
2095
2096 /* Check nexthop. */
2097 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002098 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002099 else
2100 {
paul6baeb982003-10-28 03:47:15 +00002101 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2102 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002103 nexthop_delete (rib, nexthop);
2104 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002105 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002106 }
paul718e3742002-12-13 20:15:29 +00002107 /* Unlock node. */
2108 route_unlock_node (rn);
2109}
2110
2111/* Add static route into static route configuration. */
2112int
hasso39db97e2004-10-12 20:50:58 +00002113static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00002114 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002115{
2116 u_char type = 0;
2117 struct route_node *rn;
2118 struct static_ipv4 *si;
2119 struct static_ipv4 *pp;
2120 struct static_ipv4 *cp;
2121 struct static_ipv4 *update = NULL;
2122 struct route_table *stable;
2123
2124 /* Lookup table. */
2125 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2126 if (! stable)
2127 return -1;
2128
2129 /* Lookup static route prefix. */
2130 rn = route_node_get (stable, p);
2131
2132 /* Make flags. */
2133 if (gate)
2134 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002135 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002136 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002137 else
2138 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002139
2140 /* Do nothing if there is a same static route. */
2141 for (si = rn->info; si; si = si->next)
2142 {
2143 if (type == si->type
2144 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2145 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2146 {
2147 if (distance == si->distance)
2148 {
2149 route_unlock_node (rn);
2150 return 0;
2151 }
2152 else
2153 update = si;
2154 }
2155 }
2156
Paul Jakma3c0755d2006-12-08 00:53:14 +00002157 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002158 if (update)
2159 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
2160
2161 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002162 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
paul718e3742002-12-13 20:15:29 +00002163
2164 si->type = type;
2165 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002166 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002167
2168 if (gate)
2169 si->gate.ipv4 = *gate;
2170 if (ifname)
2171 si->gate.ifname = XSTRDUP (0, ifname);
2172
2173 /* Add new static route information to the tree with sort by
2174 distance value and gateway address. */
2175 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2176 {
2177 if (si->distance < cp->distance)
2178 break;
2179 if (si->distance > cp->distance)
2180 continue;
2181 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2182 {
2183 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2184 break;
2185 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2186 continue;
2187 }
2188 }
2189
2190 /* Make linked list. */
2191 if (pp)
2192 pp->next = si;
2193 else
2194 rn->info = si;
2195 if (cp)
2196 cp->prev = si;
2197 si->prev = pp;
2198 si->next = cp;
2199
2200 /* Install into rib. */
2201 static_install_ipv4 (p, si);
2202
2203 return 1;
2204}
2205
2206/* Delete static route from static route configuration. */
2207int
hasso39db97e2004-10-12 20:50:58 +00002208static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00002209 u_char distance, u_int32_t vrf_id)
2210{
2211 u_char type = 0;
2212 struct route_node *rn;
2213 struct static_ipv4 *si;
2214 struct route_table *stable;
2215
2216 /* Lookup table. */
2217 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2218 if (! stable)
2219 return -1;
2220
2221 /* Lookup static route prefix. */
2222 rn = route_node_lookup (stable, p);
2223 if (! rn)
2224 return 0;
2225
2226 /* Make flags. */
2227 if (gate)
2228 type = STATIC_IPV4_GATEWAY;
2229 else if (ifname)
2230 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002231 else
2232 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002233
2234 /* Find same static route is the tree */
2235 for (si = rn->info; si; si = si->next)
2236 if (type == si->type
2237 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2238 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2239 break;
2240
2241 /* Can't find static route. */
2242 if (! si)
2243 {
2244 route_unlock_node (rn);
2245 return 0;
2246 }
2247
2248 /* Install into rib. */
2249 static_uninstall_ipv4 (p, si);
2250
2251 /* Unlink static route from linked list. */
2252 if (si->prev)
2253 si->prev->next = si->next;
2254 else
2255 rn->info = si->next;
2256 if (si->next)
2257 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002258 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002259
2260 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002261 if (ifname)
2262 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002263 XFREE (MTYPE_STATIC_IPV4, si);
2264
paul143a3852003-09-29 20:06:13 +00002265 route_unlock_node (rn);
2266
paul718e3742002-12-13 20:15:29 +00002267 return 1;
2268}
2269
2270
2271#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00002272static int
paul718e3742002-12-13 20:15:29 +00002273rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2274 struct in6_addr *gate, unsigned int ifindex, int table)
2275{
hasso726f9b22003-05-25 21:04:54 +00002276 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2277#if defined (MUSICA) || defined (LINUX)
2278 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2279 if (p->prefixlen == 96)
2280 return 0;
2281#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00002282 return 1;
hasso726f9b22003-05-25 21:04:54 +00002283 }
paul718e3742002-12-13 20:15:29 +00002284 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
2285 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
2286 {
2287 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
2288 return 1;
2289 }
2290 return 0;
2291}
2292
2293int
2294rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00002295 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
2296 u_int32_t metric, u_char distance)
paul718e3742002-12-13 20:15:29 +00002297{
2298 struct rib *rib;
2299 struct rib *same = NULL;
2300 struct route_table *table;
2301 struct route_node *rn;
2302 struct nexthop *nexthop;
2303
paul718e3742002-12-13 20:15:29 +00002304 /* Lookup table. */
2305 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2306 if (! table)
2307 return 0;
2308
2309 /* Make sure mask is applied. */
2310 apply_mask_ipv6 (p);
2311
2312 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002313 if (!distance)
2314 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002315
2316 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2317 distance = 200;
2318
2319 /* Filter bogus route. */
2320 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
2321 return 0;
2322
2323 /* Lookup route node.*/
2324 rn = route_node_get (table, (struct prefix *) p);
2325
2326 /* If same type of route are installed, treat it as a implicit
2327 withdraw. */
2328 for (rib = rn->info; rib; rib = rib->next)
2329 {
Paul Jakma6d691122006-07-27 21:49:00 +00002330 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2331 continue;
2332
hassoebf1ead2005-09-21 14:58:20 +00002333 if (rib->type != type)
2334 continue;
2335 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002336 {
2337 same = rib;
paul718e3742002-12-13 20:15:29 +00002338 break;
2339 }
hassoebf1ead2005-09-21 14:58:20 +00002340 else if ((nexthop = rib->nexthop) &&
2341 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2342 nexthop->ifindex == ifindex)
2343 {
2344 rib->refcnt++;
2345 return 0;
2346 }
paul718e3742002-12-13 20:15:29 +00002347 }
2348
2349 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002350 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2351
paul718e3742002-12-13 20:15:29 +00002352 rib->type = type;
2353 rib->distance = distance;
2354 rib->flags = flags;
2355 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00002356 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00002357 rib->nexthop_num = 0;
2358 rib->uptime = time (NULL);
2359
2360 /* Nexthop settings. */
2361 if (gate)
2362 {
2363 if (ifindex)
2364 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2365 else
2366 nexthop_ipv6_add (rib, gate);
2367 }
2368 else
2369 nexthop_ifindex_add (rib, ifindex);
2370
2371 /* If this route is kernel route, set FIB flag to the route. */
2372 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2373 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2374 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2375
2376 /* Link new rib to node.*/
2377 rib_addnode (rn, rib);
2378
paul718e3742002-12-13 20:15:29 +00002379 /* Free implicit route.*/
2380 if (same)
paul4d38fdb2005-04-28 17:35:14 +00002381 rib_delnode (rn, same);
2382
2383 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002384 return 0;
2385}
2386
hassoebf1ead2005-09-21 14:58:20 +00002387/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002388int
2389rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
2390 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
2391{
2392 struct route_table *table;
2393 struct route_node *rn;
2394 struct rib *rib;
2395 struct rib *fib = NULL;
2396 struct rib *same = NULL;
2397 struct nexthop *nexthop;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002398 char buf1[INET6_ADDRSTRLEN];
2399 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002400
2401 /* Apply mask. */
2402 apply_mask_ipv6 (p);
2403
2404 /* Lookup table. */
2405 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2406 if (! table)
2407 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002408
paul718e3742002-12-13 20:15:29 +00002409 /* Lookup route node. */
2410 rn = route_node_lookup (table, (struct prefix *) p);
2411 if (! rn)
2412 {
2413 if (IS_ZEBRA_DEBUG_KERNEL)
2414 {
2415 if (gate)
ajsb6178002004-12-07 21:12:56 +00002416 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002417 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002418 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002419 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002420 ifindex);
2421 else
ajsb6178002004-12-07 21:12:56 +00002422 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002423 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002424 p->prefixlen,
2425 ifindex);
2426 }
2427 return ZEBRA_ERR_RTNOEXIST;
2428 }
2429
2430 /* Lookup same type route. */
2431 for (rib = rn->info; rib; rib = rib->next)
2432 {
Paul Jakma6d691122006-07-27 21:49:00 +00002433 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2434 continue;
2435
paul718e3742002-12-13 20:15:29 +00002436 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2437 fib = rib;
2438
hassoebf1ead2005-09-21 14:58:20 +00002439 if (rib->type != type)
2440 continue;
2441 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002442 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002443 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002444 if (nexthop->ifindex != ifindex)
2445 continue;
hassoebf1ead2005-09-21 14:58:20 +00002446 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002447 {
hassoebf1ead2005-09-21 14:58:20 +00002448 rib->refcnt--;
2449 route_unlock_node (rn);
2450 route_unlock_node (rn);
2451 return 0;
paul718e3742002-12-13 20:15:29 +00002452 }
hassoebf1ead2005-09-21 14:58:20 +00002453 same = rib;
2454 break;
paul718e3742002-12-13 20:15:29 +00002455 }
hassoebf1ead2005-09-21 14:58:20 +00002456 /* Make sure that the route found has the same gateway. */
2457 else if (gate == NULL ||
2458 ((nexthop = rib->nexthop) &&
2459 (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate) ||
2460 IPV6_ADDR_SAME (&nexthop->rgate.ipv6, gate))))
paul718e3742002-12-13 20:15:29 +00002461 {
hassoebf1ead2005-09-21 14:58:20 +00002462 same = rib;
2463 break;
paul718e3742002-12-13 20:15:29 +00002464 }
2465 }
2466
2467 /* If same type of route can't be found and this message is from
2468 kernel. */
2469 if (! same)
2470 {
2471 if (fib && type == ZEBRA_ROUTE_KERNEL)
2472 {
2473 /* Unset flags. */
2474 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2475 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2476
2477 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2478 }
2479 else
2480 {
2481 if (IS_ZEBRA_DEBUG_KERNEL)
2482 {
2483 if (gate)
ajsb6178002004-12-07 21:12:56 +00002484 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002485 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002486 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002487 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002488 ifindex,
2489 type);
2490 else
ajsb6178002004-12-07 21:12:56 +00002491 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002492 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002493 p->prefixlen,
2494 ifindex,
2495 type);
2496 }
2497 route_unlock_node (rn);
2498 return ZEBRA_ERR_RTNOEXIST;
2499 }
2500 }
2501
2502 if (same)
2503 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002504
paul718e3742002-12-13 20:15:29 +00002505 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002506 return 0;
2507}
2508
2509/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002510static void
paul718e3742002-12-13 20:15:29 +00002511static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2512{
2513 struct rib *rib;
2514 struct route_table *table;
2515 struct route_node *rn;
2516
2517 /* Lookup table. */
2518 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2519 if (! table)
2520 return;
2521
2522 /* Lookup existing route */
2523 rn = route_node_get (table, p);
2524 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002525 {
2526 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2527 continue;
2528
2529 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2530 break;
2531 }
paul718e3742002-12-13 20:15:29 +00002532
2533 if (rib)
2534 {
2535 /* Same distance static route is there. Update it with new
2536 nexthop. */
paul718e3742002-12-13 20:15:29 +00002537 route_unlock_node (rn);
2538
2539 switch (si->type)
2540 {
2541 case STATIC_IPV6_GATEWAY:
2542 nexthop_ipv6_add (rib, &si->ipv6);
2543 break;
2544 case STATIC_IPV6_IFNAME:
2545 nexthop_ifname_add (rib, si->ifname);
2546 break;
2547 case STATIC_IPV6_GATEWAY_IFNAME:
2548 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2549 break;
2550 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002551 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002552 }
2553 else
2554 {
2555 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002556 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2557
paul718e3742002-12-13 20:15:29 +00002558 rib->type = ZEBRA_ROUTE_STATIC;
2559 rib->distance = si->distance;
2560 rib->metric = 0;
2561 rib->nexthop_num = 0;
2562
2563 switch (si->type)
2564 {
2565 case STATIC_IPV6_GATEWAY:
2566 nexthop_ipv6_add (rib, &si->ipv6);
2567 break;
2568 case STATIC_IPV6_IFNAME:
2569 nexthop_ifname_add (rib, si->ifname);
2570 break;
2571 case STATIC_IPV6_GATEWAY_IFNAME:
2572 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2573 break;
2574 }
2575
hasso81dfcaa2003-05-25 19:21:25 +00002576 /* Save the flags of this static routes (reject, blackhole) */
2577 rib->flags = si->flags;
2578
paul718e3742002-12-13 20:15:29 +00002579 /* Link this rib to the tree. */
2580 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002581 }
2582}
2583
paula1ac18c2005-06-28 17:17:12 +00002584static int
paul718e3742002-12-13 20:15:29 +00002585static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2586{
2587 if (nexthop->type == NEXTHOP_TYPE_IPV6
2588 && si->type == STATIC_IPV6_GATEWAY
2589 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2590 return 1;
2591 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2592 && si->type == STATIC_IPV6_IFNAME
2593 && strcmp (nexthop->ifname, si->ifname) == 0)
2594 return 1;
2595 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2596 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2597 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2598 && strcmp (nexthop->ifname, si->ifname) == 0)
2599 return 1;
paule8e19462006-01-19 20:16:55 +00002600 return 0;
paul718e3742002-12-13 20:15:29 +00002601}
2602
paula1ac18c2005-06-28 17:17:12 +00002603static void
paul718e3742002-12-13 20:15:29 +00002604static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2605{
2606 struct route_table *table;
2607 struct route_node *rn;
2608 struct rib *rib;
2609 struct nexthop *nexthop;
2610
2611 /* Lookup table. */
2612 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2613 if (! table)
2614 return;
2615
2616 /* Lookup existing route with type and distance. */
2617 rn = route_node_lookup (table, (struct prefix *) p);
2618 if (! rn)
2619 return;
2620
2621 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002622 {
2623 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2624 continue;
2625
2626 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2627 break;
2628 }
2629
paul718e3742002-12-13 20:15:29 +00002630 if (! rib)
2631 {
2632 route_unlock_node (rn);
2633 return;
2634 }
2635
2636 /* Lookup nexthop. */
2637 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2638 if (static_ipv6_nexthop_same (nexthop, si))
2639 break;
2640
2641 /* Can't find nexthop. */
2642 if (! nexthop)
2643 {
2644 route_unlock_node (rn);
2645 return;
2646 }
2647
2648 /* Check nexthop. */
2649 if (rib->nexthop_num == 1)
2650 {
2651 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002652 }
2653 else
2654 {
paul6baeb982003-10-28 03:47:15 +00002655 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2656 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002657 nexthop_delete (rib, nexthop);
2658 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002659 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002660 }
paul718e3742002-12-13 20:15:29 +00002661 /* Unlock node. */
2662 route_unlock_node (rn);
2663}
2664
2665/* Add static route into static route configuration. */
2666int
2667static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002668 const char *ifname, u_char flags, u_char distance,
2669 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002670{
2671 struct route_node *rn;
2672 struct static_ipv6 *si;
2673 struct static_ipv6 *pp;
2674 struct static_ipv6 *cp;
2675 struct route_table *stable;
2676
2677 /* Lookup table. */
2678 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2679 if (! stable)
2680 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00002681
2682 if (!gate &&
2683 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
2684 return -1;
2685
2686 if (!ifname &&
2687 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
2688 return -1;
paul718e3742002-12-13 20:15:29 +00002689
2690 /* Lookup static route prefix. */
2691 rn = route_node_get (stable, p);
2692
2693 /* Do nothing if there is a same static route. */
2694 for (si = rn->info; si; si = si->next)
2695 {
2696 if (distance == si->distance
2697 && type == si->type
2698 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2699 && (! ifname || strcmp (ifname, si->ifname) == 0))
2700 {
2701 route_unlock_node (rn);
2702 return 0;
2703 }
2704 }
2705
2706 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002707 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
paul718e3742002-12-13 20:15:29 +00002708
2709 si->type = type;
2710 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002711 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002712
2713 switch (type)
2714 {
2715 case STATIC_IPV6_GATEWAY:
2716 si->ipv6 = *gate;
2717 break;
2718 case STATIC_IPV6_IFNAME:
2719 si->ifname = XSTRDUP (0, ifname);
2720 break;
2721 case STATIC_IPV6_GATEWAY_IFNAME:
2722 si->ipv6 = *gate;
2723 si->ifname = XSTRDUP (0, ifname);
2724 break;
2725 }
2726
2727 /* Add new static route information to the tree with sort by
2728 distance value and gateway address. */
2729 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2730 {
2731 if (si->distance < cp->distance)
2732 break;
2733 if (si->distance > cp->distance)
2734 continue;
2735 }
2736
2737 /* Make linked list. */
2738 if (pp)
2739 pp->next = si;
2740 else
2741 rn->info = si;
2742 if (cp)
2743 cp->prev = si;
2744 si->prev = pp;
2745 si->next = cp;
2746
2747 /* Install into rib. */
2748 static_install_ipv6 (p, si);
2749
2750 return 1;
2751}
2752
2753/* Delete static route from static route configuration. */
2754int
2755static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002756 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002757{
2758 struct route_node *rn;
2759 struct static_ipv6 *si;
2760 struct route_table *stable;
2761
2762 /* Lookup table. */
2763 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2764 if (! stable)
2765 return -1;
2766
2767 /* Lookup static route prefix. */
2768 rn = route_node_lookup (stable, p);
2769 if (! rn)
2770 return 0;
2771
2772 /* Find same static route is the tree */
2773 for (si = rn->info; si; si = si->next)
2774 if (distance == si->distance
2775 && type == si->type
2776 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2777 && (! ifname || strcmp (ifname, si->ifname) == 0))
2778 break;
2779
2780 /* Can't find static route. */
2781 if (! si)
2782 {
2783 route_unlock_node (rn);
2784 return 0;
2785 }
2786
2787 /* Install into rib. */
2788 static_uninstall_ipv6 (p, si);
2789
2790 /* Unlink static route from linked list. */
2791 if (si->prev)
2792 si->prev->next = si->next;
2793 else
2794 rn->info = si->next;
2795 if (si->next)
2796 si->next->prev = si->prev;
2797
2798 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002799 if (ifname)
2800 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00002801 XFREE (MTYPE_STATIC_IPV6, si);
2802
2803 return 1;
2804}
2805#endif /* HAVE_IPV6 */
2806
2807/* RIB update function. */
2808void
paula1ac18c2005-06-28 17:17:12 +00002809rib_update (void)
paul718e3742002-12-13 20:15:29 +00002810{
2811 struct route_node *rn;
2812 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00002813
paul718e3742002-12-13 20:15:29 +00002814 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2815 if (table)
2816 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002817 if (rn->info)
Paul Jakma6d691122006-07-27 21:49:00 +00002818 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002819
2820 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2821 if (table)
2822 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002823 if (rn->info)
Paul Jakma6d691122006-07-27 21:49:00 +00002824 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002825}
2826
paul718e3742002-12-13 20:15:29 +00002827
2828/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00002829static void
paul718e3742002-12-13 20:15:29 +00002830rib_weed_table (struct route_table *table)
2831{
2832 struct route_node *rn;
2833 struct rib *rib;
2834 struct rib *next;
2835
2836 if (table)
2837 for (rn = route_top (table); rn; rn = route_next (rn))
2838 for (rib = rn->info; rib; rib = next)
2839 {
2840 next = rib->next;
2841
Paul Jakma6d691122006-07-27 21:49:00 +00002842 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2843 continue;
2844
paulb21b19c2003-06-15 01:28:29 +00002845 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00002846 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00002847 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002848 }
2849}
2850
2851/* Delete all routes from non main table. */
2852void
paula1ac18c2005-06-28 17:17:12 +00002853rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00002854{
2855 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2856 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2857}
2858
2859/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00002860static void
paul718e3742002-12-13 20:15:29 +00002861rib_sweep_table (struct route_table *table)
2862{
2863 struct route_node *rn;
2864 struct rib *rib;
2865 struct rib *next;
2866 int ret = 0;
2867
2868 if (table)
2869 for (rn = route_top (table); rn; rn = route_next (rn))
2870 for (rib = rn->info; rib; rib = next)
2871 {
2872 next = rib->next;
2873
Paul Jakma6d691122006-07-27 21:49:00 +00002874 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2875 continue;
2876
paul718e3742002-12-13 20:15:29 +00002877 if (rib->type == ZEBRA_ROUTE_KERNEL &&
2878 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
2879 {
2880 ret = rib_uninstall_kernel (rn, rib);
2881 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00002882 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002883 }
2884 }
2885}
2886
2887/* Sweep all RIB tables. */
2888void
paula1ac18c2005-06-28 17:17:12 +00002889rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00002890{
2891 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2892 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2893}
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04002894
2895/* Remove specific by protocol routes from 'table'. */
2896static unsigned long
2897rib_score_proto_table (u_char proto, struct route_table *table)
2898{
2899 struct route_node *rn;
2900 struct rib *rib;
2901 struct rib *next;
2902 unsigned long n = 0;
2903
2904 if (table)
2905 for (rn = route_top (table); rn; rn = route_next (rn))
2906 for (rib = rn->info; rib; rib = next)
2907 {
2908 next = rib->next;
2909 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2910 continue;
2911 if (rib->type == proto)
2912 {
2913 rib_delnode (rn, rib);
2914 n++;
2915 }
2916 }
2917
2918 return n;
2919}
2920
2921/* Remove specific by protocol routes. */
2922unsigned long
2923rib_score_proto (u_char proto)
2924{
2925 return rib_score_proto_table (proto, vrf_table (AFI_IP, SAFI_UNICAST, 0))
2926 +rib_score_proto_table (proto, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2927}
2928
paul718e3742002-12-13 20:15:29 +00002929/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00002930static void
paul718e3742002-12-13 20:15:29 +00002931rib_close_table (struct route_table *table)
2932{
2933 struct route_node *rn;
2934 struct rib *rib;
2935
2936 if (table)
2937 for (rn = route_top (table); rn; rn = route_next (rn))
2938 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002939 {
2940 if (! RIB_SYSTEM_ROUTE (rib)
2941 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2942 rib_uninstall_kernel (rn, rib);
2943 }
paul718e3742002-12-13 20:15:29 +00002944}
2945
2946/* Close all RIB tables. */
2947void
paula1ac18c2005-06-28 17:17:12 +00002948rib_close (void)
paul718e3742002-12-13 20:15:29 +00002949{
2950 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2951 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2952}
2953
2954/* Routing information base initialize. */
2955void
paula1ac18c2005-06-28 17:17:12 +00002956rib_init (void)
paul718e3742002-12-13 20:15:29 +00002957{
paul4d38fdb2005-04-28 17:35:14 +00002958 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00002959 /* VRF initialization. */
2960 vrf_init ();
2961}