blob: e11afaf1360468f8359207b172fe195d8238f8ff [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. */}
70};
71
72/* Vector for routing table. */
Stephen Hemmingerd145bc02008-08-17 17:41:37 +010073static vector vrf_vector;
paul718e3742002-12-13 20:15:29 +000074
75/* Allocate new VRF. */
paula1ac18c2005-06-28 17:17:12 +000076static struct vrf *
hassofce954f2004-10-07 20:29:24 +000077vrf_alloc (const char *name)
paul718e3742002-12-13 20:15:29 +000078{
79 struct vrf *vrf;
80
81 vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
82
83 /* Put name. */
84 if (name)
85 vrf->name = XSTRDUP (MTYPE_VRF_NAME, name);
86
87 /* Allocate routing table and static table. */
88 vrf->table[AFI_IP][SAFI_UNICAST] = route_table_init ();
89 vrf->table[AFI_IP6][SAFI_UNICAST] = route_table_init ();
90 vrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
91 vrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
92
93 return vrf;
94}
95
96/* Free VRF. */
paula1ac18c2005-06-28 17:17:12 +000097static void
paul718e3742002-12-13 20:15:29 +000098vrf_free (struct vrf *vrf)
99{
100 if (vrf->name)
101 XFREE (MTYPE_VRF_NAME, vrf->name);
102 XFREE (MTYPE_VRF, vrf);
103}
104
105/* Lookup VRF by identifier. */
106struct vrf *
107vrf_lookup (u_int32_t id)
108{
109 return vector_lookup (vrf_vector, id);
110}
111
112/* Lookup VRF by name. */
paula1ac18c2005-06-28 17:17:12 +0000113static struct vrf *
paul718e3742002-12-13 20:15:29 +0000114vrf_lookup_by_name (char *name)
115{
hassofce954f2004-10-07 20:29:24 +0000116 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000117 struct vrf *vrf;
118
paul55468c82005-03-14 20:19:01 +0000119 for (i = 0; i < vector_active (vrf_vector); i++)
paul718e3742002-12-13 20:15:29 +0000120 if ((vrf = vector_slot (vrf_vector, i)) != NULL)
121 if (vrf->name && name && strcmp (vrf->name, name) == 0)
122 return vrf;
123 return NULL;
124}
125
126/* Initialize VRF. */
paula1ac18c2005-06-28 17:17:12 +0000127static void
128vrf_init (void)
paul718e3742002-12-13 20:15:29 +0000129{
130 struct vrf *default_table;
131
132 /* Allocate VRF vector. */
133 vrf_vector = vector_init (1);
134
135 /* Allocate default main table. */
136 default_table = vrf_alloc ("Default-IP-Routing-Table");
137
138 /* Default table index must be 0. */
139 vector_set_index (vrf_vector, 0, default_table);
140}
141
142/* Lookup route table. */
143struct route_table *
144vrf_table (afi_t afi, safi_t safi, u_int32_t id)
145{
146 struct vrf *vrf;
147
148 vrf = vrf_lookup (id);
149 if (! vrf)
150 return NULL;
151
152 return vrf->table[afi][safi];
153}
154
155/* Lookup static route table. */
156struct route_table *
157vrf_static_table (afi_t afi, safi_t safi, u_int32_t id)
158{
159 struct vrf *vrf;
160
161 vrf = vrf_lookup (id);
162 if (! vrf)
163 return NULL;
164
165 return vrf->stable[afi][safi];
166}
167
168/* Add nexthop to the end of the list. */
paula1ac18c2005-06-28 17:17:12 +0000169static void
paul718e3742002-12-13 20:15:29 +0000170nexthop_add (struct rib *rib, struct nexthop *nexthop)
171{
172 struct nexthop *last;
173
174 for (last = rib->nexthop; last && last->next; last = last->next)
175 ;
176 if (last)
177 last->next = nexthop;
178 else
179 rib->nexthop = nexthop;
180 nexthop->prev = last;
181
182 rib->nexthop_num++;
183}
184
185/* Delete specified nexthop from the list. */
paula1ac18c2005-06-28 17:17:12 +0000186static void
paul718e3742002-12-13 20:15:29 +0000187nexthop_delete (struct rib *rib, struct nexthop *nexthop)
188{
189 if (nexthop->next)
190 nexthop->next->prev = nexthop->prev;
191 if (nexthop->prev)
192 nexthop->prev->next = nexthop->next;
193 else
194 rib->nexthop = nexthop->next;
195 rib->nexthop_num--;
196}
197
198/* Free nexthop. */
paula1ac18c2005-06-28 17:17:12 +0000199static void
paul718e3742002-12-13 20:15:29 +0000200nexthop_free (struct nexthop *nexthop)
201{
paula4b70762003-05-16 17:19:48 +0000202 if (nexthop->ifname)
203 XFREE (0, nexthop->ifname);
paul718e3742002-12-13 20:15:29 +0000204 XFREE (MTYPE_NEXTHOP, nexthop);
205}
206
207struct nexthop *
208nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
209{
210 struct nexthop *nexthop;
211
Stephen Hemminger393deb92008-08-18 14:13:29 -0700212 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000213 nexthop->type = NEXTHOP_TYPE_IFINDEX;
214 nexthop->ifindex = ifindex;
215
216 nexthop_add (rib, nexthop);
217
218 return nexthop;
219}
220
221struct nexthop *
222nexthop_ifname_add (struct rib *rib, char *ifname)
223{
224 struct nexthop *nexthop;
225
Stephen Hemminger393deb92008-08-18 14:13:29 -0700226 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000227 nexthop->type = NEXTHOP_TYPE_IFNAME;
paula4b70762003-05-16 17:19:48 +0000228 nexthop->ifname = XSTRDUP (0, ifname);
paul718e3742002-12-13 20:15:29 +0000229
230 nexthop_add (rib, nexthop);
231
232 return nexthop;
233}
234
235struct nexthop *
Paul Jakma7514fb72007-05-02 16:05:35 +0000236nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src)
paul718e3742002-12-13 20:15:29 +0000237{
238 struct nexthop *nexthop;
239
Stephen Hemminger393deb92008-08-18 14:13:29 -0700240 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000241 nexthop->type = NEXTHOP_TYPE_IPV4;
242 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000243 if (src)
244 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000245
246 nexthop_add (rib, nexthop);
247
248 return nexthop;
249}
250
paula1ac18c2005-06-28 17:17:12 +0000251static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000252nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
Paul Jakma7514fb72007-05-02 16:05:35 +0000253 struct in_addr *src, unsigned int ifindex)
paul718e3742002-12-13 20:15:29 +0000254{
255 struct nexthop *nexthop;
256
Stephen Hemminger393deb92008-08-18 14:13:29 -0700257 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000258 nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
259 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000260 if (src)
261 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000262 nexthop->ifindex = ifindex;
263
264 nexthop_add (rib, nexthop);
265
266 return nexthop;
267}
268
269#ifdef HAVE_IPV6
270struct nexthop *
271nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
272{
273 struct nexthop *nexthop;
274
Stephen Hemminger393deb92008-08-18 14:13:29 -0700275 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000276 nexthop->type = NEXTHOP_TYPE_IPV6;
277 nexthop->gate.ipv6 = *ipv6;
278
279 nexthop_add (rib, nexthop);
280
281 return nexthop;
282}
283
paula1ac18c2005-06-28 17:17:12 +0000284static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000285nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
286 char *ifname)
287{
288 struct nexthop *nexthop;
289
Stephen Hemminger393deb92008-08-18 14:13:29 -0700290 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000291 nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
292 nexthop->gate.ipv6 = *ipv6;
293 nexthop->ifname = XSTRDUP (0, ifname);
294
295 nexthop_add (rib, nexthop);
296
297 return nexthop;
298}
299
paula1ac18c2005-06-28 17:17:12 +0000300static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000301nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
302 unsigned int ifindex)
303{
304 struct nexthop *nexthop;
305
Stephen Hemminger393deb92008-08-18 14:13:29 -0700306 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000307 nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
308 nexthop->gate.ipv6 = *ipv6;
309 nexthop->ifindex = ifindex;
310
311 nexthop_add (rib, nexthop);
312
313 return nexthop;
314}
315#endif /* HAVE_IPV6 */
316
paul595db7f2003-05-25 21:35:06 +0000317struct nexthop *
318nexthop_blackhole_add (struct rib *rib)
319{
320 struct nexthop *nexthop;
321
Stephen Hemminger393deb92008-08-18 14:13:29 -0700322 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul595db7f2003-05-25 21:35:06 +0000323 nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
324 SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
325
326 nexthop_add (rib, nexthop);
327
328 return nexthop;
329}
330
paul718e3742002-12-13 20:15:29 +0000331/* If force flag is not set, do not modify falgs at all for uninstall
332 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000333static int
paul718e3742002-12-13 20:15:29 +0000334nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
335 struct route_node *top)
336{
337 struct prefix_ipv4 p;
338 struct route_table *table;
339 struct route_node *rn;
340 struct rib *match;
341 struct nexthop *newhop;
342
343 if (nexthop->type == NEXTHOP_TYPE_IPV4)
344 nexthop->ifindex = 0;
345
346 if (set)
347 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
348
349 /* Make lookup prefix. */
350 memset (&p, 0, sizeof (struct prefix_ipv4));
351 p.family = AF_INET;
352 p.prefixlen = IPV4_MAX_PREFIXLEN;
353 p.prefix = nexthop->gate.ipv4;
354
355 /* Lookup table. */
356 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
357 if (! table)
358 return 0;
359
360 rn = route_node_match (table, (struct prefix *) &p);
361 while (rn)
362 {
363 route_unlock_node (rn);
364
365 /* If lookup self prefix return immidiately. */
366 if (rn == top)
367 return 0;
368
369 /* Pick up selected route. */
370 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100371 {
372 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
373 continue;
374 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
375 break;
376 }
paul718e3742002-12-13 20:15:29 +0000377
378 /* If there is no selected route or matched route is EGP, go up
379 tree. */
380 if (! match
381 || match->type == ZEBRA_ROUTE_BGP)
382 {
383 do {
384 rn = rn->parent;
385 } while (rn && rn->info == NULL);
386 if (rn)
387 route_lock_node (rn);
388 }
389 else
390 {
391 if (match->type == ZEBRA_ROUTE_CONNECT)
392 {
393 /* Directly point connected route. */
394 newhop = match->nexthop;
395 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
396 nexthop->ifindex = newhop->ifindex;
397
398 return 1;
399 }
400 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
401 {
402 for (newhop = match->nexthop; newhop; newhop = newhop->next)
403 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
404 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
405 {
406 if (set)
407 {
408 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
409 nexthop->rtype = newhop->type;
410 if (newhop->type == NEXTHOP_TYPE_IPV4 ||
411 newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
412 nexthop->rgate.ipv4 = newhop->gate.ipv4;
413 if (newhop->type == NEXTHOP_TYPE_IFINDEX
414 || newhop->type == NEXTHOP_TYPE_IFNAME
415 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
416 nexthop->rifindex = newhop->ifindex;
417 }
418 return 1;
419 }
420 return 0;
421 }
422 else
423 {
424 return 0;
425 }
426 }
427 }
428 return 0;
429}
430
431#ifdef HAVE_IPV6
432/* If force flag is not set, do not modify falgs at all for uninstall
433 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000434static int
paul718e3742002-12-13 20:15:29 +0000435nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
436 struct route_node *top)
437{
438 struct prefix_ipv6 p;
439 struct route_table *table;
440 struct route_node *rn;
441 struct rib *match;
442 struct nexthop *newhop;
443
444 if (nexthop->type == NEXTHOP_TYPE_IPV6)
445 nexthop->ifindex = 0;
446
447 if (set)
448 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
449
450 /* Make lookup prefix. */
451 memset (&p, 0, sizeof (struct prefix_ipv6));
452 p.family = AF_INET6;
453 p.prefixlen = IPV6_MAX_PREFIXLEN;
454 p.prefix = nexthop->gate.ipv6;
455
456 /* Lookup table. */
457 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
458 if (! table)
459 return 0;
460
461 rn = route_node_match (table, (struct prefix *) &p);
462 while (rn)
463 {
464 route_unlock_node (rn);
465
466 /* If lookup self prefix return immidiately. */
467 if (rn == top)
468 return 0;
469
470 /* Pick up selected route. */
471 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100472 {
473 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
474 continue;
475 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
476 break;
477 }
paul718e3742002-12-13 20:15:29 +0000478
479 /* If there is no selected route or matched route is EGP, go up
480 tree. */
481 if (! match
482 || match->type == ZEBRA_ROUTE_BGP)
483 {
484 do {
485 rn = rn->parent;
486 } while (rn && rn->info == NULL);
487 if (rn)
488 route_lock_node (rn);
489 }
490 else
491 {
492 if (match->type == ZEBRA_ROUTE_CONNECT)
493 {
494 /* Directly point connected route. */
495 newhop = match->nexthop;
496
497 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
498 nexthop->ifindex = newhop->ifindex;
499
500 return 1;
501 }
502 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
503 {
504 for (newhop = match->nexthop; newhop; newhop = newhop->next)
505 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
506 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
507 {
508 if (set)
509 {
510 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
511 nexthop->rtype = newhop->type;
512 if (newhop->type == NEXTHOP_TYPE_IPV6
513 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
514 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
515 nexthop->rgate.ipv6 = newhop->gate.ipv6;
516 if (newhop->type == NEXTHOP_TYPE_IFINDEX
517 || newhop->type == NEXTHOP_TYPE_IFNAME
518 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
519 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
520 nexthop->rifindex = newhop->ifindex;
521 }
522 return 1;
523 }
524 return 0;
525 }
526 else
527 {
528 return 0;
529 }
530 }
531 }
532 return 0;
533}
534#endif /* HAVE_IPV6 */
535
536struct rib *
537rib_match_ipv4 (struct in_addr addr)
538{
539 struct prefix_ipv4 p;
540 struct route_table *table;
541 struct route_node *rn;
542 struct rib *match;
543 struct nexthop *newhop;
544
545 /* Lookup table. */
546 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
547 if (! table)
548 return 0;
549
550 memset (&p, 0, sizeof (struct prefix_ipv4));
551 p.family = AF_INET;
552 p.prefixlen = IPV4_MAX_PREFIXLEN;
553 p.prefix = addr;
554
555 rn = route_node_match (table, (struct prefix *) &p);
556
557 while (rn)
558 {
559 route_unlock_node (rn);
560
561 /* Pick up selected route. */
562 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100563 {
564 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
565 continue;
566 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
567 break;
568 }
paul718e3742002-12-13 20:15:29 +0000569
570 /* If there is no selected route or matched route is EGP, go up
571 tree. */
572 if (! match
573 || match->type == ZEBRA_ROUTE_BGP)
574 {
575 do {
576 rn = rn->parent;
577 } while (rn && rn->info == NULL);
578 if (rn)
579 route_lock_node (rn);
580 }
581 else
582 {
583 if (match->type == ZEBRA_ROUTE_CONNECT)
584 /* Directly point connected route. */
585 return match;
586 else
587 {
588 for (newhop = match->nexthop; newhop; newhop = newhop->next)
589 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
590 return match;
591 return NULL;
592 }
593 }
594 }
595 return NULL;
596}
597
598struct rib *
599rib_lookup_ipv4 (struct prefix_ipv4 *p)
600{
601 struct route_table *table;
602 struct route_node *rn;
603 struct rib *match;
604 struct nexthop *nexthop;
605
606 /* Lookup table. */
607 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
608 if (! table)
609 return 0;
610
611 rn = route_node_lookup (table, (struct prefix *) p);
612
613 /* No route for this prefix. */
614 if (! rn)
615 return NULL;
616
617 /* Unlock node. */
618 route_unlock_node (rn);
619
paul718e3742002-12-13 20:15:29 +0000620 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100621 {
622 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
623 continue;
624 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
625 break;
626 }
paul718e3742002-12-13 20:15:29 +0000627
628 if (! match || match->type == ZEBRA_ROUTE_BGP)
629 return NULL;
630
631 if (match->type == ZEBRA_ROUTE_CONNECT)
632 return match;
633
634 for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
635 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
636 return match;
637
638 return NULL;
639}
640
Denis Ovsienkodc958242007-08-13 16:03:06 +0000641/*
642 * This clone function, unlike its original rib_lookup_ipv4(), checks
643 * if specified IPv4 route record (prefix/mask -> gate) exists in
644 * the whole RIB and has ZEBRA_FLAG_SELECTED set.
645 *
646 * Return values:
647 * -1: error
648 * 0: exact match found
649 * 1: a match was found with a different gate
650 * 2: connected route found
651 * 3: no matches found
652 */
653int
654rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
655{
656 struct route_table *table;
657 struct route_node *rn;
658 struct rib *match;
659 struct nexthop *nexthop;
660
661 /* Lookup table. */
662 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
663 if (! table)
664 return ZEBRA_RIB_LOOKUP_ERROR;
665
666 /* Scan the RIB table for exactly matching RIB entry. */
667 rn = route_node_lookup (table, (struct prefix *) p);
668
669 /* No route for this prefix. */
670 if (! rn)
671 return ZEBRA_RIB_NOTFOUND;
672
673 /* Unlock node. */
674 route_unlock_node (rn);
675
676 /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
677 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100678 {
679 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
680 continue;
681 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
682 break;
683 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000684
685 /* None such found :( */
686 if (!match)
687 return ZEBRA_RIB_NOTFOUND;
688
689 if (match->type == ZEBRA_ROUTE_CONNECT)
690 return ZEBRA_RIB_FOUND_CONNECTED;
691
692 /* Ok, we have a cood candidate, let's check it's nexthop list... */
693 for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
694 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
695 {
696 /* We are happy with either direct or recursive hexthop */
697 if (nexthop->gate.ipv4.s_addr == qgate->sin.sin_addr.s_addr ||
698 nexthop->rgate.ipv4.s_addr == qgate->sin.sin_addr.s_addr)
699 return ZEBRA_RIB_FOUND_EXACT;
700 else
701 {
702 if (IS_ZEBRA_DEBUG_RIB)
703 {
704 char gate_buf[INET_ADDRSTRLEN], rgate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
705 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
706 inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, rgate_buf, INET_ADDRSTRLEN);
707 inet_ntop (AF_INET, &qgate->sin.sin_addr.s_addr, qgate_buf, INET_ADDRSTRLEN);
708 zlog_debug ("%s: qgate == %s, gate == %s, rgate == %s", __func__, qgate_buf, gate_buf, rgate_buf);
709 }
710 return ZEBRA_RIB_FOUND_NOGATE;
711 }
712 }
713
714 return ZEBRA_RIB_NOTFOUND;
715}
716
paul718e3742002-12-13 20:15:29 +0000717#ifdef HAVE_IPV6
718struct rib *
719rib_match_ipv6 (struct in6_addr *addr)
720{
721 struct prefix_ipv6 p;
722 struct route_table *table;
723 struct route_node *rn;
724 struct rib *match;
725 struct nexthop *newhop;
726
727 /* Lookup table. */
728 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
729 if (! table)
730 return 0;
731
732 memset (&p, 0, sizeof (struct prefix_ipv6));
733 p.family = AF_INET6;
734 p.prefixlen = IPV6_MAX_PREFIXLEN;
735 IPV6_ADDR_COPY (&p.prefix, addr);
736
737 rn = route_node_match (table, (struct prefix *) &p);
738
739 while (rn)
740 {
741 route_unlock_node (rn);
742
743 /* Pick up selected route. */
744 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100745 {
746 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
747 continue;
748 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
749 break;
750 }
paul718e3742002-12-13 20:15:29 +0000751
752 /* If there is no selected route or matched route is EGP, go up
753 tree. */
754 if (! match
755 || match->type == ZEBRA_ROUTE_BGP)
756 {
757 do {
758 rn = rn->parent;
759 } while (rn && rn->info == NULL);
760 if (rn)
761 route_lock_node (rn);
762 }
763 else
764 {
765 if (match->type == ZEBRA_ROUTE_CONNECT)
766 /* Directly point connected route. */
767 return match;
768 else
769 {
770 for (newhop = match->nexthop; newhop; newhop = newhop->next)
771 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
772 return match;
773 return NULL;
774 }
775 }
776 }
777 return NULL;
778}
779#endif /* HAVE_IPV6 */
780
Paul Jakma7514fb72007-05-02 16:05:35 +0000781#define RIB_SYSTEM_ROUTE(R) \
782 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
783
Denis Ovsienkodc958242007-08-13 16:03:06 +0000784/* This function verifies reachability of one given nexthop, which can be
785 * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
786 * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
787 * nexthop->ifindex will be updated appropriately as well.
788 * An existing route map can turn (otherwise active) nexthop into inactive, but
789 * not vice versa.
790 *
791 * The return value is the final value of 'ACTIVE' flag.
792 */
793
paula1ac18c2005-06-28 17:17:12 +0000794static int
paul718e3742002-12-13 20:15:29 +0000795nexthop_active_check (struct route_node *rn, struct rib *rib,
796 struct nexthop *nexthop, int set)
797{
798 struct interface *ifp;
Paul Jakma7514fb72007-05-02 16:05:35 +0000799 route_map_result_t ret = RMAP_MATCH;
800 extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
801 struct route_map *rmap;
802 int family;
paul718e3742002-12-13 20:15:29 +0000803
Paul Jakma7514fb72007-05-02 16:05:35 +0000804 family = 0;
paul718e3742002-12-13 20:15:29 +0000805 switch (nexthop->type)
806 {
807 case NEXTHOP_TYPE_IFINDEX:
808 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000809 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000810 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
811 else
812 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
813 break;
paul718e3742002-12-13 20:15:29 +0000814 case NEXTHOP_TYPE_IPV6_IFNAME:
Paul Jakma7514fb72007-05-02 16:05:35 +0000815 family = AFI_IP6;
816 case NEXTHOP_TYPE_IFNAME:
paul718e3742002-12-13 20:15:29 +0000817 ifp = if_lookup_by_name (nexthop->ifname);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000818 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000819 {
820 if (set)
821 nexthop->ifindex = ifp->ifindex;
822 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
823 }
824 else
825 {
826 if (set)
827 nexthop->ifindex = 0;
828 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
829 }
830 break;
831 case NEXTHOP_TYPE_IPV4:
832 case NEXTHOP_TYPE_IPV4_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000833 family = AFI_IP;
paul718e3742002-12-13 20:15:29 +0000834 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
835 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
836 else
837 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
838 break;
839#ifdef HAVE_IPV6
840 case NEXTHOP_TYPE_IPV6:
Paul Jakma7514fb72007-05-02 16:05:35 +0000841 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000842 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
843 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
844 else
845 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
846 break;
847 case NEXTHOP_TYPE_IPV6_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000848 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000849 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
850 {
851 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000852 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000853 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
854 else
855 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
856 }
857 else
858 {
859 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
860 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
861 else
862 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
863 }
864 break;
865#endif /* HAVE_IPV6 */
paul595db7f2003-05-25 21:35:06 +0000866 case NEXTHOP_TYPE_BLACKHOLE:
867 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
868 break;
paul718e3742002-12-13 20:15:29 +0000869 default:
870 break;
871 }
Paul Jakma7514fb72007-05-02 16:05:35 +0000872 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
873 return 0;
874
875 if (RIB_SYSTEM_ROUTE(rib) ||
876 (family == AFI_IP && rn->p.family != AF_INET) ||
877 (family == AFI_IP6 && rn->p.family != AF_INET6))
878 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
879
880 rmap = 0;
881 if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
882 proto_rm[family][rib->type])
883 rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
884 if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
885 rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
886 if (rmap) {
887 ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, nexthop);
888 }
889
890 if (ret == RMAP_DENYMATCH)
891 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
paul718e3742002-12-13 20:15:29 +0000892 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
893}
894
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000895/* Iterate over all nexthops of the given RIB entry and refresh their
896 * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
897 * nexthop is found to toggle the ACTIVE flag, the whole rib structure
898 * is flagged with ZEBRA_FLAG_CHANGED. The 4th 'set' argument is
899 * transparently passed to nexthop_active_check().
900 *
901 * Return value is the new number of active nexthops.
902 */
903
paula1ac18c2005-06-28 17:17:12 +0000904static int
paul718e3742002-12-13 20:15:29 +0000905nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
906{
907 struct nexthop *nexthop;
Joakim Tjernlundc3a56062009-06-24 19:15:36 +0200908 int prev_active, prev_index, new_active;
paul718e3742002-12-13 20:15:29 +0000909
910 rib->nexthop_active_num = 0;
911 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
912
913 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000914 {
915 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
Joakim Tjernlundc3a56062009-06-24 19:15:36 +0200916 prev_index = nexthop->ifindex;
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000917 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
918 rib->nexthop_active_num++;
Joakim Tjernlundc3a56062009-06-24 19:15:36 +0200919 if (prev_active != new_active ||
920 prev_index != nexthop->ifindex)
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000921 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
922 }
paul718e3742002-12-13 20:15:29 +0000923 return rib->nexthop_active_num;
924}
paul6baeb982003-10-28 03:47:15 +0000925
paul718e3742002-12-13 20:15:29 +0000926
paul718e3742002-12-13 20:15:29 +0000927
paula1ac18c2005-06-28 17:17:12 +0000928static void
paul718e3742002-12-13 20:15:29 +0000929rib_install_kernel (struct route_node *rn, struct rib *rib)
930{
931 int ret = 0;
932 struct nexthop *nexthop;
933
934 switch (PREFIX_FAMILY (&rn->p))
935 {
936 case AF_INET:
937 ret = kernel_add_ipv4 (&rn->p, rib);
938 break;
939#ifdef HAVE_IPV6
940 case AF_INET6:
941 ret = kernel_add_ipv6 (&rn->p, rib);
942 break;
943#endif /* HAVE_IPV6 */
944 }
945
Denis Ovsienkodc958242007-08-13 16:03:06 +0000946 /* This condition is never met, if we are using rt_socket.c */
paul718e3742002-12-13 20:15:29 +0000947 if (ret < 0)
948 {
949 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
950 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
951 }
952}
953
954/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +0000955static int
paul718e3742002-12-13 20:15:29 +0000956rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
957{
958 int ret = 0;
959 struct nexthop *nexthop;
960
961 switch (PREFIX_FAMILY (&rn->p))
962 {
963 case AF_INET:
964 ret = kernel_delete_ipv4 (&rn->p, rib);
965 break;
966#ifdef HAVE_IPV6
967 case AF_INET6:
968 ret = kernel_delete_ipv6 (&rn->p, rib);
969 break;
970#endif /* HAVE_IPV6 */
971 }
972
973 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
974 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
975
976 return ret;
977}
978
979/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +0000980static void
paul718e3742002-12-13 20:15:29 +0000981rib_uninstall (struct route_node *rn, struct rib *rib)
982{
983 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
984 {
985 redistribute_delete (&rn->p, rib);
986 if (! RIB_SYSTEM_ROUTE (rib))
987 rib_uninstall_kernel (rn, rib);
988 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
989 }
990}
991
Paul Jakma6d691122006-07-27 21:49:00 +0000992static void rib_unlink (struct route_node *, struct rib *);
993
paul718e3742002-12-13 20:15:29 +0000994/* Core function for processing routing information base. */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +0000995static void
996rib_process (struct route_node *rn)
paul718e3742002-12-13 20:15:29 +0000997{
998 struct rib *rib;
999 struct rib *next;
1000 struct rib *fib = NULL;
1001 struct rib *select = NULL;
Paul Jakma6d691122006-07-27 21:49:00 +00001002 struct rib *del = NULL;
pauld753e9e2003-01-22 19:45:50 +00001003 int installed = 0;
1004 struct nexthop *nexthop = NULL;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001005 char buf[INET6_ADDRSTRLEN];
paul4d38fdb2005-04-28 17:35:14 +00001006
1007 assert (rn);
1008
Paul Jakma93bdada2007-08-06 19:25:11 +00001009 if (IS_ZEBRA_DEBUG_RIB || IS_ZEBRA_DEBUG_RIB_Q)
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001010 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001011
paul718e3742002-12-13 20:15:29 +00001012 for (rib = rn->info; rib; rib = next)
1013 {
Denis Ovsienkodc958242007-08-13 16:03:06 +00001014 /* The next pointer is saved, because current pointer
1015 * may be passed to rib_unlink() in the middle of iteration.
1016 */
paul718e3742002-12-13 20:15:29 +00001017 next = rib->next;
pauld753e9e2003-01-22 19:45:50 +00001018
paul718e3742002-12-13 20:15:29 +00001019 /* Currently installed rib. */
1020 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Paul Jakma6d691122006-07-27 21:49:00 +00001021 {
1022 assert (fib == NULL);
1023 fib = rib;
1024 }
1025
1026 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1027 * which we need to do do further work with below.
1028 */
1029 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1030 {
1031 if (rib != fib)
1032 {
1033 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001034 zlog_debug ("%s: %s/%d: rn %p, removing rib %p", __func__,
1035 buf, rn->p.prefixlen, rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001036 rib_unlink (rn, rib);
1037 }
1038 else
1039 del = rib;
1040
1041 continue;
1042 }
paul4d38fdb2005-04-28 17:35:14 +00001043
paul718e3742002-12-13 20:15:29 +00001044 /* Skip unreachable nexthop. */
1045 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +00001046 continue;
paul718e3742002-12-13 20:15:29 +00001047
1048 /* Infinit distance. */
1049 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +00001050 continue;
paul718e3742002-12-13 20:15:29 +00001051
paulaf887b52006-01-18 14:52:52 +00001052 /* Newly selected rib, the common case. */
1053 if (!select)
1054 {
1055 select = rib;
1056 continue;
1057 }
1058
1059 /* filter route selection in following order:
paulaf887b52006-01-18 14:52:52 +00001060 * - connected beats other types
paula8d9c1f2006-01-25 06:31:04 +00001061 * - lower distance beats higher
paulaf887b52006-01-18 14:52:52 +00001062 * - lower metric beats higher for equal distance
1063 * - last, hence oldest, route wins tie break.
1064 */
paula1038a12006-01-30 14:08:51 +00001065
1066 /* Connected routes. Pick the last connected
1067 * route of the set of lowest metric connected routes.
1068 */
paula8d9c1f2006-01-25 06:31:04 +00001069 if (rib->type == ZEBRA_ROUTE_CONNECT)
1070 {
paula1038a12006-01-30 14:08:51 +00001071 if (select->type != ZEBRA_ROUTE_CONNECT
paula8d9c1f2006-01-25 06:31:04 +00001072 || rib->metric <= select->metric)
paula1038a12006-01-30 14:08:51 +00001073 select = rib;
1074 continue;
paula8d9c1f2006-01-25 06:31:04 +00001075 }
1076 else if (select->type == ZEBRA_ROUTE_CONNECT)
1077 continue;
1078
1079 /* higher distance loses */
1080 if (rib->distance > select->distance)
1081 continue;
1082
1083 /* lower wins */
1084 if (rib->distance < select->distance)
1085 {
paulaf887b52006-01-18 14:52:52 +00001086 select = rib;
paula8d9c1f2006-01-25 06:31:04 +00001087 continue;
1088 }
1089
1090 /* metric tie-breaks equal distance */
1091 if (rib->metric <= select->metric)
1092 select = rib;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001093 } /* for (rib = rn->info; rib; rib = next) */
1094
1095 /* After the cycle is finished, the following pointers will be set:
1096 * select --- the winner RIB entry, if any was found, otherwise NULL
1097 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1098 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1099 * rib --- NULL
1100 */
1101
1102 /* Same RIB entry is selected. Update FIB and finish. */
paul718e3742002-12-13 20:15:29 +00001103 if (select && select == fib)
1104 {
Paul Jakma6d691122006-07-27 21:49:00 +00001105 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001106 zlog_debug ("%s: %s/%d: Updating existing route, select %p, fib %p",
1107 __func__, buf, rn->p.prefixlen, select, fib);
paul718e3742002-12-13 20:15:29 +00001108 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +00001109 {
1110 redistribute_delete (&rn->p, select);
1111 if (! RIB_SYSTEM_ROUTE (select))
1112 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001113
paul4d38fdb2005-04-28 17:35:14 +00001114 /* Set real nexthop. */
1115 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +00001116
paul4d38fdb2005-04-28 17:35:14 +00001117 if (! RIB_SYSTEM_ROUTE (select))
1118 rib_install_kernel (rn, select);
1119 redistribute_add (&rn->p, select);
1120 }
pauld753e9e2003-01-22 19:45:50 +00001121 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001122 {
1123 /* Housekeeping code to deal with
1124 race conditions in kernel with linux
1125 netlink reporting interface up before IPv4 or IPv6 protocol
1126 is ready to add routes.
1127 This makes sure the routes are IN the kernel.
1128 */
pauld753e9e2003-01-22 19:45:50 +00001129
paul4d38fdb2005-04-28 17:35:14 +00001130 for (nexthop = select->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001131 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
paul4d38fdb2005-04-28 17:35:14 +00001132 {
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001133 installed = 1;
1134 break;
paul4d38fdb2005-04-28 17:35:14 +00001135 }
1136 if (! installed)
1137 rib_install_kernel (rn, select);
1138 }
Paul Jakma6d691122006-07-27 21:49:00 +00001139 goto end;
paul718e3742002-12-13 20:15:29 +00001140 }
1141
Denis Ovsienkodc958242007-08-13 16:03:06 +00001142 /* At this point we either haven't found the best RIB entry or it is
1143 * different from what we currently intend to flag with SELECTED. In both
1144 * cases, if a RIB block is present in FIB, it should be withdrawn.
1145 */
paul718e3742002-12-13 20:15:29 +00001146 if (fib)
1147 {
Paul Jakma6d691122006-07-27 21:49:00 +00001148 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001149 zlog_debug ("%s: %s/%d: Removing existing route, fib %p", __func__,
1150 buf, rn->p.prefixlen, fib);
paul718e3742002-12-13 20:15:29 +00001151 redistribute_delete (&rn->p, fib);
1152 if (! RIB_SYSTEM_ROUTE (fib))
1153 rib_uninstall_kernel (rn, fib);
1154 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1155
1156 /* Set real nexthop. */
1157 nexthop_active_update (rn, fib, 1);
1158 }
1159
Denis Ovsienkodc958242007-08-13 16:03:06 +00001160 /* Regardless of some RIB entry being SELECTED or not before, now we can
1161 * tell, that if a new winner exists, FIB is still not updated with this
1162 * data, but ready to be.
1163 */
paul718e3742002-12-13 20:15:29 +00001164 if (select)
1165 {
Paul Jakma6d691122006-07-27 21:49:00 +00001166 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001167 zlog_debug ("%s: %s/%d: Adding route, select %p", __func__, buf,
1168 rn->p.prefixlen, select);
paul718e3742002-12-13 20:15:29 +00001169 /* Set real nexthop. */
1170 nexthop_active_update (rn, select, 1);
1171
1172 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001173 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001174 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1175 redistribute_add (&rn->p, select);
1176 }
paul4d38fdb2005-04-28 17:35:14 +00001177
Paul Jakma6d691122006-07-27 21:49:00 +00001178 /* FIB route was removed, should be deleted */
1179 if (del)
1180 {
1181 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001182 zlog_debug ("%s: %s/%d: Deleting fib %p, rn %p", __func__, buf,
1183 rn->p.prefixlen, del, rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001184 rib_unlink (rn, del);
1185 }
paul4d38fdb2005-04-28 17:35:14 +00001186
Paul Jakma6d691122006-07-27 21:49:00 +00001187end:
1188 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma93bdada2007-08-06 19:25:11 +00001189 zlog_debug ("%s: %s/%d: rn %p dequeued", __func__, buf, rn->p.prefixlen, rn);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001190}
1191
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001192/* Take a list of route_node structs and return 1, if there was a record
1193 * picked from it and processed by rib_process(). Don't process more,
1194 * than one RN record; operate only in the specified sub-queue.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001195 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001196static unsigned int
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001197process_subq (struct list * subq, u_char qindex)
1198{
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001199 struct listnode *lnode = listhead (subq);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001200 struct route_node *rnode;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001201
1202 if (!lnode)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001203 return 0;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001204
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001205 rnode = listgetdata (lnode);
1206 rib_process (rnode);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001207
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001208 if (rnode->info) /* The first RIB record is holding the flags bitmask. */
1209 UNSET_FLAG (((struct rib *)rnode->info)->rn_status, RIB_ROUTE_QUEUED(qindex));
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001210 else
1211 {
1212 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1213 __func__, rnode, rnode->lock);
1214 zlog_backtrace(LOG_DEBUG);
1215 }
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001216 route_unlock_node (rnode);
1217 list_delete_node (subq, lnode);
1218 return 1;
1219}
1220
1221/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1222 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1223 * is pointed to the meta queue structure.
1224 */
1225static wq_item_status
1226meta_queue_process (struct work_queue *dummy, void *data)
1227{
1228 struct meta_queue * mq = data;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001229 unsigned i;
1230
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001231 for (i = 0; i < MQ_SIZE; i++)
1232 if (process_subq (mq->subq[i], i))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001233 {
1234 mq->size--;
1235 break;
1236 }
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001237 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1238}
1239
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001240/* Map from rib types to queue type (priority) in meta queue */
1241static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
1242 [ZEBRA_ROUTE_SYSTEM] = 4,
1243 [ZEBRA_ROUTE_KERNEL] = 0,
1244 [ZEBRA_ROUTE_CONNECT] = 0,
1245 [ZEBRA_ROUTE_STATIC] = 1,
1246 [ZEBRA_ROUTE_RIP] = 2,
1247 [ZEBRA_ROUTE_RIPNG] = 2,
1248 [ZEBRA_ROUTE_OSPF] = 2,
1249 [ZEBRA_ROUTE_OSPF6] = 2,
1250 [ZEBRA_ROUTE_ISIS] = 2,
1251 [ZEBRA_ROUTE_BGP] = 3,
1252 [ZEBRA_ROUTE_HSLS] = 4,
1253};
1254
1255/* Look into the RN and queue it into one or more priority queues,
1256 * increasing the size for each data push done.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001257 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001258static void
1259rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001260{
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001261 struct rib *rib;
1262 char buf[INET6_ADDRSTRLEN];
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001263
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001264 if (IS_ZEBRA_DEBUG_RIB_Q)
1265 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001266
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001267 for (rib = rn->info; rib; rib = rib->next)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001268 {
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001269 u_char qindex = meta_queue_map[rib->type];
1270
1271 /* Invariant: at this point we always have rn->info set. */
1272 if (CHECK_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED(qindex)))
1273 {
1274 if (IS_ZEBRA_DEBUG_RIB_Q)
1275 zlog_debug ("%s: %s/%d: rn %p is already queued in sub-queue %u",
1276 __func__, buf, rn->p.prefixlen, rn, qindex);
1277 continue;
1278 }
1279
1280 SET_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED(qindex));
1281 listnode_add (mq->subq[qindex], rn);
1282 route_lock_node (rn);
1283 mq->size++;
1284
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001285 if (IS_ZEBRA_DEBUG_RIB_Q)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001286 zlog_debug ("%s: %s/%d: queued rn %p into sub-queue %u",
1287 __func__, buf, rn->p.prefixlen, rn, qindex);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001288 }
paul4d38fdb2005-04-28 17:35:14 +00001289}
1290
Paul Jakma6d691122006-07-27 21:49:00 +00001291/* Add route_node to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001292static void
Paul Jakma6d691122006-07-27 21:49:00 +00001293rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
paul4d38fdb2005-04-28 17:35:14 +00001294{
Paul Jakma93bdada2007-08-06 19:25:11 +00001295 char buf[INET_ADDRSTRLEN];
Paul Jakma6d691122006-07-27 21:49:00 +00001296 assert (zebra && rn);
paul4d38fdb2005-04-28 17:35:14 +00001297
Paul Jakma93bdada2007-08-06 19:25:11 +00001298 if (IS_ZEBRA_DEBUG_RIB_Q)
1299 inet_ntop (AF_INET, &rn->p.u.prefix, buf, INET_ADDRSTRLEN);
1300
Paul Jakma6d691122006-07-27 21:49:00 +00001301 /* Pointless to queue a route_node with no RIB entries to add or remove */
1302 if (!rn->info)
1303 {
1304 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1305 __func__, rn, rn->lock);
1306 zlog_backtrace(LOG_DEBUG);
1307 return;
1308 }
paul4d38fdb2005-04-28 17:35:14 +00001309
Paul Jakma6d691122006-07-27 21:49:00 +00001310 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma93bdada2007-08-06 19:25:11 +00001311 zlog_info ("%s: %s/%d: work queue added", __func__, buf, rn->p.prefixlen);
Paul Jakma6d691122006-07-27 21:49:00 +00001312
1313 assert (zebra);
1314
paul4d38fdb2005-04-28 17:35:14 +00001315 if (zebra->ribq == NULL)
1316 {
Paul Jakma6d691122006-07-27 21:49:00 +00001317 zlog_err ("%s: work_queue does not exist!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001318 return;
1319 }
Paul Jakma6d691122006-07-27 21:49:00 +00001320
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001321 /* The RIB queue should normally be either empty or holding the only work_queue_item
1322 * element. In the latter case this element would hold a pointer to the meta queue
1323 * structure, which must be used to actually queue the route nodes to process. So
1324 * create the MQ holder, if necessary, then push the work into it in any case.
1325 * This semantics was introduced after 0.99.9 release.
1326 */
1327
1328 /* Should I invent work_queue_empty() and use it, or it's Ok to do as follows? */
1329 if (!zebra->ribq->items->count)
1330 work_queue_add (zebra->ribq, zebra->mq);
1331
1332 rib_meta_queue_add (zebra->mq, rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001333
1334 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma93bdada2007-08-06 19:25:11 +00001335 zlog_debug ("%s: %s/%d: rn %p queued", __func__, buf, rn->p.prefixlen, rn);
paul4d38fdb2005-04-28 17:35:14 +00001336
1337 return;
1338}
1339
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001340/* Create new meta queue.
1341 A destructor function doesn't seem to be necessary here.
1342 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001343static struct meta_queue *
1344meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001345{
1346 struct meta_queue *new;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001347 unsigned i;
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001348
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001349 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1350 assert(new);
1351
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001352 for (i = 0; i < MQ_SIZE; i++)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001353 {
1354 new->subq[i] = list_new ();
1355 assert(new->subq[i]);
1356 }
1357
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001358 return new;
1359}
1360
paul4d38fdb2005-04-28 17:35:14 +00001361/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001362static void
paul4d38fdb2005-04-28 17:35:14 +00001363rib_queue_init (struct zebra_t *zebra)
1364{
1365 assert (zebra);
1366
1367 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001368 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001369 {
Paul Jakma6d691122006-07-27 21:49:00 +00001370 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001371 return;
1372 }
1373
1374 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001375 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001376 zebra->ribq->spec.errorfunc = NULL;
paul4d38fdb2005-04-28 17:35:14 +00001377 /* XXX: TODO: These should be runtime configurable via vty */
1378 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001379 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001380
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001381 if (!(zebra->mq = meta_queue_new ()))
1382 {
1383 zlog_err ("%s: could not initialise meta queue!", __func__);
1384 return;
1385 }
paul4d38fdb2005-04-28 17:35:14 +00001386 return;
paul718e3742002-12-13 20:15:29 +00001387}
1388
Paul Jakma6d691122006-07-27 21:49:00 +00001389/* RIB updates are processed via a queue of pointers to route_nodes.
1390 *
1391 * The queue length is bounded by the maximal size of the routing table,
1392 * as a route_node will not be requeued, if already queued.
1393 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001394 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1395 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1396 * and then submit route_node to queue for best-path selection later.
1397 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001398 *
1399 * Deleted RIBs are reaped during best-path selection.
1400 *
1401 * rib_addnode
1402 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001403 * |-------->| | best RIB, if required
1404 * | |
1405 * static_install->|->rib_addqueue...... -> rib_process
1406 * | |
1407 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001408 * |-> set RIB_ENTRY_REMOVE |
1409 * rib_delnode (RIB freed)
1410 *
1411 *
1412 * Queueing state for a route_node is kept in the head RIB entry, this
1413 * state must be preserved as and when the head RIB entry of a
1414 * route_node is changed by rib_unlink / rib_link. A small complication,
1415 * but saves having to allocate a dedicated object for this.
1416 *
1417 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1418 *
1419 * - route_nodes: refcounted by:
1420 * - RIBs attached to route_node:
1421 * - managed by: rib_link/unlink
1422 * - route_node processing queue
1423 * - managed by: rib_addqueue, rib_process.
1424 *
1425 */
1426
paul718e3742002-12-13 20:15:29 +00001427/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001428static void
Paul Jakma6d691122006-07-27 21:49:00 +00001429rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001430{
1431 struct rib *head;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001432 char buf[INET6_ADDRSTRLEN];
paul4d38fdb2005-04-28 17:35:14 +00001433
1434 assert (rib && rn);
1435
Paul Jakma6d691122006-07-27 21:49:00 +00001436 route_lock_node (rn); /* rn route table reference */
1437
1438 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001439 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001440 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001441 zlog_debug ("%s: %s/%d: rn %p, rib %p", __func__,
1442 buf, rn->p.prefixlen, rn, rib);
1443 }
Paul Jakma6d691122006-07-27 21:49:00 +00001444
paul718e3742002-12-13 20:15:29 +00001445 head = rn->info;
1446 if (head)
Paul Jakma6d691122006-07-27 21:49:00 +00001447 {
1448 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001449 zlog_debug ("%s: %s/%d: new head, rn_status copied over", __func__,
1450 buf, rn->p.prefixlen);
Paul Jakma6d691122006-07-27 21:49:00 +00001451 head->prev = rib;
1452 /* Transfer the rn status flags to the new head RIB */
1453 rib->rn_status = head->rn_status;
1454 }
paul718e3742002-12-13 20:15:29 +00001455 rib->next = head;
1456 rn->info = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001457 rib_queue_add (&zebrad, rn);
1458}
1459
1460static void
1461rib_addnode (struct route_node *rn, struct rib *rib)
1462{
1463 /* RIB node has been un-removed before route-node is processed.
1464 * route_node must hence already be on the queue for processing..
1465 */
1466 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1467 {
1468 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001469 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001470 char buf[INET6_ADDRSTRLEN];
1471 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001472 zlog_debug ("%s: %s/%d: rn %p, un-removed rib %p",
1473 __func__, buf, rn->p.prefixlen, rn, rib);
1474 }
Paul Jakma6d691122006-07-27 21:49:00 +00001475 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1476 return;
1477 }
1478 rib_link (rn, rib);
1479}
1480
1481static void
1482rib_unlink (struct route_node *rn, struct rib *rib)
1483{
1484 struct nexthop *nexthop, *next;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001485 char buf[INET6_ADDRSTRLEN];
Paul Jakma6d691122006-07-27 21:49:00 +00001486
1487 assert (rn && rib);
1488
1489 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001490 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001491 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001492 zlog_debug ("%s: %s/%d: rn %p, rib %p",
1493 __func__, buf, rn->p.prefixlen, rn, rib);
1494 }
Paul Jakma6d691122006-07-27 21:49:00 +00001495
1496 if (rib->next)
1497 rib->next->prev = rib->prev;
1498
1499 if (rib->prev)
1500 rib->prev->next = rib->next;
1501 else
1502 {
1503 rn->info = rib->next;
1504
1505 if (rn->info)
1506 {
1507 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001508 zlog_debug ("%s: %s/%d: rn %p, rib %p, new head copy",
1509 __func__, buf, rn->p.prefixlen, rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001510 rib->next->rn_status = rib->rn_status;
1511 }
1512 }
1513
1514 /* free RIB and nexthops */
1515 for (nexthop = rib->nexthop; nexthop; nexthop = next)
1516 {
1517 next = nexthop->next;
1518 nexthop_free (nexthop);
1519 }
1520 XFREE (MTYPE_RIB, rib);
1521
1522 route_unlock_node (rn); /* rn route table reference */
paul718e3742002-12-13 20:15:29 +00001523}
1524
paula1ac18c2005-06-28 17:17:12 +00001525static void
paul718e3742002-12-13 20:15:29 +00001526rib_delnode (struct route_node *rn, struct rib *rib)
1527{
Paul Jakma6d691122006-07-27 21:49:00 +00001528 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001529 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001530 char buf[INET6_ADDRSTRLEN];
1531 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001532 zlog_debug ("%s: %s/%d: rn %p, rib %p, removing", __func__,
1533 buf, rn->p.prefixlen, rn, rib);
1534 }
Paul Jakma6d691122006-07-27 21:49:00 +00001535 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1536 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001537}
1538
1539int
1540rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001541 struct in_addr *gate, struct in_addr *src,
1542 unsigned int ifindex, u_int32_t vrf_id,
paul718e3742002-12-13 20:15:29 +00001543 u_int32_t metric, u_char distance)
1544{
1545 struct rib *rib;
1546 struct rib *same = NULL;
1547 struct route_table *table;
1548 struct route_node *rn;
1549 struct nexthop *nexthop;
1550
1551 /* Lookup table. */
1552 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1553 if (! table)
1554 return 0;
1555
1556 /* Make it sure prefixlen is applied to the prefix. */
1557 apply_mask_ipv4 (p);
1558
1559 /* Set default distance by route type. */
1560 if (distance == 0)
1561 {
1562 distance = route_info[type].distance;
1563
1564 /* iBGP distance is 200. */
1565 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1566 distance = 200;
1567 }
1568
1569 /* Lookup route node.*/
1570 rn = route_node_get (table, (struct prefix *) p);
1571
1572 /* If same type of route are installed, treat it as a implicit
1573 withdraw. */
1574 for (rib = rn->info; rib; rib = rib->next)
1575 {
Paul Jakma6d691122006-07-27 21:49:00 +00001576 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1577 continue;
1578
hassoebf1ead2005-09-21 14:58:20 +00001579 if (rib->type != type)
1580 continue;
1581 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001582 {
1583 same = rib;
1584 break;
1585 }
hassoebf1ead2005-09-21 14:58:20 +00001586 /* Duplicate connected route comes in. */
1587 else if ((nexthop = rib->nexthop) &&
1588 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001589 nexthop->ifindex == ifindex &&
1590 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001591 {
1592 rib->refcnt++;
1593 return 0 ;
1594 }
paul718e3742002-12-13 20:15:29 +00001595 }
1596
1597 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001598 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001599 rib->type = type;
1600 rib->distance = distance;
1601 rib->flags = flags;
1602 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001603 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001604 rib->nexthop_num = 0;
1605 rib->uptime = time (NULL);
1606
1607 /* Nexthop settings. */
1608 if (gate)
1609 {
1610 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001611 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001612 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001613 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001614 }
1615 else
1616 nexthop_ifindex_add (rib, ifindex);
1617
1618 /* If this route is kernel route, set FIB flag to the route. */
1619 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1620 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1621 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1622
1623 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001624 if (IS_ZEBRA_DEBUG_RIB)
1625 zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
paul718e3742002-12-13 20:15:29 +00001626 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001627
paul718e3742002-12-13 20:15:29 +00001628 /* Free implicit route.*/
1629 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001630 {
1631 if (IS_ZEBRA_DEBUG_RIB)
1632 zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001633 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001634 }
paul4d38fdb2005-04-28 17:35:14 +00001635
1636 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001637 return 0;
1638}
1639
Denis Ovsienkodc958242007-08-13 16:03:06 +00001640/* This function dumps the contents of a given RIB entry into
1641 * standard debug log. Calling function name and IP prefix in
1642 * question are passed as 1st and 2nd arguments.
1643 */
1644
1645void rib_dump (const char * func, const struct prefix_ipv4 * p, const struct rib * rib)
1646{
1647 char straddr1[INET_ADDRSTRLEN], straddr2[INET_ADDRSTRLEN];
1648 struct nexthop *nexthop;
1649
1650 inet_ntop (AF_INET, &p->prefix, straddr1, INET_ADDRSTRLEN);
1651 zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr1, p->prefixlen);
1652 zlog_debug
1653 (
1654 "%s: refcnt == %lu, uptime == %u, type == %u, table == %d",
1655 func,
1656 rib->refcnt,
1657 rib->uptime,
1658 rib->type,
1659 rib->table
1660 );
1661 zlog_debug
1662 (
1663 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1664 func,
1665 rib->metric,
1666 rib->distance,
1667 rib->flags,
1668 rib->status
1669 );
1670 zlog_debug
1671 (
1672 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1673 func,
1674 rib->nexthop_num,
1675 rib->nexthop_active_num,
1676 rib->nexthop_fib_num
1677 );
1678 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1679 {
1680 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, straddr1, INET_ADDRSTRLEN);
1681 inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, straddr2, INET_ADDRSTRLEN);
1682 zlog_debug
1683 (
1684 "%s: NH %s (%s) with flags %s%s%s",
1685 func,
1686 straddr1,
1687 straddr2,
1688 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1689 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1690 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1691 );
1692 }
1693 zlog_debug ("%s: dump complete", func);
1694}
1695
1696/* This is an exported helper to rtm_read() to dump the strange
1697 * RIB entry found by rib_lookup_ipv4_route()
1698 */
1699
1700void rib_lookup_and_dump (struct prefix_ipv4 * p)
1701{
1702 struct route_table *table;
1703 struct route_node *rn;
1704 struct rib *rib;
1705 char prefix_buf[INET_ADDRSTRLEN];
1706
1707 /* Lookup table. */
1708 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1709 if (! table)
1710 {
1711 zlog_err ("%s: vrf_table() returned NULL", __func__);
1712 return;
1713 }
1714
1715 inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
1716 /* Scan the RIB table for exactly matching RIB entry. */
1717 rn = route_node_lookup (table, (struct prefix *) p);
1718
1719 /* No route for this prefix. */
1720 if (! rn)
1721 {
1722 zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
1723 return;
1724 }
1725
1726 /* Unlock node. */
1727 route_unlock_node (rn);
1728
1729 /* let's go */
1730 for (rib = rn->info; rib; rib = rib->next)
1731 {
1732 zlog_debug
1733 (
1734 "%s: rn %p, rib %p: %s, %s",
1735 __func__,
1736 rn,
1737 rib,
1738 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
1739 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
1740 );
1741 rib_dump (__func__, p, rib);
1742 }
1743}
1744
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001745/* Check if requested address assignment will fail due to another
1746 * route being installed by zebra in FIB already. Take necessary
1747 * actions, if needed: remove such a route from FIB and deSELECT
1748 * corresponding RIB entry. Then put affected RN into RIBQ head.
1749 */
1750void rib_lookup_and_pushup (struct prefix_ipv4 * p)
1751{
1752 struct route_table *table;
1753 struct route_node *rn;
1754 struct rib *rib;
1755 unsigned changed = 0;
1756
1757 if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
1758 {
1759 zlog_err ("%s: vrf_table() returned NULL", __func__);
1760 return;
1761 }
1762
1763 /* No matches would be the simplest case. */
1764 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
1765 return;
1766
1767 /* Unlock node. */
1768 route_unlock_node (rn);
1769
1770 /* Check all RIB entries. In case any changes have to be done, requeue
1771 * the RN into RIBQ head. If the routing message about the new connected
1772 * route (generated by the IP address we are going to assign very soon)
1773 * comes before the RIBQ is processed, the new RIB entry will join
1774 * RIBQ record already on head. This is necessary for proper revalidation
1775 * of the rest of the RIB.
1776 */
1777 for (rib = rn->info; rib; rib = rib->next)
1778 {
1779 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
1780 ! RIB_SYSTEM_ROUTE (rib))
1781 {
1782 changed = 1;
1783 if (IS_ZEBRA_DEBUG_RIB)
1784 {
1785 char buf[INET_ADDRSTRLEN];
1786 inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
1787 zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
1788 rib_dump (__func__, (struct prefix_ipv4 *)&rn->p, rib);
1789 }
1790 rib_uninstall (rn, rib);
1791 }
1792 }
1793 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001794 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001795}
1796
paul718e3742002-12-13 20:15:29 +00001797int
1798rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib)
1799{
1800 struct route_table *table;
1801 struct route_node *rn;
1802 struct rib *same;
1803 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00001804
paul718e3742002-12-13 20:15:29 +00001805 /* Lookup table. */
1806 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1807 if (! table)
1808 return 0;
paul718e3742002-12-13 20:15:29 +00001809 /* Make it sure prefixlen is applied to the prefix. */
1810 apply_mask_ipv4 (p);
1811
1812 /* Set default distance by route type. */
1813 if (rib->distance == 0)
1814 {
1815 rib->distance = route_info[rib->type].distance;
1816
1817 /* iBGP distance is 200. */
1818 if (rib->type == ZEBRA_ROUTE_BGP
1819 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1820 rib->distance = 200;
1821 }
1822
1823 /* Lookup route node.*/
1824 rn = route_node_get (table, (struct prefix *) p);
1825
1826 /* If same type of route are installed, treat it as a implicit
1827 withdraw. */
1828 for (same = rn->info; same; same = same->next)
1829 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00001830 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00001831 continue;
1832
paul718e3742002-12-13 20:15:29 +00001833 if (same->type == rib->type && same->table == rib->table
1834 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001835 break;
paul718e3742002-12-13 20:15:29 +00001836 }
paul4d38fdb2005-04-28 17:35:14 +00001837
paul718e3742002-12-13 20:15:29 +00001838 /* If this route is kernel route, set FIB flag to the route. */
1839 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
1840 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1841 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1842
1843 /* Link new rib to node.*/
1844 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001845 if (IS_ZEBRA_DEBUG_RIB)
1846 {
1847 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
1848 __func__, rn, rib);
1849 rib_dump (__func__, p, rib);
1850 }
paul718e3742002-12-13 20:15:29 +00001851
paul718e3742002-12-13 20:15:29 +00001852 /* Free implicit route.*/
1853 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001854 {
1855 if (IS_ZEBRA_DEBUG_RIB)
1856 {
1857 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
1858 __func__, rn, same);
1859 rib_dump (__func__, p, same);
1860 }
paul4d38fdb2005-04-28 17:35:14 +00001861 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001862 }
paul4d38fdb2005-04-28 17:35:14 +00001863
1864 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001865 return 0;
1866}
1867
hassoebf1ead2005-09-21 14:58:20 +00001868/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00001869int
1870rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
1871 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1872{
1873 struct route_table *table;
1874 struct route_node *rn;
1875 struct rib *rib;
1876 struct rib *fib = NULL;
1877 struct rib *same = NULL;
1878 struct nexthop *nexthop;
Stephen Hemminger81cce012009-04-28 14:28:00 -07001879 char buf1[INET_ADDRSTRLEN];
1880 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00001881
1882 /* Lookup table. */
1883 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1884 if (! table)
1885 return 0;
1886
1887 /* Apply mask. */
1888 apply_mask_ipv4 (p);
1889
paul5ec90d22003-06-19 01:41:37 +00001890 if (IS_ZEBRA_DEBUG_KERNEL && gate)
ajsb6178002004-12-07 21:12:56 +00001891 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001892 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul5ec90d22003-06-19 01:41:37 +00001893 p->prefixlen,
1894 inet_ntoa (*gate),
1895 ifindex);
1896
paul718e3742002-12-13 20:15:29 +00001897 /* Lookup route node. */
1898 rn = route_node_lookup (table, (struct prefix *) p);
1899 if (! rn)
1900 {
1901 if (IS_ZEBRA_DEBUG_KERNEL)
1902 {
1903 if (gate)
ajsb6178002004-12-07 21:12:56 +00001904 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001905 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001906 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07001907 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001908 ifindex);
1909 else
ajsb6178002004-12-07 21:12:56 +00001910 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001911 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001912 p->prefixlen,
1913 ifindex);
1914 }
1915 return ZEBRA_ERR_RTNOEXIST;
1916 }
1917
1918 /* Lookup same type route. */
1919 for (rib = rn->info; rib; rib = rib->next)
1920 {
Paul Jakma6d691122006-07-27 21:49:00 +00001921 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1922 continue;
1923
paul718e3742002-12-13 20:15:29 +00001924 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1925 fib = rib;
1926
hassoebf1ead2005-09-21 14:58:20 +00001927 if (rib->type != type)
1928 continue;
1929 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
1930 nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex)
paul718e3742002-12-13 20:15:29 +00001931 {
hassoebf1ead2005-09-21 14:58:20 +00001932 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00001933 {
hassoebf1ead2005-09-21 14:58:20 +00001934 rib->refcnt--;
1935 route_unlock_node (rn);
1936 route_unlock_node (rn);
1937 return 0;
paul718e3742002-12-13 20:15:29 +00001938 }
hassoebf1ead2005-09-21 14:58:20 +00001939 same = rib;
1940 break;
paul718e3742002-12-13 20:15:29 +00001941 }
hassoebf1ead2005-09-21 14:58:20 +00001942 /* Make sure that the route found has the same gateway. */
1943 else if (gate == NULL ||
1944 ((nexthop = rib->nexthop) &&
1945 (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
1946 IPV4_ADDR_SAME (&nexthop->rgate.ipv4, gate))))
paul5ec90d22003-06-19 01:41:37 +00001947 {
hassoebf1ead2005-09-21 14:58:20 +00001948 same = rib;
1949 break;
paul718e3742002-12-13 20:15:29 +00001950 }
1951 }
1952
1953 /* If same type of route can't be found and this message is from
1954 kernel. */
1955 if (! same)
1956 {
1957 if (fib && type == ZEBRA_ROUTE_KERNEL)
1958 {
1959 /* Unset flags. */
1960 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1961 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1962
1963 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1964 }
1965 else
1966 {
1967 if (IS_ZEBRA_DEBUG_KERNEL)
1968 {
1969 if (gate)
ajsb6178002004-12-07 21:12:56 +00001970 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001971 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001972 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07001973 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001974 ifindex,
1975 type);
1976 else
ajsb6178002004-12-07 21:12:56 +00001977 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001978 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001979 p->prefixlen,
1980 ifindex,
1981 type);
1982 }
1983 route_unlock_node (rn);
1984 return ZEBRA_ERR_RTNOEXIST;
1985 }
1986 }
paul4d38fdb2005-04-28 17:35:14 +00001987
paul718e3742002-12-13 20:15:29 +00001988 if (same)
1989 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00001990
paul718e3742002-12-13 20:15:29 +00001991 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001992 return 0;
1993}
1994
1995/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00001996static void
paul718e3742002-12-13 20:15:29 +00001997static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
1998{
1999 struct rib *rib;
2000 struct route_node *rn;
2001 struct route_table *table;
2002
2003 /* Lookup table. */
2004 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2005 if (! table)
2006 return;
2007
2008 /* Lookup existing route */
2009 rn = route_node_get (table, p);
2010 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002011 {
2012 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2013 continue;
2014
2015 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2016 break;
2017 }
paul718e3742002-12-13 20:15:29 +00002018
2019 if (rib)
2020 {
2021 /* Same distance static route is there. Update it with new
2022 nexthop. */
paul718e3742002-12-13 20:15:29 +00002023 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002024 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002025 {
2026 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002027 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002028 break;
2029 case STATIC_IPV4_IFNAME:
2030 nexthop_ifname_add (rib, si->gate.ifname);
2031 break;
2032 case STATIC_IPV4_BLACKHOLE:
2033 nexthop_blackhole_add (rib);
2034 break;
paul4d38fdb2005-04-28 17:35:14 +00002035 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002036 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002037 }
2038 else
2039 {
2040 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002041 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2042
paul718e3742002-12-13 20:15:29 +00002043 rib->type = ZEBRA_ROUTE_STATIC;
2044 rib->distance = si->distance;
2045 rib->metric = 0;
2046 rib->nexthop_num = 0;
2047
2048 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002049 {
2050 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002051 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002052 break;
2053 case STATIC_IPV4_IFNAME:
2054 nexthop_ifname_add (rib, si->gate.ifname);
2055 break;
2056 case STATIC_IPV4_BLACKHOLE:
2057 nexthop_blackhole_add (rib);
2058 break;
2059 }
paul718e3742002-12-13 20:15:29 +00002060
hasso81dfcaa2003-05-25 19:21:25 +00002061 /* Save the flags of this static routes (reject, blackhole) */
2062 rib->flags = si->flags;
2063
paul718e3742002-12-13 20:15:29 +00002064 /* Link this rib to the tree. */
2065 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002066 }
2067}
2068
paula1ac18c2005-06-28 17:17:12 +00002069static int
paul718e3742002-12-13 20:15:29 +00002070static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2071{
2072 if (nexthop->type == NEXTHOP_TYPE_IPV4
2073 && si->type == STATIC_IPV4_GATEWAY
2074 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2075 return 1;
2076 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2077 && si->type == STATIC_IPV4_IFNAME
2078 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2079 return 1;
paul595db7f2003-05-25 21:35:06 +00002080 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2081 && si->type == STATIC_IPV4_BLACKHOLE)
2082 return 1;
paule8e19462006-01-19 20:16:55 +00002083 return 0;
paul718e3742002-12-13 20:15:29 +00002084}
2085
2086/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002087static void
paul718e3742002-12-13 20:15:29 +00002088static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
2089{
2090 struct route_node *rn;
2091 struct rib *rib;
2092 struct nexthop *nexthop;
2093 struct route_table *table;
2094
2095 /* Lookup table. */
2096 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2097 if (! table)
2098 return;
paul4d38fdb2005-04-28 17:35:14 +00002099
paul718e3742002-12-13 20:15:29 +00002100 /* Lookup existing route with type and distance. */
2101 rn = route_node_lookup (table, p);
2102 if (! rn)
2103 return;
2104
2105 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002106 {
2107 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2108 continue;
2109
2110 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2111 break;
2112 }
paul718e3742002-12-13 20:15:29 +00002113
2114 if (! rib)
2115 {
2116 route_unlock_node (rn);
2117 return;
2118 }
2119
2120 /* Lookup nexthop. */
2121 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2122 if (static_ipv4_nexthop_same (nexthop, si))
2123 break;
2124
2125 /* Can't find nexthop. */
2126 if (! nexthop)
2127 {
2128 route_unlock_node (rn);
2129 return;
2130 }
2131
2132 /* Check nexthop. */
2133 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002134 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002135 else
2136 {
paul6baeb982003-10-28 03:47:15 +00002137 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2138 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002139 nexthop_delete (rib, nexthop);
2140 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002141 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002142 }
paul718e3742002-12-13 20:15:29 +00002143 /* Unlock node. */
2144 route_unlock_node (rn);
2145}
2146
2147/* Add static route into static route configuration. */
2148int
hasso39db97e2004-10-12 20:50:58 +00002149static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00002150 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002151{
2152 u_char type = 0;
2153 struct route_node *rn;
2154 struct static_ipv4 *si;
2155 struct static_ipv4 *pp;
2156 struct static_ipv4 *cp;
2157 struct static_ipv4 *update = NULL;
2158 struct route_table *stable;
2159
2160 /* Lookup table. */
2161 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2162 if (! stable)
2163 return -1;
2164
2165 /* Lookup static route prefix. */
2166 rn = route_node_get (stable, p);
2167
2168 /* Make flags. */
2169 if (gate)
2170 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002171 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002172 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002173 else
2174 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002175
2176 /* Do nothing if there is a same static route. */
2177 for (si = rn->info; si; si = si->next)
2178 {
2179 if (type == si->type
2180 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2181 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2182 {
2183 if (distance == si->distance)
2184 {
2185 route_unlock_node (rn);
2186 return 0;
2187 }
2188 else
2189 update = si;
2190 }
2191 }
2192
Paul Jakma3c0755d2006-12-08 00:53:14 +00002193 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002194 if (update)
2195 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
2196
2197 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002198 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
paul718e3742002-12-13 20:15:29 +00002199
2200 si->type = type;
2201 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002202 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002203
2204 if (gate)
2205 si->gate.ipv4 = *gate;
2206 if (ifname)
2207 si->gate.ifname = XSTRDUP (0, ifname);
2208
2209 /* Add new static route information to the tree with sort by
2210 distance value and gateway address. */
2211 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2212 {
2213 if (si->distance < cp->distance)
2214 break;
2215 if (si->distance > cp->distance)
2216 continue;
2217 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2218 {
2219 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2220 break;
2221 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2222 continue;
2223 }
2224 }
2225
2226 /* Make linked list. */
2227 if (pp)
2228 pp->next = si;
2229 else
2230 rn->info = si;
2231 if (cp)
2232 cp->prev = si;
2233 si->prev = pp;
2234 si->next = cp;
2235
2236 /* Install into rib. */
2237 static_install_ipv4 (p, si);
2238
2239 return 1;
2240}
2241
2242/* Delete static route from static route configuration. */
2243int
hasso39db97e2004-10-12 20:50:58 +00002244static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00002245 u_char distance, u_int32_t vrf_id)
2246{
2247 u_char type = 0;
2248 struct route_node *rn;
2249 struct static_ipv4 *si;
2250 struct route_table *stable;
2251
2252 /* Lookup table. */
2253 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2254 if (! stable)
2255 return -1;
2256
2257 /* Lookup static route prefix. */
2258 rn = route_node_lookup (stable, p);
2259 if (! rn)
2260 return 0;
2261
2262 /* Make flags. */
2263 if (gate)
2264 type = STATIC_IPV4_GATEWAY;
2265 else if (ifname)
2266 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002267 else
2268 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002269
2270 /* Find same static route is the tree */
2271 for (si = rn->info; si; si = si->next)
2272 if (type == si->type
2273 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2274 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2275 break;
2276
2277 /* Can't find static route. */
2278 if (! si)
2279 {
2280 route_unlock_node (rn);
2281 return 0;
2282 }
2283
2284 /* Install into rib. */
2285 static_uninstall_ipv4 (p, si);
2286
2287 /* Unlink static route from linked list. */
2288 if (si->prev)
2289 si->prev->next = si->next;
2290 else
2291 rn->info = si->next;
2292 if (si->next)
2293 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002294 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002295
2296 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002297 if (ifname)
2298 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002299 XFREE (MTYPE_STATIC_IPV4, si);
2300
paul143a3852003-09-29 20:06:13 +00002301 route_unlock_node (rn);
2302
paul718e3742002-12-13 20:15:29 +00002303 return 1;
2304}
2305
2306
2307#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00002308static int
paul718e3742002-12-13 20:15:29 +00002309rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2310 struct in6_addr *gate, unsigned int ifindex, int table)
2311{
hasso726f9b22003-05-25 21:04:54 +00002312 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2313#if defined (MUSICA) || defined (LINUX)
2314 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2315 if (p->prefixlen == 96)
2316 return 0;
2317#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00002318 return 1;
hasso726f9b22003-05-25 21:04:54 +00002319 }
paul718e3742002-12-13 20:15:29 +00002320 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
2321 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
2322 {
2323 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
2324 return 1;
2325 }
2326 return 0;
2327}
2328
2329int
2330rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00002331 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
2332 u_int32_t metric, u_char distance)
paul718e3742002-12-13 20:15:29 +00002333{
2334 struct rib *rib;
2335 struct rib *same = NULL;
2336 struct route_table *table;
2337 struct route_node *rn;
2338 struct nexthop *nexthop;
2339
paul718e3742002-12-13 20:15:29 +00002340 /* Lookup table. */
2341 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2342 if (! table)
2343 return 0;
2344
2345 /* Make sure mask is applied. */
2346 apply_mask_ipv6 (p);
2347
2348 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002349 if (!distance)
2350 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002351
2352 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2353 distance = 200;
2354
2355 /* Filter bogus route. */
2356 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
2357 return 0;
2358
2359 /* Lookup route node.*/
2360 rn = route_node_get (table, (struct prefix *) p);
2361
2362 /* If same type of route are installed, treat it as a implicit
2363 withdraw. */
2364 for (rib = rn->info; rib; rib = rib->next)
2365 {
Paul Jakma6d691122006-07-27 21:49:00 +00002366 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2367 continue;
2368
hassoebf1ead2005-09-21 14:58:20 +00002369 if (rib->type != type)
2370 continue;
2371 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002372 {
2373 same = rib;
paul718e3742002-12-13 20:15:29 +00002374 break;
2375 }
hassoebf1ead2005-09-21 14:58:20 +00002376 else if ((nexthop = rib->nexthop) &&
2377 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2378 nexthop->ifindex == ifindex)
2379 {
2380 rib->refcnt++;
2381 return 0;
2382 }
paul718e3742002-12-13 20:15:29 +00002383 }
2384
2385 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002386 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2387
paul718e3742002-12-13 20:15:29 +00002388 rib->type = type;
2389 rib->distance = distance;
2390 rib->flags = flags;
2391 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00002392 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00002393 rib->nexthop_num = 0;
2394 rib->uptime = time (NULL);
2395
2396 /* Nexthop settings. */
2397 if (gate)
2398 {
2399 if (ifindex)
2400 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2401 else
2402 nexthop_ipv6_add (rib, gate);
2403 }
2404 else
2405 nexthop_ifindex_add (rib, ifindex);
2406
2407 /* If this route is kernel route, set FIB flag to the route. */
2408 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2409 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2410 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2411
2412 /* Link new rib to node.*/
2413 rib_addnode (rn, rib);
2414
paul718e3742002-12-13 20:15:29 +00002415 /* Free implicit route.*/
2416 if (same)
paul4d38fdb2005-04-28 17:35:14 +00002417 rib_delnode (rn, same);
2418
2419 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002420 return 0;
2421}
2422
hassoebf1ead2005-09-21 14:58:20 +00002423/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002424int
2425rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
2426 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
2427{
2428 struct route_table *table;
2429 struct route_node *rn;
2430 struct rib *rib;
2431 struct rib *fib = NULL;
2432 struct rib *same = NULL;
2433 struct nexthop *nexthop;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002434 char buf1[INET6_ADDRSTRLEN];
2435 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002436
2437 /* Apply mask. */
2438 apply_mask_ipv6 (p);
2439
2440 /* Lookup table. */
2441 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2442 if (! table)
2443 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002444
paul718e3742002-12-13 20:15:29 +00002445 /* Lookup route node. */
2446 rn = route_node_lookup (table, (struct prefix *) p);
2447 if (! rn)
2448 {
2449 if (IS_ZEBRA_DEBUG_KERNEL)
2450 {
2451 if (gate)
ajsb6178002004-12-07 21:12:56 +00002452 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002453 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002454 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002455 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002456 ifindex);
2457 else
ajsb6178002004-12-07 21:12:56 +00002458 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002459 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002460 p->prefixlen,
2461 ifindex);
2462 }
2463 return ZEBRA_ERR_RTNOEXIST;
2464 }
2465
2466 /* Lookup same type route. */
2467 for (rib = rn->info; rib; rib = rib->next)
2468 {
Paul Jakma6d691122006-07-27 21:49:00 +00002469 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2470 continue;
2471
paul718e3742002-12-13 20:15:29 +00002472 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2473 fib = rib;
2474
hassoebf1ead2005-09-21 14:58:20 +00002475 if (rib->type != type)
2476 continue;
2477 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
2478 nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex)
paul718e3742002-12-13 20:15:29 +00002479 {
hassoebf1ead2005-09-21 14:58:20 +00002480 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002481 {
hassoebf1ead2005-09-21 14:58:20 +00002482 rib->refcnt--;
2483 route_unlock_node (rn);
2484 route_unlock_node (rn);
2485 return 0;
paul718e3742002-12-13 20:15:29 +00002486 }
hassoebf1ead2005-09-21 14:58:20 +00002487 same = rib;
2488 break;
paul718e3742002-12-13 20:15:29 +00002489 }
hassoebf1ead2005-09-21 14:58:20 +00002490 /* Make sure that the route found has the same gateway. */
2491 else if (gate == NULL ||
2492 ((nexthop = rib->nexthop) &&
2493 (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate) ||
2494 IPV6_ADDR_SAME (&nexthop->rgate.ipv6, gate))))
paul718e3742002-12-13 20:15:29 +00002495 {
hassoebf1ead2005-09-21 14:58:20 +00002496 same = rib;
2497 break;
paul718e3742002-12-13 20:15:29 +00002498 }
2499 }
2500
2501 /* If same type of route can't be found and this message is from
2502 kernel. */
2503 if (! same)
2504 {
2505 if (fib && type == ZEBRA_ROUTE_KERNEL)
2506 {
2507 /* Unset flags. */
2508 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2509 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2510
2511 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2512 }
2513 else
2514 {
2515 if (IS_ZEBRA_DEBUG_KERNEL)
2516 {
2517 if (gate)
ajsb6178002004-12-07 21:12:56 +00002518 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002519 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002520 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002521 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002522 ifindex,
2523 type);
2524 else
ajsb6178002004-12-07 21:12:56 +00002525 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002526 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002527 p->prefixlen,
2528 ifindex,
2529 type);
2530 }
2531 route_unlock_node (rn);
2532 return ZEBRA_ERR_RTNOEXIST;
2533 }
2534 }
2535
2536 if (same)
2537 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002538
paul718e3742002-12-13 20:15:29 +00002539 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002540 return 0;
2541}
2542
2543/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002544static void
paul718e3742002-12-13 20:15:29 +00002545static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2546{
2547 struct rib *rib;
2548 struct route_table *table;
2549 struct route_node *rn;
2550
2551 /* Lookup table. */
2552 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2553 if (! table)
2554 return;
2555
2556 /* Lookup existing route */
2557 rn = route_node_get (table, p);
2558 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002559 {
2560 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2561 continue;
2562
2563 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2564 break;
2565 }
paul718e3742002-12-13 20:15:29 +00002566
2567 if (rib)
2568 {
2569 /* Same distance static route is there. Update it with new
2570 nexthop. */
paul718e3742002-12-13 20:15:29 +00002571 route_unlock_node (rn);
2572
2573 switch (si->type)
2574 {
2575 case STATIC_IPV6_GATEWAY:
2576 nexthop_ipv6_add (rib, &si->ipv6);
2577 break;
2578 case STATIC_IPV6_IFNAME:
2579 nexthop_ifname_add (rib, si->ifname);
2580 break;
2581 case STATIC_IPV6_GATEWAY_IFNAME:
2582 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2583 break;
2584 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002585 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002586 }
2587 else
2588 {
2589 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002590 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2591
paul718e3742002-12-13 20:15:29 +00002592 rib->type = ZEBRA_ROUTE_STATIC;
2593 rib->distance = si->distance;
2594 rib->metric = 0;
2595 rib->nexthop_num = 0;
2596
2597 switch (si->type)
2598 {
2599 case STATIC_IPV6_GATEWAY:
2600 nexthop_ipv6_add (rib, &si->ipv6);
2601 break;
2602 case STATIC_IPV6_IFNAME:
2603 nexthop_ifname_add (rib, si->ifname);
2604 break;
2605 case STATIC_IPV6_GATEWAY_IFNAME:
2606 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2607 break;
2608 }
2609
hasso81dfcaa2003-05-25 19:21:25 +00002610 /* Save the flags of this static routes (reject, blackhole) */
2611 rib->flags = si->flags;
2612
paul718e3742002-12-13 20:15:29 +00002613 /* Link this rib to the tree. */
2614 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002615 }
2616}
2617
paula1ac18c2005-06-28 17:17:12 +00002618static int
paul718e3742002-12-13 20:15:29 +00002619static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2620{
2621 if (nexthop->type == NEXTHOP_TYPE_IPV6
2622 && si->type == STATIC_IPV6_GATEWAY
2623 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2624 return 1;
2625 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2626 && si->type == STATIC_IPV6_IFNAME
2627 && strcmp (nexthop->ifname, si->ifname) == 0)
2628 return 1;
2629 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2630 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2631 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2632 && strcmp (nexthop->ifname, si->ifname) == 0)
2633 return 1;
paule8e19462006-01-19 20:16:55 +00002634 return 0;
paul718e3742002-12-13 20:15:29 +00002635}
2636
paula1ac18c2005-06-28 17:17:12 +00002637static void
paul718e3742002-12-13 20:15:29 +00002638static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2639{
2640 struct route_table *table;
2641 struct route_node *rn;
2642 struct rib *rib;
2643 struct nexthop *nexthop;
2644
2645 /* Lookup table. */
2646 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2647 if (! table)
2648 return;
2649
2650 /* Lookup existing route with type and distance. */
2651 rn = route_node_lookup (table, (struct prefix *) p);
2652 if (! rn)
2653 return;
2654
2655 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002656 {
2657 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2658 continue;
2659
2660 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2661 break;
2662 }
2663
paul718e3742002-12-13 20:15:29 +00002664 if (! rib)
2665 {
2666 route_unlock_node (rn);
2667 return;
2668 }
2669
2670 /* Lookup nexthop. */
2671 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2672 if (static_ipv6_nexthop_same (nexthop, si))
2673 break;
2674
2675 /* Can't find nexthop. */
2676 if (! nexthop)
2677 {
2678 route_unlock_node (rn);
2679 return;
2680 }
2681
2682 /* Check nexthop. */
2683 if (rib->nexthop_num == 1)
2684 {
2685 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002686 }
2687 else
2688 {
paul6baeb982003-10-28 03:47:15 +00002689 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2690 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002691 nexthop_delete (rib, nexthop);
2692 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002693 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002694 }
paul718e3742002-12-13 20:15:29 +00002695 /* Unlock node. */
2696 route_unlock_node (rn);
2697}
2698
2699/* Add static route into static route configuration. */
2700int
2701static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002702 const char *ifname, u_char flags, u_char distance,
2703 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002704{
2705 struct route_node *rn;
2706 struct static_ipv6 *si;
2707 struct static_ipv6 *pp;
2708 struct static_ipv6 *cp;
2709 struct route_table *stable;
2710
2711 /* Lookup table. */
2712 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2713 if (! stable)
2714 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00002715
2716 if (!gate &&
2717 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
2718 return -1;
2719
2720 if (!ifname &&
2721 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
2722 return -1;
paul718e3742002-12-13 20:15:29 +00002723
2724 /* Lookup static route prefix. */
2725 rn = route_node_get (stable, p);
2726
2727 /* Do nothing if there is a same static route. */
2728 for (si = rn->info; si; si = si->next)
2729 {
2730 if (distance == si->distance
2731 && type == si->type
2732 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2733 && (! ifname || strcmp (ifname, si->ifname) == 0))
2734 {
2735 route_unlock_node (rn);
2736 return 0;
2737 }
2738 }
2739
2740 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002741 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
paul718e3742002-12-13 20:15:29 +00002742
2743 si->type = type;
2744 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002745 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002746
2747 switch (type)
2748 {
2749 case STATIC_IPV6_GATEWAY:
2750 si->ipv6 = *gate;
2751 break;
2752 case STATIC_IPV6_IFNAME:
2753 si->ifname = XSTRDUP (0, ifname);
2754 break;
2755 case STATIC_IPV6_GATEWAY_IFNAME:
2756 si->ipv6 = *gate;
2757 si->ifname = XSTRDUP (0, ifname);
2758 break;
2759 }
2760
2761 /* Add new static route information to the tree with sort by
2762 distance value and gateway address. */
2763 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2764 {
2765 if (si->distance < cp->distance)
2766 break;
2767 if (si->distance > cp->distance)
2768 continue;
2769 }
2770
2771 /* Make linked list. */
2772 if (pp)
2773 pp->next = si;
2774 else
2775 rn->info = si;
2776 if (cp)
2777 cp->prev = si;
2778 si->prev = pp;
2779 si->next = cp;
2780
2781 /* Install into rib. */
2782 static_install_ipv6 (p, si);
2783
2784 return 1;
2785}
2786
2787/* Delete static route from static route configuration. */
2788int
2789static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002790 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002791{
2792 struct route_node *rn;
2793 struct static_ipv6 *si;
2794 struct route_table *stable;
2795
2796 /* Lookup table. */
2797 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2798 if (! stable)
2799 return -1;
2800
2801 /* Lookup static route prefix. */
2802 rn = route_node_lookup (stable, p);
2803 if (! rn)
2804 return 0;
2805
2806 /* Find same static route is the tree */
2807 for (si = rn->info; si; si = si->next)
2808 if (distance == si->distance
2809 && type == si->type
2810 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2811 && (! ifname || strcmp (ifname, si->ifname) == 0))
2812 break;
2813
2814 /* Can't find static route. */
2815 if (! si)
2816 {
2817 route_unlock_node (rn);
2818 return 0;
2819 }
2820
2821 /* Install into rib. */
2822 static_uninstall_ipv6 (p, si);
2823
2824 /* Unlink static route from linked list. */
2825 if (si->prev)
2826 si->prev->next = si->next;
2827 else
2828 rn->info = si->next;
2829 if (si->next)
2830 si->next->prev = si->prev;
2831
2832 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002833 if (ifname)
2834 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00002835 XFREE (MTYPE_STATIC_IPV6, si);
2836
2837 return 1;
2838}
2839#endif /* HAVE_IPV6 */
2840
2841/* RIB update function. */
2842void
paula1ac18c2005-06-28 17:17:12 +00002843rib_update (void)
paul718e3742002-12-13 20:15:29 +00002844{
2845 struct route_node *rn;
2846 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00002847
paul718e3742002-12-13 20:15:29 +00002848 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2849 if (table)
2850 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002851 if (rn->info)
Paul Jakma6d691122006-07-27 21:49:00 +00002852 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002853
2854 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2855 if (table)
2856 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002857 if (rn->info)
Paul Jakma6d691122006-07-27 21:49:00 +00002858 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002859}
2860
2861/* Interface goes up. */
paula1ac18c2005-06-28 17:17:12 +00002862static void
paul718e3742002-12-13 20:15:29 +00002863rib_if_up (struct interface *ifp)
2864{
2865 rib_update ();
2866}
2867
2868/* Interface goes down. */
paula1ac18c2005-06-28 17:17:12 +00002869static void
paul718e3742002-12-13 20:15:29 +00002870rib_if_down (struct interface *ifp)
2871{
2872 rib_update ();
2873}
2874
2875/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00002876static void
paul718e3742002-12-13 20:15:29 +00002877rib_weed_table (struct route_table *table)
2878{
2879 struct route_node *rn;
2880 struct rib *rib;
2881 struct rib *next;
2882
2883 if (table)
2884 for (rn = route_top (table); rn; rn = route_next (rn))
2885 for (rib = rn->info; rib; rib = next)
2886 {
2887 next = rib->next;
2888
Paul Jakma6d691122006-07-27 21:49:00 +00002889 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2890 continue;
2891
paulb21b19c2003-06-15 01:28:29 +00002892 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00002893 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00002894 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002895 }
2896}
2897
2898/* Delete all routes from non main table. */
2899void
paula1ac18c2005-06-28 17:17:12 +00002900rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00002901{
2902 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2903 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2904}
2905
2906/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00002907static void
paul718e3742002-12-13 20:15:29 +00002908rib_sweep_table (struct route_table *table)
2909{
2910 struct route_node *rn;
2911 struct rib *rib;
2912 struct rib *next;
2913 int ret = 0;
2914
2915 if (table)
2916 for (rn = route_top (table); rn; rn = route_next (rn))
2917 for (rib = rn->info; rib; rib = next)
2918 {
2919 next = rib->next;
2920
Paul Jakma6d691122006-07-27 21:49:00 +00002921 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2922 continue;
2923
paul718e3742002-12-13 20:15:29 +00002924 if (rib->type == ZEBRA_ROUTE_KERNEL &&
2925 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
2926 {
2927 ret = rib_uninstall_kernel (rn, rib);
2928 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00002929 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002930 }
2931 }
2932}
2933
2934/* Sweep all RIB tables. */
2935void
paula1ac18c2005-06-28 17:17:12 +00002936rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00002937{
2938 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2939 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2940}
2941
2942/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00002943static void
paul718e3742002-12-13 20:15:29 +00002944rib_close_table (struct route_table *table)
2945{
2946 struct route_node *rn;
2947 struct rib *rib;
2948
2949 if (table)
2950 for (rn = route_top (table); rn; rn = route_next (rn))
2951 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002952 {
2953 if (! RIB_SYSTEM_ROUTE (rib)
2954 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2955 rib_uninstall_kernel (rn, rib);
2956 }
paul718e3742002-12-13 20:15:29 +00002957}
2958
2959/* Close all RIB tables. */
2960void
paula1ac18c2005-06-28 17:17:12 +00002961rib_close (void)
paul718e3742002-12-13 20:15:29 +00002962{
2963 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2964 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2965}
2966
2967/* Routing information base initialize. */
2968void
paula1ac18c2005-06-28 17:17:12 +00002969rib_init (void)
paul718e3742002-12-13 20:15:29 +00002970{
paul4d38fdb2005-04-28 17:35:14 +00002971 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00002972 /* VRF initialization. */
2973 vrf_init ();
2974}