blob: 8228350f0953538d8d540765e70525adb5601057 [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 ();
93
94 return vrf;
95}
96
paul718e3742002-12-13 20:15:29 +000097/* Lookup VRF by identifier. */
98struct vrf *
99vrf_lookup (u_int32_t id)
100{
101 return vector_lookup (vrf_vector, id);
102}
103
paul718e3742002-12-13 20:15:29 +0000104/* Initialize VRF. */
paula1ac18c2005-06-28 17:17:12 +0000105static void
106vrf_init (void)
paul718e3742002-12-13 20:15:29 +0000107{
108 struct vrf *default_table;
109
110 /* Allocate VRF vector. */
111 vrf_vector = vector_init (1);
112
113 /* Allocate default main table. */
114 default_table = vrf_alloc ("Default-IP-Routing-Table");
115
116 /* Default table index must be 0. */
117 vector_set_index (vrf_vector, 0, default_table);
118}
119
120/* Lookup route table. */
121struct route_table *
122vrf_table (afi_t afi, safi_t safi, u_int32_t id)
123{
124 struct vrf *vrf;
125
126 vrf = vrf_lookup (id);
127 if (! vrf)
128 return NULL;
129
130 return vrf->table[afi][safi];
131}
132
133/* Lookup static route table. */
134struct route_table *
135vrf_static_table (afi_t afi, safi_t safi, u_int32_t id)
136{
137 struct vrf *vrf;
138
139 vrf = vrf_lookup (id);
140 if (! vrf)
141 return NULL;
142
143 return vrf->stable[afi][safi];
144}
145
146/* Add nexthop to the end of the list. */
paula1ac18c2005-06-28 17:17:12 +0000147static void
paul718e3742002-12-13 20:15:29 +0000148nexthop_add (struct rib *rib, struct nexthop *nexthop)
149{
150 struct nexthop *last;
151
152 for (last = rib->nexthop; last && last->next; last = last->next)
153 ;
154 if (last)
155 last->next = nexthop;
156 else
157 rib->nexthop = nexthop;
158 nexthop->prev = last;
159
160 rib->nexthop_num++;
161}
162
163/* Delete specified nexthop from the list. */
paula1ac18c2005-06-28 17:17:12 +0000164static void
paul718e3742002-12-13 20:15:29 +0000165nexthop_delete (struct rib *rib, struct nexthop *nexthop)
166{
167 if (nexthop->next)
168 nexthop->next->prev = nexthop->prev;
169 if (nexthop->prev)
170 nexthop->prev->next = nexthop->next;
171 else
172 rib->nexthop = nexthop->next;
173 rib->nexthop_num--;
174}
175
176/* Free nexthop. */
paula1ac18c2005-06-28 17:17:12 +0000177static void
paul718e3742002-12-13 20:15:29 +0000178nexthop_free (struct nexthop *nexthop)
179{
paula4b70762003-05-16 17:19:48 +0000180 if (nexthop->ifname)
181 XFREE (0, nexthop->ifname);
paul718e3742002-12-13 20:15:29 +0000182 XFREE (MTYPE_NEXTHOP, nexthop);
183}
184
185struct nexthop *
186nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
187{
188 struct nexthop *nexthop;
189
Stephen Hemminger393deb92008-08-18 14:13:29 -0700190 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000191 nexthop->type = NEXTHOP_TYPE_IFINDEX;
192 nexthop->ifindex = ifindex;
193
194 nexthop_add (rib, nexthop);
195
196 return nexthop;
197}
198
199struct nexthop *
200nexthop_ifname_add (struct rib *rib, char *ifname)
201{
202 struct nexthop *nexthop;
203
Stephen Hemminger393deb92008-08-18 14:13:29 -0700204 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000205 nexthop->type = NEXTHOP_TYPE_IFNAME;
paula4b70762003-05-16 17:19:48 +0000206 nexthop->ifname = XSTRDUP (0, ifname);
paul718e3742002-12-13 20:15:29 +0000207
208 nexthop_add (rib, nexthop);
209
210 return nexthop;
211}
212
213struct nexthop *
Paul Jakma7514fb72007-05-02 16:05:35 +0000214nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src)
paul718e3742002-12-13 20:15:29 +0000215{
216 struct nexthop *nexthop;
217
Stephen Hemminger393deb92008-08-18 14:13:29 -0700218 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000219 nexthop->type = NEXTHOP_TYPE_IPV4;
220 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000221 if (src)
222 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000223
224 nexthop_add (rib, nexthop);
225
226 return nexthop;
227}
228
paula1ac18c2005-06-28 17:17:12 +0000229static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000230nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
Paul Jakma7514fb72007-05-02 16:05:35 +0000231 struct in_addr *src, unsigned int ifindex)
paul718e3742002-12-13 20:15:29 +0000232{
233 struct nexthop *nexthop;
234
Stephen Hemminger393deb92008-08-18 14:13:29 -0700235 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000236 nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
237 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000238 if (src)
239 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000240 nexthop->ifindex = ifindex;
241
242 nexthop_add (rib, nexthop);
243
244 return nexthop;
245}
246
247#ifdef HAVE_IPV6
248struct nexthop *
249nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
250{
251 struct nexthop *nexthop;
252
Stephen Hemminger393deb92008-08-18 14:13:29 -0700253 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000254 nexthop->type = NEXTHOP_TYPE_IPV6;
255 nexthop->gate.ipv6 = *ipv6;
256
257 nexthop_add (rib, nexthop);
258
259 return nexthop;
260}
261
paula1ac18c2005-06-28 17:17:12 +0000262static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000263nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
264 char *ifname)
265{
266 struct nexthop *nexthop;
267
Stephen Hemminger393deb92008-08-18 14:13:29 -0700268 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000269 nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
270 nexthop->gate.ipv6 = *ipv6;
271 nexthop->ifname = XSTRDUP (0, ifname);
272
273 nexthop_add (rib, nexthop);
274
275 return nexthop;
276}
277
paula1ac18c2005-06-28 17:17:12 +0000278static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000279nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
280 unsigned int ifindex)
281{
282 struct nexthop *nexthop;
283
Stephen Hemminger393deb92008-08-18 14:13:29 -0700284 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000285 nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
286 nexthop->gate.ipv6 = *ipv6;
287 nexthop->ifindex = ifindex;
288
289 nexthop_add (rib, nexthop);
290
291 return nexthop;
292}
293#endif /* HAVE_IPV6 */
294
paul595db7f2003-05-25 21:35:06 +0000295struct nexthop *
296nexthop_blackhole_add (struct rib *rib)
297{
298 struct nexthop *nexthop;
299
Stephen Hemminger393deb92008-08-18 14:13:29 -0700300 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul595db7f2003-05-25 21:35:06 +0000301 nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
302 SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
303
304 nexthop_add (rib, nexthop);
305
306 return nexthop;
307}
308
paul718e3742002-12-13 20:15:29 +0000309/* If force flag is not set, do not modify falgs at all for uninstall
310 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000311static int
paul718e3742002-12-13 20:15:29 +0000312nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
313 struct route_node *top)
314{
315 struct prefix_ipv4 p;
316 struct route_table *table;
317 struct route_node *rn;
318 struct rib *match;
319 struct nexthop *newhop;
320
321 if (nexthop->type == NEXTHOP_TYPE_IPV4)
322 nexthop->ifindex = 0;
323
324 if (set)
325 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
326
327 /* Make lookup prefix. */
328 memset (&p, 0, sizeof (struct prefix_ipv4));
329 p.family = AF_INET;
330 p.prefixlen = IPV4_MAX_PREFIXLEN;
331 p.prefix = nexthop->gate.ipv4;
332
333 /* Lookup table. */
334 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
335 if (! table)
336 return 0;
337
338 rn = route_node_match (table, (struct prefix *) &p);
339 while (rn)
340 {
341 route_unlock_node (rn);
342
David Warda50c1072009-12-03 15:34:39 +0300343 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000344 if (rn == top)
345 return 0;
346
347 /* Pick up selected route. */
348 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100349 {
350 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
351 continue;
352 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
353 break;
354 }
paul718e3742002-12-13 20:15:29 +0000355
356 /* If there is no selected route or matched route is EGP, go up
357 tree. */
358 if (! match
359 || match->type == ZEBRA_ROUTE_BGP)
360 {
361 do {
362 rn = rn->parent;
363 } while (rn && rn->info == NULL);
364 if (rn)
365 route_lock_node (rn);
366 }
367 else
368 {
369 if (match->type == ZEBRA_ROUTE_CONNECT)
370 {
371 /* Directly point connected route. */
372 newhop = match->nexthop;
373 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
374 nexthop->ifindex = newhop->ifindex;
375
376 return 1;
377 }
378 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
379 {
380 for (newhop = match->nexthop; newhop; newhop = newhop->next)
381 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
382 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
383 {
384 if (set)
385 {
386 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
387 nexthop->rtype = newhop->type;
388 if (newhop->type == NEXTHOP_TYPE_IPV4 ||
389 newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
390 nexthop->rgate.ipv4 = newhop->gate.ipv4;
391 if (newhop->type == NEXTHOP_TYPE_IFINDEX
392 || newhop->type == NEXTHOP_TYPE_IFNAME
393 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
394 nexthop->rifindex = newhop->ifindex;
395 }
396 return 1;
397 }
398 return 0;
399 }
400 else
401 {
402 return 0;
403 }
404 }
405 }
406 return 0;
407}
408
409#ifdef HAVE_IPV6
410/* If force flag is not set, do not modify falgs at all for uninstall
411 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000412static int
paul718e3742002-12-13 20:15:29 +0000413nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
414 struct route_node *top)
415{
416 struct prefix_ipv6 p;
417 struct route_table *table;
418 struct route_node *rn;
419 struct rib *match;
420 struct nexthop *newhop;
421
422 if (nexthop->type == NEXTHOP_TYPE_IPV6)
423 nexthop->ifindex = 0;
424
425 if (set)
426 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
427
428 /* Make lookup prefix. */
429 memset (&p, 0, sizeof (struct prefix_ipv6));
430 p.family = AF_INET6;
431 p.prefixlen = IPV6_MAX_PREFIXLEN;
432 p.prefix = nexthop->gate.ipv6;
433
434 /* Lookup table. */
435 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
436 if (! table)
437 return 0;
438
439 rn = route_node_match (table, (struct prefix *) &p);
440 while (rn)
441 {
442 route_unlock_node (rn);
443
David Warda50c1072009-12-03 15:34:39 +0300444 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000445 if (rn == top)
446 return 0;
447
448 /* Pick up selected route. */
449 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100450 {
451 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
452 continue;
453 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
454 break;
455 }
paul718e3742002-12-13 20:15:29 +0000456
457 /* If there is no selected route or matched route is EGP, go up
458 tree. */
459 if (! match
460 || match->type == ZEBRA_ROUTE_BGP)
461 {
462 do {
463 rn = rn->parent;
464 } while (rn && rn->info == NULL);
465 if (rn)
466 route_lock_node (rn);
467 }
468 else
469 {
470 if (match->type == ZEBRA_ROUTE_CONNECT)
471 {
472 /* Directly point connected route. */
473 newhop = match->nexthop;
474
475 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
476 nexthop->ifindex = newhop->ifindex;
477
478 return 1;
479 }
480 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
481 {
482 for (newhop = match->nexthop; newhop; newhop = newhop->next)
483 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
484 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
485 {
486 if (set)
487 {
488 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
489 nexthop->rtype = newhop->type;
490 if (newhop->type == NEXTHOP_TYPE_IPV6
491 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
492 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
493 nexthop->rgate.ipv6 = newhop->gate.ipv6;
494 if (newhop->type == NEXTHOP_TYPE_IFINDEX
495 || newhop->type == NEXTHOP_TYPE_IFNAME
496 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
497 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
498 nexthop->rifindex = newhop->ifindex;
499 }
500 return 1;
501 }
502 return 0;
503 }
504 else
505 {
506 return 0;
507 }
508 }
509 }
510 return 0;
511}
512#endif /* HAVE_IPV6 */
513
514struct rib *
515rib_match_ipv4 (struct in_addr addr)
516{
517 struct prefix_ipv4 p;
518 struct route_table *table;
519 struct route_node *rn;
520 struct rib *match;
521 struct nexthop *newhop;
522
523 /* Lookup table. */
524 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
525 if (! table)
526 return 0;
527
528 memset (&p, 0, sizeof (struct prefix_ipv4));
529 p.family = AF_INET;
530 p.prefixlen = IPV4_MAX_PREFIXLEN;
531 p.prefix = addr;
532
533 rn = route_node_match (table, (struct prefix *) &p);
534
535 while (rn)
536 {
537 route_unlock_node (rn);
538
539 /* Pick up selected route. */
540 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100541 {
542 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
543 continue;
544 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
545 break;
546 }
paul718e3742002-12-13 20:15:29 +0000547
548 /* If there is no selected route or matched route is EGP, go up
549 tree. */
550 if (! match
551 || match->type == ZEBRA_ROUTE_BGP)
552 {
553 do {
554 rn = rn->parent;
555 } while (rn && rn->info == NULL);
556 if (rn)
557 route_lock_node (rn);
558 }
559 else
560 {
561 if (match->type == ZEBRA_ROUTE_CONNECT)
562 /* Directly point connected route. */
563 return match;
564 else
565 {
566 for (newhop = match->nexthop; newhop; newhop = newhop->next)
567 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
568 return match;
569 return NULL;
570 }
571 }
572 }
573 return NULL;
574}
575
576struct rib *
577rib_lookup_ipv4 (struct prefix_ipv4 *p)
578{
579 struct route_table *table;
580 struct route_node *rn;
581 struct rib *match;
582 struct nexthop *nexthop;
583
584 /* Lookup table. */
585 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
586 if (! table)
587 return 0;
588
589 rn = route_node_lookup (table, (struct prefix *) p);
590
591 /* No route for this prefix. */
592 if (! rn)
593 return NULL;
594
595 /* Unlock node. */
596 route_unlock_node (rn);
597
paul718e3742002-12-13 20:15:29 +0000598 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100599 {
600 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
601 continue;
602 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
603 break;
604 }
paul718e3742002-12-13 20:15:29 +0000605
606 if (! match || match->type == ZEBRA_ROUTE_BGP)
607 return NULL;
608
609 if (match->type == ZEBRA_ROUTE_CONNECT)
610 return match;
611
612 for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
613 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
614 return match;
615
616 return NULL;
617}
618
Denis Ovsienkodc958242007-08-13 16:03:06 +0000619/*
620 * This clone function, unlike its original rib_lookup_ipv4(), checks
621 * if specified IPv4 route record (prefix/mask -> gate) exists in
622 * the whole RIB and has ZEBRA_FLAG_SELECTED set.
623 *
624 * Return values:
625 * -1: error
626 * 0: exact match found
627 * 1: a match was found with a different gate
628 * 2: connected route found
629 * 3: no matches found
630 */
631int
632rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
633{
634 struct route_table *table;
635 struct route_node *rn;
636 struct rib *match;
637 struct nexthop *nexthop;
638
639 /* Lookup table. */
640 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
641 if (! table)
642 return ZEBRA_RIB_LOOKUP_ERROR;
643
644 /* Scan the RIB table for exactly matching RIB entry. */
645 rn = route_node_lookup (table, (struct prefix *) p);
646
647 /* No route for this prefix. */
648 if (! rn)
649 return ZEBRA_RIB_NOTFOUND;
650
651 /* Unlock node. */
652 route_unlock_node (rn);
653
654 /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
655 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100656 {
657 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
658 continue;
659 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
660 break;
661 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000662
663 /* None such found :( */
664 if (!match)
665 return ZEBRA_RIB_NOTFOUND;
666
667 if (match->type == ZEBRA_ROUTE_CONNECT)
668 return ZEBRA_RIB_FOUND_CONNECTED;
669
670 /* Ok, we have a cood candidate, let's check it's nexthop list... */
671 for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
672 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
673 {
674 /* We are happy with either direct or recursive hexthop */
675 if (nexthop->gate.ipv4.s_addr == qgate->sin.sin_addr.s_addr ||
676 nexthop->rgate.ipv4.s_addr == qgate->sin.sin_addr.s_addr)
677 return ZEBRA_RIB_FOUND_EXACT;
678 else
679 {
680 if (IS_ZEBRA_DEBUG_RIB)
681 {
682 char gate_buf[INET_ADDRSTRLEN], rgate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
683 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
684 inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, rgate_buf, INET_ADDRSTRLEN);
685 inet_ntop (AF_INET, &qgate->sin.sin_addr.s_addr, qgate_buf, INET_ADDRSTRLEN);
686 zlog_debug ("%s: qgate == %s, gate == %s, rgate == %s", __func__, qgate_buf, gate_buf, rgate_buf);
687 }
688 return ZEBRA_RIB_FOUND_NOGATE;
689 }
690 }
691
692 return ZEBRA_RIB_NOTFOUND;
693}
694
paul718e3742002-12-13 20:15:29 +0000695#ifdef HAVE_IPV6
696struct rib *
697rib_match_ipv6 (struct in6_addr *addr)
698{
699 struct prefix_ipv6 p;
700 struct route_table *table;
701 struct route_node *rn;
702 struct rib *match;
703 struct nexthop *newhop;
704
705 /* Lookup table. */
706 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
707 if (! table)
708 return 0;
709
710 memset (&p, 0, sizeof (struct prefix_ipv6));
711 p.family = AF_INET6;
712 p.prefixlen = IPV6_MAX_PREFIXLEN;
713 IPV6_ADDR_COPY (&p.prefix, addr);
714
715 rn = route_node_match (table, (struct prefix *) &p);
716
717 while (rn)
718 {
719 route_unlock_node (rn);
720
721 /* Pick up selected route. */
722 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100723 {
724 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
725 continue;
726 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
727 break;
728 }
paul718e3742002-12-13 20:15:29 +0000729
730 /* If there is no selected route or matched route is EGP, go up
731 tree. */
732 if (! match
733 || match->type == ZEBRA_ROUTE_BGP)
734 {
735 do {
736 rn = rn->parent;
737 } while (rn && rn->info == NULL);
738 if (rn)
739 route_lock_node (rn);
740 }
741 else
742 {
743 if (match->type == ZEBRA_ROUTE_CONNECT)
744 /* Directly point connected route. */
745 return match;
746 else
747 {
748 for (newhop = match->nexthop; newhop; newhop = newhop->next)
749 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
750 return match;
751 return NULL;
752 }
753 }
754 }
755 return NULL;
756}
757#endif /* HAVE_IPV6 */
758
Paul Jakma7514fb72007-05-02 16:05:35 +0000759#define RIB_SYSTEM_ROUTE(R) \
760 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
761
Denis Ovsienkodc958242007-08-13 16:03:06 +0000762/* This function verifies reachability of one given nexthop, which can be
763 * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
764 * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
765 * nexthop->ifindex will be updated appropriately as well.
766 * An existing route map can turn (otherwise active) nexthop into inactive, but
767 * not vice versa.
768 *
769 * The return value is the final value of 'ACTIVE' flag.
770 */
771
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300772static unsigned
paul718e3742002-12-13 20:15:29 +0000773nexthop_active_check (struct route_node *rn, struct rib *rib,
774 struct nexthop *nexthop, int set)
775{
776 struct interface *ifp;
Paul Jakma7514fb72007-05-02 16:05:35 +0000777 route_map_result_t ret = RMAP_MATCH;
778 extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
779 struct route_map *rmap;
780 int family;
paul718e3742002-12-13 20:15:29 +0000781
Paul Jakma7514fb72007-05-02 16:05:35 +0000782 family = 0;
paul718e3742002-12-13 20:15:29 +0000783 switch (nexthop->type)
784 {
785 case NEXTHOP_TYPE_IFINDEX:
786 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000787 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000788 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
789 else
790 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
791 break;
paul718e3742002-12-13 20:15:29 +0000792 case NEXTHOP_TYPE_IPV6_IFNAME:
Paul Jakma7514fb72007-05-02 16:05:35 +0000793 family = AFI_IP6;
794 case NEXTHOP_TYPE_IFNAME:
paul718e3742002-12-13 20:15:29 +0000795 ifp = if_lookup_by_name (nexthop->ifname);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000796 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000797 {
798 if (set)
799 nexthop->ifindex = ifp->ifindex;
800 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
801 }
802 else
803 {
804 if (set)
805 nexthop->ifindex = 0;
806 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
807 }
808 break;
809 case NEXTHOP_TYPE_IPV4:
810 case NEXTHOP_TYPE_IPV4_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000811 family = AFI_IP;
paul718e3742002-12-13 20:15:29 +0000812 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
813 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
814 else
815 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
816 break;
817#ifdef HAVE_IPV6
818 case NEXTHOP_TYPE_IPV6:
Paul Jakma7514fb72007-05-02 16:05:35 +0000819 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000820 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
821 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
822 else
823 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
824 break;
825 case NEXTHOP_TYPE_IPV6_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000826 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000827 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
828 {
829 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000830 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000831 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
832 else
833 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
834 }
835 else
836 {
837 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
838 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
839 else
840 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
841 }
842 break;
843#endif /* HAVE_IPV6 */
paul595db7f2003-05-25 21:35:06 +0000844 case NEXTHOP_TYPE_BLACKHOLE:
845 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
846 break;
paul718e3742002-12-13 20:15:29 +0000847 default:
848 break;
849 }
Paul Jakma7514fb72007-05-02 16:05:35 +0000850 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
851 return 0;
852
853 if (RIB_SYSTEM_ROUTE(rib) ||
854 (family == AFI_IP && rn->p.family != AF_INET) ||
855 (family == AFI_IP6 && rn->p.family != AF_INET6))
856 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
857
858 rmap = 0;
859 if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
860 proto_rm[family][rib->type])
861 rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
862 if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
863 rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
864 if (rmap) {
865 ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, nexthop);
866 }
867
868 if (ret == RMAP_DENYMATCH)
869 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
paul718e3742002-12-13 20:15:29 +0000870 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
871}
872
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000873/* Iterate over all nexthops of the given RIB entry and refresh their
874 * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
875 * nexthop is found to toggle the ACTIVE flag, the whole rib structure
876 * is flagged with ZEBRA_FLAG_CHANGED. The 4th 'set' argument is
877 * transparently passed to nexthop_active_check().
878 *
879 * Return value is the new number of active nexthops.
880 */
881
paula1ac18c2005-06-28 17:17:12 +0000882static int
paul718e3742002-12-13 20:15:29 +0000883nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
884{
885 struct nexthop *nexthop;
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300886 unsigned int prev_active, prev_index, new_active;
paul718e3742002-12-13 20:15:29 +0000887
888 rib->nexthop_active_num = 0;
889 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
890
891 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000892 {
893 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
Joakim Tjernlundc3a56062009-06-24 19:15:36 +0200894 prev_index = nexthop->ifindex;
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000895 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
896 rib->nexthop_active_num++;
Joakim Tjernlundc3a56062009-06-24 19:15:36 +0200897 if (prev_active != new_active ||
898 prev_index != nexthop->ifindex)
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000899 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
900 }
paul718e3742002-12-13 20:15:29 +0000901 return rib->nexthop_active_num;
902}
paul6baeb982003-10-28 03:47:15 +0000903
paul718e3742002-12-13 20:15:29 +0000904
paul718e3742002-12-13 20:15:29 +0000905
paula1ac18c2005-06-28 17:17:12 +0000906static void
paul718e3742002-12-13 20:15:29 +0000907rib_install_kernel (struct route_node *rn, struct rib *rib)
908{
909 int ret = 0;
910 struct nexthop *nexthop;
911
912 switch (PREFIX_FAMILY (&rn->p))
913 {
914 case AF_INET:
915 ret = kernel_add_ipv4 (&rn->p, rib);
916 break;
917#ifdef HAVE_IPV6
918 case AF_INET6:
919 ret = kernel_add_ipv6 (&rn->p, rib);
920 break;
921#endif /* HAVE_IPV6 */
922 }
923
Denis Ovsienkodc958242007-08-13 16:03:06 +0000924 /* This condition is never met, if we are using rt_socket.c */
paul718e3742002-12-13 20:15:29 +0000925 if (ret < 0)
926 {
927 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
928 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
929 }
930}
931
932/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +0000933static int
paul718e3742002-12-13 20:15:29 +0000934rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
935{
936 int ret = 0;
937 struct nexthop *nexthop;
938
939 switch (PREFIX_FAMILY (&rn->p))
940 {
941 case AF_INET:
942 ret = kernel_delete_ipv4 (&rn->p, rib);
943 break;
944#ifdef HAVE_IPV6
945 case AF_INET6:
946 ret = kernel_delete_ipv6 (&rn->p, rib);
947 break;
948#endif /* HAVE_IPV6 */
949 }
950
951 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
952 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
953
954 return ret;
955}
956
957/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +0000958static void
paul718e3742002-12-13 20:15:29 +0000959rib_uninstall (struct route_node *rn, struct rib *rib)
960{
961 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
962 {
963 redistribute_delete (&rn->p, rib);
964 if (! RIB_SYSTEM_ROUTE (rib))
965 rib_uninstall_kernel (rn, rib);
966 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
967 }
968}
969
Paul Jakma6d691122006-07-27 21:49:00 +0000970static void rib_unlink (struct route_node *, struct rib *);
971
paul718e3742002-12-13 20:15:29 +0000972/* Core function for processing routing information base. */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +0000973static void
974rib_process (struct route_node *rn)
paul718e3742002-12-13 20:15:29 +0000975{
976 struct rib *rib;
977 struct rib *next;
978 struct rib *fib = NULL;
979 struct rib *select = NULL;
Paul Jakma6d691122006-07-27 21:49:00 +0000980 struct rib *del = NULL;
pauld753e9e2003-01-22 19:45:50 +0000981 int installed = 0;
982 struct nexthop *nexthop = NULL;
Denis Ovsienkof304cb42007-10-03 12:27:16 +0000983 char buf[INET6_ADDRSTRLEN];
paul4d38fdb2005-04-28 17:35:14 +0000984
985 assert (rn);
986
Paul Jakma93bdada2007-08-06 19:25:11 +0000987 if (IS_ZEBRA_DEBUG_RIB || IS_ZEBRA_DEBUG_RIB_Q)
Denis Ovsienkof304cb42007-10-03 12:27:16 +0000988 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +0000989
paul718e3742002-12-13 20:15:29 +0000990 for (rib = rn->info; rib; rib = next)
991 {
Denis Ovsienkodc958242007-08-13 16:03:06 +0000992 /* The next pointer is saved, because current pointer
993 * may be passed to rib_unlink() in the middle of iteration.
994 */
paul718e3742002-12-13 20:15:29 +0000995 next = rib->next;
pauld753e9e2003-01-22 19:45:50 +0000996
paul718e3742002-12-13 20:15:29 +0000997 /* Currently installed rib. */
998 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Paul Jakma6d691122006-07-27 21:49:00 +0000999 {
1000 assert (fib == NULL);
1001 fib = rib;
1002 }
1003
1004 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1005 * which we need to do do further work with below.
1006 */
1007 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1008 {
1009 if (rib != fib)
1010 {
1011 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001012 zlog_debug ("%s: %s/%d: rn %p, removing rib %p", __func__,
1013 buf, rn->p.prefixlen, rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001014 rib_unlink (rn, rib);
1015 }
1016 else
1017 del = rib;
1018
1019 continue;
1020 }
paul4d38fdb2005-04-28 17:35:14 +00001021
paul718e3742002-12-13 20:15:29 +00001022 /* Skip unreachable nexthop. */
1023 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +00001024 continue;
paul718e3742002-12-13 20:15:29 +00001025
1026 /* Infinit distance. */
1027 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +00001028 continue;
paul718e3742002-12-13 20:15:29 +00001029
paulaf887b52006-01-18 14:52:52 +00001030 /* Newly selected rib, the common case. */
1031 if (!select)
1032 {
1033 select = rib;
1034 continue;
1035 }
1036
1037 /* filter route selection in following order:
paulaf887b52006-01-18 14:52:52 +00001038 * - connected beats other types
paula8d9c1f2006-01-25 06:31:04 +00001039 * - lower distance beats higher
paulaf887b52006-01-18 14:52:52 +00001040 * - lower metric beats higher for equal distance
1041 * - last, hence oldest, route wins tie break.
1042 */
paula1038a12006-01-30 14:08:51 +00001043
1044 /* Connected routes. Pick the last connected
1045 * route of the set of lowest metric connected routes.
1046 */
paula8d9c1f2006-01-25 06:31:04 +00001047 if (rib->type == ZEBRA_ROUTE_CONNECT)
1048 {
paula1038a12006-01-30 14:08:51 +00001049 if (select->type != ZEBRA_ROUTE_CONNECT
paula8d9c1f2006-01-25 06:31:04 +00001050 || rib->metric <= select->metric)
paula1038a12006-01-30 14:08:51 +00001051 select = rib;
1052 continue;
paula8d9c1f2006-01-25 06:31:04 +00001053 }
1054 else if (select->type == ZEBRA_ROUTE_CONNECT)
1055 continue;
1056
1057 /* higher distance loses */
1058 if (rib->distance > select->distance)
1059 continue;
1060
1061 /* lower wins */
1062 if (rib->distance < select->distance)
1063 {
paulaf887b52006-01-18 14:52:52 +00001064 select = rib;
paula8d9c1f2006-01-25 06:31:04 +00001065 continue;
1066 }
1067
1068 /* metric tie-breaks equal distance */
1069 if (rib->metric <= select->metric)
1070 select = rib;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001071 } /* for (rib = rn->info; rib; rib = next) */
1072
1073 /* After the cycle is finished, the following pointers will be set:
1074 * select --- the winner RIB entry, if any was found, otherwise NULL
1075 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1076 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1077 * rib --- NULL
1078 */
1079
1080 /* Same RIB entry is selected. Update FIB and finish. */
paul718e3742002-12-13 20:15:29 +00001081 if (select && select == fib)
1082 {
Paul Jakma6d691122006-07-27 21:49:00 +00001083 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001084 zlog_debug ("%s: %s/%d: Updating existing route, select %p, fib %p",
1085 __func__, buf, rn->p.prefixlen, select, fib);
paul718e3742002-12-13 20:15:29 +00001086 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +00001087 {
1088 redistribute_delete (&rn->p, select);
1089 if (! RIB_SYSTEM_ROUTE (select))
1090 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001091
paul4d38fdb2005-04-28 17:35:14 +00001092 /* Set real nexthop. */
1093 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +00001094
paul4d38fdb2005-04-28 17:35:14 +00001095 if (! RIB_SYSTEM_ROUTE (select))
1096 rib_install_kernel (rn, select);
1097 redistribute_add (&rn->p, select);
1098 }
pauld753e9e2003-01-22 19:45:50 +00001099 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001100 {
1101 /* Housekeeping code to deal with
1102 race conditions in kernel with linux
1103 netlink reporting interface up before IPv4 or IPv6 protocol
1104 is ready to add routes.
1105 This makes sure the routes are IN the kernel.
1106 */
pauld753e9e2003-01-22 19:45:50 +00001107
paul4d38fdb2005-04-28 17:35:14 +00001108 for (nexthop = select->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001109 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
paul4d38fdb2005-04-28 17:35:14 +00001110 {
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001111 installed = 1;
1112 break;
paul4d38fdb2005-04-28 17:35:14 +00001113 }
1114 if (! installed)
1115 rib_install_kernel (rn, select);
1116 }
Paul Jakma6d691122006-07-27 21:49:00 +00001117 goto end;
paul718e3742002-12-13 20:15:29 +00001118 }
1119
Denis Ovsienkodc958242007-08-13 16:03:06 +00001120 /* At this point we either haven't found the best RIB entry or it is
1121 * different from what we currently intend to flag with SELECTED. In both
1122 * cases, if a RIB block is present in FIB, it should be withdrawn.
1123 */
paul718e3742002-12-13 20:15:29 +00001124 if (fib)
1125 {
Paul Jakma6d691122006-07-27 21:49:00 +00001126 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001127 zlog_debug ("%s: %s/%d: Removing existing route, fib %p", __func__,
1128 buf, rn->p.prefixlen, fib);
paul718e3742002-12-13 20:15:29 +00001129 redistribute_delete (&rn->p, fib);
1130 if (! RIB_SYSTEM_ROUTE (fib))
1131 rib_uninstall_kernel (rn, fib);
1132 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1133
1134 /* Set real nexthop. */
1135 nexthop_active_update (rn, fib, 1);
1136 }
1137
Denis Ovsienkodc958242007-08-13 16:03:06 +00001138 /* Regardless of some RIB entry being SELECTED or not before, now we can
1139 * tell, that if a new winner exists, FIB is still not updated with this
1140 * data, but ready to be.
1141 */
paul718e3742002-12-13 20:15:29 +00001142 if (select)
1143 {
Paul Jakma6d691122006-07-27 21:49:00 +00001144 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001145 zlog_debug ("%s: %s/%d: Adding route, select %p", __func__, buf,
1146 rn->p.prefixlen, select);
paul718e3742002-12-13 20:15:29 +00001147 /* Set real nexthop. */
1148 nexthop_active_update (rn, select, 1);
1149
1150 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001151 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001152 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1153 redistribute_add (&rn->p, select);
1154 }
paul4d38fdb2005-04-28 17:35:14 +00001155
Paul Jakma6d691122006-07-27 21:49:00 +00001156 /* FIB route was removed, should be deleted */
1157 if (del)
1158 {
1159 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001160 zlog_debug ("%s: %s/%d: Deleting fib %p, rn %p", __func__, buf,
1161 rn->p.prefixlen, del, rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001162 rib_unlink (rn, del);
1163 }
paul4d38fdb2005-04-28 17:35:14 +00001164
Paul Jakma6d691122006-07-27 21:49:00 +00001165end:
1166 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma93bdada2007-08-06 19:25:11 +00001167 zlog_debug ("%s: %s/%d: rn %p dequeued", __func__, buf, rn->p.prefixlen, rn);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001168}
1169
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001170/* Take a list of route_node structs and return 1, if there was a record
1171 * picked from it and processed by rib_process(). Don't process more,
1172 * than one RN record; operate only in the specified sub-queue.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001173 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001174static unsigned int
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001175process_subq (struct list * subq, u_char qindex)
1176{
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001177 struct listnode *lnode = listhead (subq);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001178 struct route_node *rnode;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001179
1180 if (!lnode)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001181 return 0;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001182
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001183 rnode = listgetdata (lnode);
1184 rib_process (rnode);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001185
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001186 if (rnode->info) /* The first RIB record is holding the flags bitmask. */
1187 UNSET_FLAG (((struct rib *)rnode->info)->rn_status, RIB_ROUTE_QUEUED(qindex));
Chris Caputo67b94672009-07-18 04:02:26 +00001188#if 0
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001189 else
1190 {
1191 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1192 __func__, rnode, rnode->lock);
1193 zlog_backtrace(LOG_DEBUG);
1194 }
Chris Caputo67b94672009-07-18 04:02:26 +00001195#endif
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001196 route_unlock_node (rnode);
1197 list_delete_node (subq, lnode);
1198 return 1;
1199}
1200
1201/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1202 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1203 * is pointed to the meta queue structure.
1204 */
1205static wq_item_status
1206meta_queue_process (struct work_queue *dummy, void *data)
1207{
1208 struct meta_queue * mq = data;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001209 unsigned i;
1210
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001211 for (i = 0; i < MQ_SIZE; i++)
1212 if (process_subq (mq->subq[i], i))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001213 {
1214 mq->size--;
1215 break;
1216 }
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001217 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1218}
1219
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001220/* Map from rib types to queue type (priority) in meta queue */
1221static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
1222 [ZEBRA_ROUTE_SYSTEM] = 4,
1223 [ZEBRA_ROUTE_KERNEL] = 0,
1224 [ZEBRA_ROUTE_CONNECT] = 0,
1225 [ZEBRA_ROUTE_STATIC] = 1,
1226 [ZEBRA_ROUTE_RIP] = 2,
1227 [ZEBRA_ROUTE_RIPNG] = 2,
1228 [ZEBRA_ROUTE_OSPF] = 2,
1229 [ZEBRA_ROUTE_OSPF6] = 2,
1230 [ZEBRA_ROUTE_ISIS] = 2,
1231 [ZEBRA_ROUTE_BGP] = 3,
1232 [ZEBRA_ROUTE_HSLS] = 4,
1233};
1234
1235/* Look into the RN and queue it into one or more priority queues,
1236 * increasing the size for each data push done.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001237 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001238static void
1239rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001240{
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001241 struct rib *rib;
1242 char buf[INET6_ADDRSTRLEN];
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001243
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001244 if (IS_ZEBRA_DEBUG_RIB_Q)
1245 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001246
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001247 for (rib = rn->info; rib; rib = rib->next)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001248 {
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001249 u_char qindex = meta_queue_map[rib->type];
1250
1251 /* Invariant: at this point we always have rn->info set. */
1252 if (CHECK_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED(qindex)))
1253 {
1254 if (IS_ZEBRA_DEBUG_RIB_Q)
1255 zlog_debug ("%s: %s/%d: rn %p is already queued in sub-queue %u",
1256 __func__, buf, rn->p.prefixlen, rn, qindex);
1257 continue;
1258 }
1259
1260 SET_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED(qindex));
1261 listnode_add (mq->subq[qindex], rn);
1262 route_lock_node (rn);
1263 mq->size++;
1264
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001265 if (IS_ZEBRA_DEBUG_RIB_Q)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001266 zlog_debug ("%s: %s/%d: queued rn %p into sub-queue %u",
1267 __func__, buf, rn->p.prefixlen, rn, qindex);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001268 }
paul4d38fdb2005-04-28 17:35:14 +00001269}
1270
Paul Jakma6d691122006-07-27 21:49:00 +00001271/* Add route_node to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001272static void
Paul Jakma6d691122006-07-27 21:49:00 +00001273rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
paul4d38fdb2005-04-28 17:35:14 +00001274{
paul4d38fdb2005-04-28 17:35:14 +00001275
Paul Jakma93bdada2007-08-06 19:25:11 +00001276 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma6d691122006-07-27 21:49:00 +00001277 {
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001278 char buf[INET6_ADDRSTRLEN];
1279
1280 zlog_info ("%s: %s/%d: work queue added", __func__,
1281 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN),
1282 rn->p.prefixlen);
Paul Jakma6d691122006-07-27 21:49:00 +00001283 }
paul4d38fdb2005-04-28 17:35:14 +00001284
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001285 /*
1286 * The RIB queue should normally be either empty or holding the only
1287 * work_queue_item element. In the latter case this element would
1288 * hold a pointer to the meta queue structure, which must be used to
1289 * actually queue the route nodes to process. So create the MQ
1290 * holder, if necessary, then push the work into it in any case.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001291 * This semantics was introduced after 0.99.9 release.
1292 */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001293 if (!zebra->ribq->items->count)
1294 work_queue_add (zebra->ribq, zebra->mq);
1295
1296 rib_meta_queue_add (zebra->mq, rn);
paul4d38fdb2005-04-28 17:35:14 +00001297}
1298
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001299/* Create new meta queue.
1300 A destructor function doesn't seem to be necessary here.
1301 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001302static struct meta_queue *
1303meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001304{
1305 struct meta_queue *new;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001306 unsigned i;
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001307
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001308 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1309 assert(new);
1310
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001311 for (i = 0; i < MQ_SIZE; i++)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001312 {
1313 new->subq[i] = list_new ();
1314 assert(new->subq[i]);
1315 }
1316
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001317 return new;
1318}
1319
paul4d38fdb2005-04-28 17:35:14 +00001320/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001321static void
paul4d38fdb2005-04-28 17:35:14 +00001322rib_queue_init (struct zebra_t *zebra)
1323{
paul4d38fdb2005-04-28 17:35:14 +00001324 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001325 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001326 {
Paul Jakma6d691122006-07-27 21:49:00 +00001327 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001328 return;
1329 }
1330
1331 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001332 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001333 zebra->ribq->spec.errorfunc = NULL;
paul4d38fdb2005-04-28 17:35:14 +00001334 /* XXX: TODO: These should be runtime configurable via vty */
1335 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001336 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001337
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001338 if (!(zebra->mq = meta_queue_new ()))
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001339 zlog_err ("%s: could not initialise meta queue!", __func__);
paul718e3742002-12-13 20:15:29 +00001340}
1341
Paul Jakma6d691122006-07-27 21:49:00 +00001342/* RIB updates are processed via a queue of pointers to route_nodes.
1343 *
1344 * The queue length is bounded by the maximal size of the routing table,
1345 * as a route_node will not be requeued, if already queued.
1346 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001347 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1348 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1349 * and then submit route_node to queue for best-path selection later.
1350 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001351 *
1352 * Deleted RIBs are reaped during best-path selection.
1353 *
1354 * rib_addnode
1355 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001356 * |-------->| | best RIB, if required
1357 * | |
1358 * static_install->|->rib_addqueue...... -> rib_process
1359 * | |
1360 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001361 * |-> set RIB_ENTRY_REMOVE |
1362 * rib_delnode (RIB freed)
1363 *
1364 *
1365 * Queueing state for a route_node is kept in the head RIB entry, this
1366 * state must be preserved as and when the head RIB entry of a
1367 * route_node is changed by rib_unlink / rib_link. A small complication,
1368 * but saves having to allocate a dedicated object for this.
1369 *
1370 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1371 *
1372 * - route_nodes: refcounted by:
1373 * - RIBs attached to route_node:
1374 * - managed by: rib_link/unlink
1375 * - route_node processing queue
1376 * - managed by: rib_addqueue, rib_process.
1377 *
1378 */
1379
paul718e3742002-12-13 20:15:29 +00001380/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001381static void
Paul Jakma6d691122006-07-27 21:49:00 +00001382rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001383{
1384 struct rib *head;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001385 char buf[INET6_ADDRSTRLEN];
paul4d38fdb2005-04-28 17:35:14 +00001386
1387 assert (rib && rn);
1388
Paul Jakma6d691122006-07-27 21:49:00 +00001389 route_lock_node (rn); /* rn route table reference */
1390
1391 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001392 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001393 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001394 zlog_debug ("%s: %s/%d: rn %p, rib %p", __func__,
1395 buf, rn->p.prefixlen, rn, rib);
1396 }
Paul Jakma6d691122006-07-27 21:49:00 +00001397
paul718e3742002-12-13 20:15:29 +00001398 head = rn->info;
1399 if (head)
Paul Jakma6d691122006-07-27 21:49:00 +00001400 {
1401 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001402 zlog_debug ("%s: %s/%d: new head, rn_status copied over", __func__,
1403 buf, rn->p.prefixlen);
Paul Jakma6d691122006-07-27 21:49:00 +00001404 head->prev = rib;
1405 /* Transfer the rn status flags to the new head RIB */
1406 rib->rn_status = head->rn_status;
1407 }
paul718e3742002-12-13 20:15:29 +00001408 rib->next = head;
1409 rn->info = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001410 rib_queue_add (&zebrad, rn);
1411}
1412
1413static void
1414rib_addnode (struct route_node *rn, struct rib *rib)
1415{
1416 /* RIB node has been un-removed before route-node is processed.
1417 * route_node must hence already be on the queue for processing..
1418 */
1419 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1420 {
1421 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001422 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001423 char buf[INET6_ADDRSTRLEN];
1424 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001425 zlog_debug ("%s: %s/%d: rn %p, un-removed rib %p",
1426 __func__, buf, rn->p.prefixlen, rn, rib);
1427 }
Paul Jakma6d691122006-07-27 21:49:00 +00001428 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1429 return;
1430 }
1431 rib_link (rn, rib);
1432}
1433
1434static void
1435rib_unlink (struct route_node *rn, struct rib *rib)
1436{
1437 struct nexthop *nexthop, *next;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001438 char buf[INET6_ADDRSTRLEN];
Paul Jakma6d691122006-07-27 21:49:00 +00001439
1440 assert (rn && rib);
1441
1442 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001443 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001444 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001445 zlog_debug ("%s: %s/%d: rn %p, rib %p",
1446 __func__, buf, rn->p.prefixlen, rn, rib);
1447 }
Paul Jakma6d691122006-07-27 21:49:00 +00001448
1449 if (rib->next)
1450 rib->next->prev = rib->prev;
1451
1452 if (rib->prev)
1453 rib->prev->next = rib->next;
1454 else
1455 {
1456 rn->info = rib->next;
1457
1458 if (rn->info)
1459 {
1460 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001461 zlog_debug ("%s: %s/%d: rn %p, rib %p, new head copy",
1462 __func__, buf, rn->p.prefixlen, rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001463 rib->next->rn_status = rib->rn_status;
1464 }
1465 }
1466
1467 /* free RIB and nexthops */
1468 for (nexthop = rib->nexthop; nexthop; nexthop = next)
1469 {
1470 next = nexthop->next;
1471 nexthop_free (nexthop);
1472 }
1473 XFREE (MTYPE_RIB, rib);
1474
1475 route_unlock_node (rn); /* rn route table reference */
paul718e3742002-12-13 20:15:29 +00001476}
1477
paula1ac18c2005-06-28 17:17:12 +00001478static void
paul718e3742002-12-13 20:15:29 +00001479rib_delnode (struct route_node *rn, struct rib *rib)
1480{
Paul Jakma6d691122006-07-27 21:49:00 +00001481 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001482 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001483 char buf[INET6_ADDRSTRLEN];
1484 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001485 zlog_debug ("%s: %s/%d: rn %p, rib %p, removing", __func__,
1486 buf, rn->p.prefixlen, rn, rib);
1487 }
Paul Jakma6d691122006-07-27 21:49:00 +00001488 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1489 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001490}
1491
1492int
1493rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001494 struct in_addr *gate, struct in_addr *src,
1495 unsigned int ifindex, u_int32_t vrf_id,
paul718e3742002-12-13 20:15:29 +00001496 u_int32_t metric, u_char distance)
1497{
1498 struct rib *rib;
1499 struct rib *same = NULL;
1500 struct route_table *table;
1501 struct route_node *rn;
1502 struct nexthop *nexthop;
1503
1504 /* Lookup table. */
1505 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1506 if (! table)
1507 return 0;
1508
1509 /* Make it sure prefixlen is applied to the prefix. */
1510 apply_mask_ipv4 (p);
1511
1512 /* Set default distance by route type. */
1513 if (distance == 0)
1514 {
David Lamparter7052f222009-08-27 00:28:28 +02001515 if ((unsigned)type >= sizeof(route_info) / sizeof(route_info[0]))
1516 distance = 150;
1517 else
1518 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00001519
1520 /* iBGP distance is 200. */
1521 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1522 distance = 200;
1523 }
1524
1525 /* Lookup route node.*/
1526 rn = route_node_get (table, (struct prefix *) p);
1527
1528 /* If same type of route are installed, treat it as a implicit
1529 withdraw. */
1530 for (rib = rn->info; rib; rib = rib->next)
1531 {
Paul Jakma6d691122006-07-27 21:49:00 +00001532 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1533 continue;
1534
hassoebf1ead2005-09-21 14:58:20 +00001535 if (rib->type != type)
1536 continue;
1537 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001538 {
1539 same = rib;
1540 break;
1541 }
hassoebf1ead2005-09-21 14:58:20 +00001542 /* Duplicate connected route comes in. */
1543 else if ((nexthop = rib->nexthop) &&
1544 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001545 nexthop->ifindex == ifindex &&
1546 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001547 {
1548 rib->refcnt++;
1549 return 0 ;
1550 }
paul718e3742002-12-13 20:15:29 +00001551 }
1552
1553 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001554 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001555 rib->type = type;
1556 rib->distance = distance;
1557 rib->flags = flags;
1558 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001559 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001560 rib->nexthop_num = 0;
1561 rib->uptime = time (NULL);
1562
1563 /* Nexthop settings. */
1564 if (gate)
1565 {
1566 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001567 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001568 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001569 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001570 }
1571 else
1572 nexthop_ifindex_add (rib, ifindex);
1573
1574 /* If this route is kernel route, set FIB flag to the route. */
1575 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1576 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1577 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1578
1579 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001580 if (IS_ZEBRA_DEBUG_RIB)
1581 zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
paul718e3742002-12-13 20:15:29 +00001582 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001583
paul718e3742002-12-13 20:15:29 +00001584 /* Free implicit route.*/
1585 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001586 {
1587 if (IS_ZEBRA_DEBUG_RIB)
1588 zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001589 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001590 }
paul4d38fdb2005-04-28 17:35:14 +00001591
1592 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001593 return 0;
1594}
1595
Denis Ovsienkodc958242007-08-13 16:03:06 +00001596/* This function dumps the contents of a given RIB entry into
1597 * standard debug log. Calling function name and IP prefix in
1598 * question are passed as 1st and 2nd arguments.
1599 */
1600
1601void rib_dump (const char * func, const struct prefix_ipv4 * p, const struct rib * rib)
1602{
1603 char straddr1[INET_ADDRSTRLEN], straddr2[INET_ADDRSTRLEN];
1604 struct nexthop *nexthop;
1605
1606 inet_ntop (AF_INET, &p->prefix, straddr1, INET_ADDRSTRLEN);
1607 zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr1, p->prefixlen);
1608 zlog_debug
1609 (
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001610 "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
Denis Ovsienkodc958242007-08-13 16:03:06 +00001611 func,
1612 rib->refcnt,
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001613 (unsigned long) rib->uptime,
Denis Ovsienkodc958242007-08-13 16:03:06 +00001614 rib->type,
1615 rib->table
1616 );
1617 zlog_debug
1618 (
1619 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1620 func,
1621 rib->metric,
1622 rib->distance,
1623 rib->flags,
1624 rib->status
1625 );
1626 zlog_debug
1627 (
1628 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1629 func,
1630 rib->nexthop_num,
1631 rib->nexthop_active_num,
1632 rib->nexthop_fib_num
1633 );
1634 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1635 {
1636 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, straddr1, INET_ADDRSTRLEN);
1637 inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, straddr2, INET_ADDRSTRLEN);
1638 zlog_debug
1639 (
1640 "%s: NH %s (%s) with flags %s%s%s",
1641 func,
1642 straddr1,
1643 straddr2,
1644 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1645 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1646 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1647 );
1648 }
1649 zlog_debug ("%s: dump complete", func);
1650}
1651
1652/* This is an exported helper to rtm_read() to dump the strange
1653 * RIB entry found by rib_lookup_ipv4_route()
1654 */
1655
1656void rib_lookup_and_dump (struct prefix_ipv4 * p)
1657{
1658 struct route_table *table;
1659 struct route_node *rn;
1660 struct rib *rib;
1661 char prefix_buf[INET_ADDRSTRLEN];
1662
1663 /* Lookup table. */
1664 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1665 if (! table)
1666 {
1667 zlog_err ("%s: vrf_table() returned NULL", __func__);
1668 return;
1669 }
1670
1671 inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
1672 /* Scan the RIB table for exactly matching RIB entry. */
1673 rn = route_node_lookup (table, (struct prefix *) p);
1674
1675 /* No route for this prefix. */
1676 if (! rn)
1677 {
1678 zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
1679 return;
1680 }
1681
1682 /* Unlock node. */
1683 route_unlock_node (rn);
1684
1685 /* let's go */
1686 for (rib = rn->info; rib; rib = rib->next)
1687 {
1688 zlog_debug
1689 (
1690 "%s: rn %p, rib %p: %s, %s",
1691 __func__,
1692 rn,
1693 rib,
1694 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
1695 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
1696 );
1697 rib_dump (__func__, p, rib);
1698 }
1699}
1700
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001701/* Check if requested address assignment will fail due to another
1702 * route being installed by zebra in FIB already. Take necessary
1703 * actions, if needed: remove such a route from FIB and deSELECT
1704 * corresponding RIB entry. Then put affected RN into RIBQ head.
1705 */
1706void rib_lookup_and_pushup (struct prefix_ipv4 * p)
1707{
1708 struct route_table *table;
1709 struct route_node *rn;
1710 struct rib *rib;
1711 unsigned changed = 0;
1712
1713 if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
1714 {
1715 zlog_err ("%s: vrf_table() returned NULL", __func__);
1716 return;
1717 }
1718
1719 /* No matches would be the simplest case. */
1720 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
1721 return;
1722
1723 /* Unlock node. */
1724 route_unlock_node (rn);
1725
1726 /* Check all RIB entries. In case any changes have to be done, requeue
1727 * the RN into RIBQ head. If the routing message about the new connected
1728 * route (generated by the IP address we are going to assign very soon)
1729 * comes before the RIBQ is processed, the new RIB entry will join
1730 * RIBQ record already on head. This is necessary for proper revalidation
1731 * of the rest of the RIB.
1732 */
1733 for (rib = rn->info; rib; rib = rib->next)
1734 {
1735 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
1736 ! RIB_SYSTEM_ROUTE (rib))
1737 {
1738 changed = 1;
1739 if (IS_ZEBRA_DEBUG_RIB)
1740 {
1741 char buf[INET_ADDRSTRLEN];
1742 inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
1743 zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
1744 rib_dump (__func__, (struct prefix_ipv4 *)&rn->p, rib);
1745 }
1746 rib_uninstall (rn, rib);
1747 }
1748 }
1749 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001750 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001751}
1752
paul718e3742002-12-13 20:15:29 +00001753int
1754rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib)
1755{
1756 struct route_table *table;
1757 struct route_node *rn;
1758 struct rib *same;
1759 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00001760
paul718e3742002-12-13 20:15:29 +00001761 /* Lookup table. */
1762 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1763 if (! table)
1764 return 0;
paul718e3742002-12-13 20:15:29 +00001765 /* Make it sure prefixlen is applied to the prefix. */
1766 apply_mask_ipv4 (p);
1767
1768 /* Set default distance by route type. */
1769 if (rib->distance == 0)
1770 {
1771 rib->distance = route_info[rib->type].distance;
1772
1773 /* iBGP distance is 200. */
1774 if (rib->type == ZEBRA_ROUTE_BGP
1775 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1776 rib->distance = 200;
1777 }
1778
1779 /* Lookup route node.*/
1780 rn = route_node_get (table, (struct prefix *) p);
1781
1782 /* If same type of route are installed, treat it as a implicit
1783 withdraw. */
1784 for (same = rn->info; same; same = same->next)
1785 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00001786 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00001787 continue;
1788
paul718e3742002-12-13 20:15:29 +00001789 if (same->type == rib->type && same->table == rib->table
1790 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001791 break;
paul718e3742002-12-13 20:15:29 +00001792 }
paul4d38fdb2005-04-28 17:35:14 +00001793
paul718e3742002-12-13 20:15:29 +00001794 /* If this route is kernel route, set FIB flag to the route. */
1795 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
1796 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1797 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1798
1799 /* Link new rib to node.*/
1800 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001801 if (IS_ZEBRA_DEBUG_RIB)
1802 {
1803 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
1804 __func__, rn, rib);
1805 rib_dump (__func__, p, rib);
1806 }
paul718e3742002-12-13 20:15:29 +00001807
paul718e3742002-12-13 20:15:29 +00001808 /* Free implicit route.*/
1809 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001810 {
1811 if (IS_ZEBRA_DEBUG_RIB)
1812 {
1813 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
1814 __func__, rn, same);
1815 rib_dump (__func__, p, same);
1816 }
paul4d38fdb2005-04-28 17:35:14 +00001817 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001818 }
paul4d38fdb2005-04-28 17:35:14 +00001819
1820 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001821 return 0;
1822}
1823
hassoebf1ead2005-09-21 14:58:20 +00001824/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00001825int
1826rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
1827 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1828{
1829 struct route_table *table;
1830 struct route_node *rn;
1831 struct rib *rib;
1832 struct rib *fib = NULL;
1833 struct rib *same = NULL;
1834 struct nexthop *nexthop;
Stephen Hemminger81cce012009-04-28 14:28:00 -07001835 char buf1[INET_ADDRSTRLEN];
1836 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00001837
1838 /* Lookup table. */
1839 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1840 if (! table)
1841 return 0;
1842
1843 /* Apply mask. */
1844 apply_mask_ipv4 (p);
1845
paul5ec90d22003-06-19 01:41:37 +00001846 if (IS_ZEBRA_DEBUG_KERNEL && gate)
ajsb6178002004-12-07 21:12:56 +00001847 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001848 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul5ec90d22003-06-19 01:41:37 +00001849 p->prefixlen,
1850 inet_ntoa (*gate),
1851 ifindex);
1852
paul718e3742002-12-13 20:15:29 +00001853 /* Lookup route node. */
1854 rn = route_node_lookup (table, (struct prefix *) p);
1855 if (! rn)
1856 {
1857 if (IS_ZEBRA_DEBUG_KERNEL)
1858 {
1859 if (gate)
ajsb6178002004-12-07 21:12:56 +00001860 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001861 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001862 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07001863 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001864 ifindex);
1865 else
ajsb6178002004-12-07 21:12:56 +00001866 zlog_debug ("route %s/%d 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,
1869 ifindex);
1870 }
1871 return ZEBRA_ERR_RTNOEXIST;
1872 }
1873
1874 /* Lookup same type route. */
1875 for (rib = rn->info; rib; rib = rib->next)
1876 {
Paul Jakma6d691122006-07-27 21:49:00 +00001877 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1878 continue;
1879
paul718e3742002-12-13 20:15:29 +00001880 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1881 fib = rib;
1882
hassoebf1ead2005-09-21 14:58:20 +00001883 if (rib->type != type)
1884 continue;
1885 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
1886 nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex)
paul718e3742002-12-13 20:15:29 +00001887 {
hassoebf1ead2005-09-21 14:58:20 +00001888 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00001889 {
hassoebf1ead2005-09-21 14:58:20 +00001890 rib->refcnt--;
1891 route_unlock_node (rn);
1892 route_unlock_node (rn);
1893 return 0;
paul718e3742002-12-13 20:15:29 +00001894 }
hassoebf1ead2005-09-21 14:58:20 +00001895 same = rib;
1896 break;
paul718e3742002-12-13 20:15:29 +00001897 }
hassoebf1ead2005-09-21 14:58:20 +00001898 /* Make sure that the route found has the same gateway. */
1899 else if (gate == NULL ||
1900 ((nexthop = rib->nexthop) &&
1901 (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
1902 IPV4_ADDR_SAME (&nexthop->rgate.ipv4, gate))))
paul5ec90d22003-06-19 01:41:37 +00001903 {
hassoebf1ead2005-09-21 14:58:20 +00001904 same = rib;
1905 break;
paul718e3742002-12-13 20:15:29 +00001906 }
1907 }
1908
1909 /* If same type of route can't be found and this message is from
1910 kernel. */
1911 if (! same)
1912 {
1913 if (fib && type == ZEBRA_ROUTE_KERNEL)
1914 {
1915 /* Unset flags. */
1916 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1917 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1918
1919 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1920 }
1921 else
1922 {
1923 if (IS_ZEBRA_DEBUG_KERNEL)
1924 {
1925 if (gate)
ajsb6178002004-12-07 21:12:56 +00001926 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001927 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001928 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07001929 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001930 ifindex,
1931 type);
1932 else
ajsb6178002004-12-07 21:12:56 +00001933 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001934 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001935 p->prefixlen,
1936 ifindex,
1937 type);
1938 }
1939 route_unlock_node (rn);
1940 return ZEBRA_ERR_RTNOEXIST;
1941 }
1942 }
paul4d38fdb2005-04-28 17:35:14 +00001943
paul718e3742002-12-13 20:15:29 +00001944 if (same)
1945 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00001946
paul718e3742002-12-13 20:15:29 +00001947 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001948 return 0;
1949}
1950
1951/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00001952static void
paul718e3742002-12-13 20:15:29 +00001953static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
1954{
1955 struct rib *rib;
1956 struct route_node *rn;
1957 struct route_table *table;
1958
1959 /* Lookup table. */
1960 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1961 if (! table)
1962 return;
1963
1964 /* Lookup existing route */
1965 rn = route_node_get (table, p);
1966 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00001967 {
1968 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1969 continue;
1970
1971 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1972 break;
1973 }
paul718e3742002-12-13 20:15:29 +00001974
1975 if (rib)
1976 {
1977 /* Same distance static route is there. Update it with new
1978 nexthop. */
paul718e3742002-12-13 20:15:29 +00001979 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001980 switch (si->type)
paul7021c422003-07-15 12:52:22 +00001981 {
1982 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00001983 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00001984 break;
1985 case STATIC_IPV4_IFNAME:
1986 nexthop_ifname_add (rib, si->gate.ifname);
1987 break;
1988 case STATIC_IPV4_BLACKHOLE:
1989 nexthop_blackhole_add (rib);
1990 break;
paul4d38fdb2005-04-28 17:35:14 +00001991 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00001992 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001993 }
1994 else
1995 {
1996 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00001997 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
1998
paul718e3742002-12-13 20:15:29 +00001999 rib->type = ZEBRA_ROUTE_STATIC;
2000 rib->distance = si->distance;
2001 rib->metric = 0;
2002 rib->nexthop_num = 0;
2003
2004 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002005 {
2006 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002007 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002008 break;
2009 case STATIC_IPV4_IFNAME:
2010 nexthop_ifname_add (rib, si->gate.ifname);
2011 break;
2012 case STATIC_IPV4_BLACKHOLE:
2013 nexthop_blackhole_add (rib);
2014 break;
2015 }
paul718e3742002-12-13 20:15:29 +00002016
hasso81dfcaa2003-05-25 19:21:25 +00002017 /* Save the flags of this static routes (reject, blackhole) */
2018 rib->flags = si->flags;
2019
paul718e3742002-12-13 20:15:29 +00002020 /* Link this rib to the tree. */
2021 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002022 }
2023}
2024
paula1ac18c2005-06-28 17:17:12 +00002025static int
paul718e3742002-12-13 20:15:29 +00002026static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2027{
2028 if (nexthop->type == NEXTHOP_TYPE_IPV4
2029 && si->type == STATIC_IPV4_GATEWAY
2030 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2031 return 1;
2032 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2033 && si->type == STATIC_IPV4_IFNAME
2034 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2035 return 1;
paul595db7f2003-05-25 21:35:06 +00002036 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2037 && si->type == STATIC_IPV4_BLACKHOLE)
2038 return 1;
paule8e19462006-01-19 20:16:55 +00002039 return 0;
paul718e3742002-12-13 20:15:29 +00002040}
2041
2042/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002043static void
paul718e3742002-12-13 20:15:29 +00002044static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
2045{
2046 struct route_node *rn;
2047 struct rib *rib;
2048 struct nexthop *nexthop;
2049 struct route_table *table;
2050
2051 /* Lookup table. */
2052 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2053 if (! table)
2054 return;
paul4d38fdb2005-04-28 17:35:14 +00002055
paul718e3742002-12-13 20:15:29 +00002056 /* Lookup existing route with type and distance. */
2057 rn = route_node_lookup (table, p);
2058 if (! rn)
2059 return;
2060
2061 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002062 {
2063 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2064 continue;
2065
2066 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2067 break;
2068 }
paul718e3742002-12-13 20:15:29 +00002069
2070 if (! rib)
2071 {
2072 route_unlock_node (rn);
2073 return;
2074 }
2075
2076 /* Lookup nexthop. */
2077 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2078 if (static_ipv4_nexthop_same (nexthop, si))
2079 break;
2080
2081 /* Can't find nexthop. */
2082 if (! nexthop)
2083 {
2084 route_unlock_node (rn);
2085 return;
2086 }
2087
2088 /* Check nexthop. */
2089 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002090 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002091 else
2092 {
paul6baeb982003-10-28 03:47:15 +00002093 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2094 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002095 nexthop_delete (rib, nexthop);
2096 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002097 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002098 }
paul718e3742002-12-13 20:15:29 +00002099 /* Unlock node. */
2100 route_unlock_node (rn);
2101}
2102
2103/* Add static route into static route configuration. */
2104int
hasso39db97e2004-10-12 20:50:58 +00002105static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00002106 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002107{
2108 u_char type = 0;
2109 struct route_node *rn;
2110 struct static_ipv4 *si;
2111 struct static_ipv4 *pp;
2112 struct static_ipv4 *cp;
2113 struct static_ipv4 *update = NULL;
2114 struct route_table *stable;
2115
2116 /* Lookup table. */
2117 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2118 if (! stable)
2119 return -1;
2120
2121 /* Lookup static route prefix. */
2122 rn = route_node_get (stable, p);
2123
2124 /* Make flags. */
2125 if (gate)
2126 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002127 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002128 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002129 else
2130 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002131
2132 /* Do nothing if there is a same static route. */
2133 for (si = rn->info; si; si = si->next)
2134 {
2135 if (type == si->type
2136 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2137 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2138 {
2139 if (distance == si->distance)
2140 {
2141 route_unlock_node (rn);
2142 return 0;
2143 }
2144 else
2145 update = si;
2146 }
2147 }
2148
Paul Jakma3c0755d2006-12-08 00:53:14 +00002149 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002150 if (update)
2151 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
2152
2153 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002154 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
paul718e3742002-12-13 20:15:29 +00002155
2156 si->type = type;
2157 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002158 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002159
2160 if (gate)
2161 si->gate.ipv4 = *gate;
2162 if (ifname)
2163 si->gate.ifname = XSTRDUP (0, ifname);
2164
2165 /* Add new static route information to the tree with sort by
2166 distance value and gateway address. */
2167 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2168 {
2169 if (si->distance < cp->distance)
2170 break;
2171 if (si->distance > cp->distance)
2172 continue;
2173 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2174 {
2175 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2176 break;
2177 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2178 continue;
2179 }
2180 }
2181
2182 /* Make linked list. */
2183 if (pp)
2184 pp->next = si;
2185 else
2186 rn->info = si;
2187 if (cp)
2188 cp->prev = si;
2189 si->prev = pp;
2190 si->next = cp;
2191
2192 /* Install into rib. */
2193 static_install_ipv4 (p, si);
2194
2195 return 1;
2196}
2197
2198/* Delete static route from static route configuration. */
2199int
hasso39db97e2004-10-12 20:50:58 +00002200static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00002201 u_char distance, u_int32_t vrf_id)
2202{
2203 u_char type = 0;
2204 struct route_node *rn;
2205 struct static_ipv4 *si;
2206 struct route_table *stable;
2207
2208 /* Lookup table. */
2209 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2210 if (! stable)
2211 return -1;
2212
2213 /* Lookup static route prefix. */
2214 rn = route_node_lookup (stable, p);
2215 if (! rn)
2216 return 0;
2217
2218 /* Make flags. */
2219 if (gate)
2220 type = STATIC_IPV4_GATEWAY;
2221 else if (ifname)
2222 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002223 else
2224 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002225
2226 /* Find same static route is the tree */
2227 for (si = rn->info; si; si = si->next)
2228 if (type == si->type
2229 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2230 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2231 break;
2232
2233 /* Can't find static route. */
2234 if (! si)
2235 {
2236 route_unlock_node (rn);
2237 return 0;
2238 }
2239
2240 /* Install into rib. */
2241 static_uninstall_ipv4 (p, si);
2242
2243 /* Unlink static route from linked list. */
2244 if (si->prev)
2245 si->prev->next = si->next;
2246 else
2247 rn->info = si->next;
2248 if (si->next)
2249 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002250 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002251
2252 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002253 if (ifname)
2254 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002255 XFREE (MTYPE_STATIC_IPV4, si);
2256
paul143a3852003-09-29 20:06:13 +00002257 route_unlock_node (rn);
2258
paul718e3742002-12-13 20:15:29 +00002259 return 1;
2260}
2261
2262
2263#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00002264static int
paul718e3742002-12-13 20:15:29 +00002265rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2266 struct in6_addr *gate, unsigned int ifindex, int table)
2267{
hasso726f9b22003-05-25 21:04:54 +00002268 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2269#if defined (MUSICA) || defined (LINUX)
2270 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2271 if (p->prefixlen == 96)
2272 return 0;
2273#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00002274 return 1;
hasso726f9b22003-05-25 21:04:54 +00002275 }
paul718e3742002-12-13 20:15:29 +00002276 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
2277 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
2278 {
2279 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
2280 return 1;
2281 }
2282 return 0;
2283}
2284
2285int
2286rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00002287 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
2288 u_int32_t metric, u_char distance)
paul718e3742002-12-13 20:15:29 +00002289{
2290 struct rib *rib;
2291 struct rib *same = NULL;
2292 struct route_table *table;
2293 struct route_node *rn;
2294 struct nexthop *nexthop;
2295
paul718e3742002-12-13 20:15:29 +00002296 /* Lookup table. */
2297 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2298 if (! table)
2299 return 0;
2300
2301 /* Make sure mask is applied. */
2302 apply_mask_ipv6 (p);
2303
2304 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002305 if (!distance)
2306 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002307
2308 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2309 distance = 200;
2310
2311 /* Filter bogus route. */
2312 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
2313 return 0;
2314
2315 /* Lookup route node.*/
2316 rn = route_node_get (table, (struct prefix *) p);
2317
2318 /* If same type of route are installed, treat it as a implicit
2319 withdraw. */
2320 for (rib = rn->info; rib; rib = rib->next)
2321 {
Paul Jakma6d691122006-07-27 21:49:00 +00002322 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2323 continue;
2324
hassoebf1ead2005-09-21 14:58:20 +00002325 if (rib->type != type)
2326 continue;
2327 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002328 {
2329 same = rib;
paul718e3742002-12-13 20:15:29 +00002330 break;
2331 }
hassoebf1ead2005-09-21 14:58:20 +00002332 else if ((nexthop = rib->nexthop) &&
2333 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2334 nexthop->ifindex == ifindex)
2335 {
2336 rib->refcnt++;
2337 return 0;
2338 }
paul718e3742002-12-13 20:15:29 +00002339 }
2340
2341 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002342 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2343
paul718e3742002-12-13 20:15:29 +00002344 rib->type = type;
2345 rib->distance = distance;
2346 rib->flags = flags;
2347 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00002348 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00002349 rib->nexthop_num = 0;
2350 rib->uptime = time (NULL);
2351
2352 /* Nexthop settings. */
2353 if (gate)
2354 {
2355 if (ifindex)
2356 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2357 else
2358 nexthop_ipv6_add (rib, gate);
2359 }
2360 else
2361 nexthop_ifindex_add (rib, ifindex);
2362
2363 /* If this route is kernel route, set FIB flag to the route. */
2364 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2365 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2366 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2367
2368 /* Link new rib to node.*/
2369 rib_addnode (rn, rib);
2370
paul718e3742002-12-13 20:15:29 +00002371 /* Free implicit route.*/
2372 if (same)
paul4d38fdb2005-04-28 17:35:14 +00002373 rib_delnode (rn, same);
2374
2375 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002376 return 0;
2377}
2378
hassoebf1ead2005-09-21 14:58:20 +00002379/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002380int
2381rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
2382 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
2383{
2384 struct route_table *table;
2385 struct route_node *rn;
2386 struct rib *rib;
2387 struct rib *fib = NULL;
2388 struct rib *same = NULL;
2389 struct nexthop *nexthop;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002390 char buf1[INET6_ADDRSTRLEN];
2391 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002392
2393 /* Apply mask. */
2394 apply_mask_ipv6 (p);
2395
2396 /* Lookup table. */
2397 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2398 if (! table)
2399 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002400
paul718e3742002-12-13 20:15:29 +00002401 /* Lookup route node. */
2402 rn = route_node_lookup (table, (struct prefix *) p);
2403 if (! rn)
2404 {
2405 if (IS_ZEBRA_DEBUG_KERNEL)
2406 {
2407 if (gate)
ajsb6178002004-12-07 21:12:56 +00002408 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002409 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002410 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002411 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002412 ifindex);
2413 else
ajsb6178002004-12-07 21:12:56 +00002414 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002415 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002416 p->prefixlen,
2417 ifindex);
2418 }
2419 return ZEBRA_ERR_RTNOEXIST;
2420 }
2421
2422 /* Lookup same type route. */
2423 for (rib = rn->info; rib; rib = rib->next)
2424 {
Paul Jakma6d691122006-07-27 21:49:00 +00002425 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2426 continue;
2427
paul718e3742002-12-13 20:15:29 +00002428 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2429 fib = rib;
2430
hassoebf1ead2005-09-21 14:58:20 +00002431 if (rib->type != type)
2432 continue;
2433 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
2434 nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex)
paul718e3742002-12-13 20:15:29 +00002435 {
hassoebf1ead2005-09-21 14:58:20 +00002436 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002437 {
hassoebf1ead2005-09-21 14:58:20 +00002438 rib->refcnt--;
2439 route_unlock_node (rn);
2440 route_unlock_node (rn);
2441 return 0;
paul718e3742002-12-13 20:15:29 +00002442 }
hassoebf1ead2005-09-21 14:58:20 +00002443 same = rib;
2444 break;
paul718e3742002-12-13 20:15:29 +00002445 }
hassoebf1ead2005-09-21 14:58:20 +00002446 /* Make sure that the route found has the same gateway. */
2447 else if (gate == NULL ||
2448 ((nexthop = rib->nexthop) &&
2449 (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate) ||
2450 IPV6_ADDR_SAME (&nexthop->rgate.ipv6, gate))))
paul718e3742002-12-13 20:15:29 +00002451 {
hassoebf1ead2005-09-21 14:58:20 +00002452 same = rib;
2453 break;
paul718e3742002-12-13 20:15:29 +00002454 }
2455 }
2456
2457 /* If same type of route can't be found and this message is from
2458 kernel. */
2459 if (! same)
2460 {
2461 if (fib && type == ZEBRA_ROUTE_KERNEL)
2462 {
2463 /* Unset flags. */
2464 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2465 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2466
2467 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2468 }
2469 else
2470 {
2471 if (IS_ZEBRA_DEBUG_KERNEL)
2472 {
2473 if (gate)
ajsb6178002004-12-07 21:12:56 +00002474 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002475 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002476 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002477 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002478 ifindex,
2479 type);
2480 else
ajsb6178002004-12-07 21:12:56 +00002481 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002482 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002483 p->prefixlen,
2484 ifindex,
2485 type);
2486 }
2487 route_unlock_node (rn);
2488 return ZEBRA_ERR_RTNOEXIST;
2489 }
2490 }
2491
2492 if (same)
2493 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002494
paul718e3742002-12-13 20:15:29 +00002495 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002496 return 0;
2497}
2498
2499/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002500static void
paul718e3742002-12-13 20:15:29 +00002501static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2502{
2503 struct rib *rib;
2504 struct route_table *table;
2505 struct route_node *rn;
2506
2507 /* Lookup table. */
2508 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2509 if (! table)
2510 return;
2511
2512 /* Lookup existing route */
2513 rn = route_node_get (table, p);
2514 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002515 {
2516 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2517 continue;
2518
2519 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2520 break;
2521 }
paul718e3742002-12-13 20:15:29 +00002522
2523 if (rib)
2524 {
2525 /* Same distance static route is there. Update it with new
2526 nexthop. */
paul718e3742002-12-13 20:15:29 +00002527 route_unlock_node (rn);
2528
2529 switch (si->type)
2530 {
2531 case STATIC_IPV6_GATEWAY:
2532 nexthop_ipv6_add (rib, &si->ipv6);
2533 break;
2534 case STATIC_IPV6_IFNAME:
2535 nexthop_ifname_add (rib, si->ifname);
2536 break;
2537 case STATIC_IPV6_GATEWAY_IFNAME:
2538 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2539 break;
2540 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002541 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002542 }
2543 else
2544 {
2545 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002546 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2547
paul718e3742002-12-13 20:15:29 +00002548 rib->type = ZEBRA_ROUTE_STATIC;
2549 rib->distance = si->distance;
2550 rib->metric = 0;
2551 rib->nexthop_num = 0;
2552
2553 switch (si->type)
2554 {
2555 case STATIC_IPV6_GATEWAY:
2556 nexthop_ipv6_add (rib, &si->ipv6);
2557 break;
2558 case STATIC_IPV6_IFNAME:
2559 nexthop_ifname_add (rib, si->ifname);
2560 break;
2561 case STATIC_IPV6_GATEWAY_IFNAME:
2562 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2563 break;
2564 }
2565
hasso81dfcaa2003-05-25 19:21:25 +00002566 /* Save the flags of this static routes (reject, blackhole) */
2567 rib->flags = si->flags;
2568
paul718e3742002-12-13 20:15:29 +00002569 /* Link this rib to the tree. */
2570 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002571 }
2572}
2573
paula1ac18c2005-06-28 17:17:12 +00002574static int
paul718e3742002-12-13 20:15:29 +00002575static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2576{
2577 if (nexthop->type == NEXTHOP_TYPE_IPV6
2578 && si->type == STATIC_IPV6_GATEWAY
2579 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2580 return 1;
2581 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2582 && si->type == STATIC_IPV6_IFNAME
2583 && strcmp (nexthop->ifname, si->ifname) == 0)
2584 return 1;
2585 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2586 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2587 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2588 && strcmp (nexthop->ifname, si->ifname) == 0)
2589 return 1;
paule8e19462006-01-19 20:16:55 +00002590 return 0;
paul718e3742002-12-13 20:15:29 +00002591}
2592
paula1ac18c2005-06-28 17:17:12 +00002593static void
paul718e3742002-12-13 20:15:29 +00002594static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2595{
2596 struct route_table *table;
2597 struct route_node *rn;
2598 struct rib *rib;
2599 struct nexthop *nexthop;
2600
2601 /* Lookup table. */
2602 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2603 if (! table)
2604 return;
2605
2606 /* Lookup existing route with type and distance. */
2607 rn = route_node_lookup (table, (struct prefix *) p);
2608 if (! rn)
2609 return;
2610
2611 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002612 {
2613 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2614 continue;
2615
2616 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2617 break;
2618 }
2619
paul718e3742002-12-13 20:15:29 +00002620 if (! rib)
2621 {
2622 route_unlock_node (rn);
2623 return;
2624 }
2625
2626 /* Lookup nexthop. */
2627 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2628 if (static_ipv6_nexthop_same (nexthop, si))
2629 break;
2630
2631 /* Can't find nexthop. */
2632 if (! nexthop)
2633 {
2634 route_unlock_node (rn);
2635 return;
2636 }
2637
2638 /* Check nexthop. */
2639 if (rib->nexthop_num == 1)
2640 {
2641 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002642 }
2643 else
2644 {
paul6baeb982003-10-28 03:47:15 +00002645 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2646 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002647 nexthop_delete (rib, nexthop);
2648 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002649 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002650 }
paul718e3742002-12-13 20:15:29 +00002651 /* Unlock node. */
2652 route_unlock_node (rn);
2653}
2654
2655/* Add static route into static route configuration. */
2656int
2657static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002658 const char *ifname, u_char flags, u_char distance,
2659 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002660{
2661 struct route_node *rn;
2662 struct static_ipv6 *si;
2663 struct static_ipv6 *pp;
2664 struct static_ipv6 *cp;
2665 struct route_table *stable;
2666
2667 /* Lookup table. */
2668 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2669 if (! stable)
2670 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00002671
2672 if (!gate &&
2673 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
2674 return -1;
2675
2676 if (!ifname &&
2677 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
2678 return -1;
paul718e3742002-12-13 20:15:29 +00002679
2680 /* Lookup static route prefix. */
2681 rn = route_node_get (stable, p);
2682
2683 /* Do nothing if there is a same static route. */
2684 for (si = rn->info; si; si = si->next)
2685 {
2686 if (distance == si->distance
2687 && type == si->type
2688 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2689 && (! ifname || strcmp (ifname, si->ifname) == 0))
2690 {
2691 route_unlock_node (rn);
2692 return 0;
2693 }
2694 }
2695
2696 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002697 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
paul718e3742002-12-13 20:15:29 +00002698
2699 si->type = type;
2700 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002701 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002702
2703 switch (type)
2704 {
2705 case STATIC_IPV6_GATEWAY:
2706 si->ipv6 = *gate;
2707 break;
2708 case STATIC_IPV6_IFNAME:
2709 si->ifname = XSTRDUP (0, ifname);
2710 break;
2711 case STATIC_IPV6_GATEWAY_IFNAME:
2712 si->ipv6 = *gate;
2713 si->ifname = XSTRDUP (0, ifname);
2714 break;
2715 }
2716
2717 /* Add new static route information to the tree with sort by
2718 distance value and gateway address. */
2719 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2720 {
2721 if (si->distance < cp->distance)
2722 break;
2723 if (si->distance > cp->distance)
2724 continue;
2725 }
2726
2727 /* Make linked list. */
2728 if (pp)
2729 pp->next = si;
2730 else
2731 rn->info = si;
2732 if (cp)
2733 cp->prev = si;
2734 si->prev = pp;
2735 si->next = cp;
2736
2737 /* Install into rib. */
2738 static_install_ipv6 (p, si);
2739
2740 return 1;
2741}
2742
2743/* Delete static route from static route configuration. */
2744int
2745static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002746 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002747{
2748 struct route_node *rn;
2749 struct static_ipv6 *si;
2750 struct route_table *stable;
2751
2752 /* Lookup table. */
2753 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2754 if (! stable)
2755 return -1;
2756
2757 /* Lookup static route prefix. */
2758 rn = route_node_lookup (stable, p);
2759 if (! rn)
2760 return 0;
2761
2762 /* Find same static route is the tree */
2763 for (si = rn->info; si; si = si->next)
2764 if (distance == si->distance
2765 && type == si->type
2766 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2767 && (! ifname || strcmp (ifname, si->ifname) == 0))
2768 break;
2769
2770 /* Can't find static route. */
2771 if (! si)
2772 {
2773 route_unlock_node (rn);
2774 return 0;
2775 }
2776
2777 /* Install into rib. */
2778 static_uninstall_ipv6 (p, si);
2779
2780 /* Unlink static route from linked list. */
2781 if (si->prev)
2782 si->prev->next = si->next;
2783 else
2784 rn->info = si->next;
2785 if (si->next)
2786 si->next->prev = si->prev;
2787
2788 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002789 if (ifname)
2790 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00002791 XFREE (MTYPE_STATIC_IPV6, si);
2792
2793 return 1;
2794}
2795#endif /* HAVE_IPV6 */
2796
2797/* RIB update function. */
2798void
paula1ac18c2005-06-28 17:17:12 +00002799rib_update (void)
paul718e3742002-12-13 20:15:29 +00002800{
2801 struct route_node *rn;
2802 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00002803
paul718e3742002-12-13 20:15:29 +00002804 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2805 if (table)
2806 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002807 if (rn->info)
Paul Jakma6d691122006-07-27 21:49:00 +00002808 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002809
2810 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2811 if (table)
2812 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002813 if (rn->info)
Paul Jakma6d691122006-07-27 21:49:00 +00002814 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002815}
2816
paul718e3742002-12-13 20:15:29 +00002817
2818/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00002819static void
paul718e3742002-12-13 20:15:29 +00002820rib_weed_table (struct route_table *table)
2821{
2822 struct route_node *rn;
2823 struct rib *rib;
2824 struct rib *next;
2825
2826 if (table)
2827 for (rn = route_top (table); rn; rn = route_next (rn))
2828 for (rib = rn->info; rib; rib = next)
2829 {
2830 next = rib->next;
2831
Paul Jakma6d691122006-07-27 21:49:00 +00002832 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2833 continue;
2834
paulb21b19c2003-06-15 01:28:29 +00002835 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00002836 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00002837 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002838 }
2839}
2840
2841/* Delete all routes from non main table. */
2842void
paula1ac18c2005-06-28 17:17:12 +00002843rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00002844{
2845 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2846 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2847}
2848
2849/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00002850static void
paul718e3742002-12-13 20:15:29 +00002851rib_sweep_table (struct route_table *table)
2852{
2853 struct route_node *rn;
2854 struct rib *rib;
2855 struct rib *next;
2856 int ret = 0;
2857
2858 if (table)
2859 for (rn = route_top (table); rn; rn = route_next (rn))
2860 for (rib = rn->info; rib; rib = next)
2861 {
2862 next = rib->next;
2863
Paul Jakma6d691122006-07-27 21:49:00 +00002864 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2865 continue;
2866
paul718e3742002-12-13 20:15:29 +00002867 if (rib->type == ZEBRA_ROUTE_KERNEL &&
2868 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
2869 {
2870 ret = rib_uninstall_kernel (rn, rib);
2871 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00002872 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002873 }
2874 }
2875}
2876
2877/* Sweep all RIB tables. */
2878void
paula1ac18c2005-06-28 17:17:12 +00002879rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00002880{
2881 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2882 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2883}
2884
2885/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00002886static void
paul718e3742002-12-13 20:15:29 +00002887rib_close_table (struct route_table *table)
2888{
2889 struct route_node *rn;
2890 struct rib *rib;
2891
2892 if (table)
2893 for (rn = route_top (table); rn; rn = route_next (rn))
2894 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002895 {
2896 if (! RIB_SYSTEM_ROUTE (rib)
2897 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2898 rib_uninstall_kernel (rn, rib);
2899 }
paul718e3742002-12-13 20:15:29 +00002900}
2901
2902/* Close all RIB tables. */
2903void
paula1ac18c2005-06-28 17:17:12 +00002904rib_close (void)
paul718e3742002-12-13 20:15:29 +00002905{
2906 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2907 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2908}
2909
2910/* Routing information base initialize. */
2911void
paula1ac18c2005-06-28 17:17:12 +00002912rib_init (void)
paul718e3742002-12-13 20:15:29 +00002913{
paul4d38fdb2005-04-28 17:35:14 +00002914 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00002915 /* VRF initialization. */
2916 vrf_init ();
2917}