blob: e2108fcb199d70a6db4569f576a09721602a3c21 [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;
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000908 int prev_active, 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);
916 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
917 rib->nexthop_active_num++;
918 if (prev_active != new_active)
919 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
920 }
paul718e3742002-12-13 20:15:29 +0000921 return rib->nexthop_active_num;
922}
paul6baeb982003-10-28 03:47:15 +0000923
paul718e3742002-12-13 20:15:29 +0000924
paul718e3742002-12-13 20:15:29 +0000925
paula1ac18c2005-06-28 17:17:12 +0000926static void
paul718e3742002-12-13 20:15:29 +0000927rib_install_kernel (struct route_node *rn, struct rib *rib)
928{
929 int ret = 0;
930 struct nexthop *nexthop;
931
932 switch (PREFIX_FAMILY (&rn->p))
933 {
934 case AF_INET:
935 ret = kernel_add_ipv4 (&rn->p, rib);
936 break;
937#ifdef HAVE_IPV6
938 case AF_INET6:
939 ret = kernel_add_ipv6 (&rn->p, rib);
940 break;
941#endif /* HAVE_IPV6 */
942 }
943
Denis Ovsienkodc958242007-08-13 16:03:06 +0000944 /* This condition is never met, if we are using rt_socket.c */
paul718e3742002-12-13 20:15:29 +0000945 if (ret < 0)
946 {
947 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
948 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
949 }
950}
951
952/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +0000953static int
paul718e3742002-12-13 20:15:29 +0000954rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
955{
956 int ret = 0;
957 struct nexthop *nexthop;
958
959 switch (PREFIX_FAMILY (&rn->p))
960 {
961 case AF_INET:
962 ret = kernel_delete_ipv4 (&rn->p, rib);
963 break;
964#ifdef HAVE_IPV6
965 case AF_INET6:
966 ret = kernel_delete_ipv6 (&rn->p, rib);
967 break;
968#endif /* HAVE_IPV6 */
969 }
970
971 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
972 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
973
974 return ret;
975}
976
977/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +0000978static void
paul718e3742002-12-13 20:15:29 +0000979rib_uninstall (struct route_node *rn, struct rib *rib)
980{
981 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
982 {
983 redistribute_delete (&rn->p, rib);
984 if (! RIB_SYSTEM_ROUTE (rib))
985 rib_uninstall_kernel (rn, rib);
986 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
987 }
988}
989
Paul Jakma6d691122006-07-27 21:49:00 +0000990static void rib_unlink (struct route_node *, struct rib *);
991
paul718e3742002-12-13 20:15:29 +0000992/* Core function for processing routing information base. */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +0000993static void
994rib_process (struct route_node *rn)
paul718e3742002-12-13 20:15:29 +0000995{
996 struct rib *rib;
997 struct rib *next;
998 struct rib *fib = NULL;
999 struct rib *select = NULL;
Paul Jakma6d691122006-07-27 21:49:00 +00001000 struct rib *del = NULL;
pauld753e9e2003-01-22 19:45:50 +00001001 int installed = 0;
1002 struct nexthop *nexthop = NULL;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001003 char buf[INET6_ADDRSTRLEN];
paul4d38fdb2005-04-28 17:35:14 +00001004
1005 assert (rn);
1006
Paul Jakma93bdada2007-08-06 19:25:11 +00001007 if (IS_ZEBRA_DEBUG_RIB || IS_ZEBRA_DEBUG_RIB_Q)
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001008 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001009
paul718e3742002-12-13 20:15:29 +00001010 for (rib = rn->info; rib; rib = next)
1011 {
Denis Ovsienkodc958242007-08-13 16:03:06 +00001012 /* The next pointer is saved, because current pointer
1013 * may be passed to rib_unlink() in the middle of iteration.
1014 */
paul718e3742002-12-13 20:15:29 +00001015 next = rib->next;
pauld753e9e2003-01-22 19:45:50 +00001016
paul718e3742002-12-13 20:15:29 +00001017 /* Currently installed rib. */
1018 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Paul Jakma6d691122006-07-27 21:49:00 +00001019 {
1020 assert (fib == NULL);
1021 fib = rib;
1022 }
1023
1024 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1025 * which we need to do do further work with below.
1026 */
1027 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1028 {
1029 if (rib != fib)
1030 {
1031 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001032 zlog_debug ("%s: %s/%d: rn %p, removing rib %p", __func__,
1033 buf, rn->p.prefixlen, rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001034 rib_unlink (rn, rib);
1035 }
1036 else
1037 del = rib;
1038
1039 continue;
1040 }
paul4d38fdb2005-04-28 17:35:14 +00001041
paul718e3742002-12-13 20:15:29 +00001042 /* Skip unreachable nexthop. */
1043 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +00001044 continue;
paul718e3742002-12-13 20:15:29 +00001045
1046 /* Infinit distance. */
1047 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +00001048 continue;
paul718e3742002-12-13 20:15:29 +00001049
paulaf887b52006-01-18 14:52:52 +00001050 /* Newly selected rib, the common case. */
1051 if (!select)
1052 {
1053 select = rib;
1054 continue;
1055 }
1056
1057 /* filter route selection in following order:
paulaf887b52006-01-18 14:52:52 +00001058 * - connected beats other types
paula8d9c1f2006-01-25 06:31:04 +00001059 * - lower distance beats higher
paulaf887b52006-01-18 14:52:52 +00001060 * - lower metric beats higher for equal distance
1061 * - last, hence oldest, route wins tie break.
1062 */
paula1038a12006-01-30 14:08:51 +00001063
1064 /* Connected routes. Pick the last connected
1065 * route of the set of lowest metric connected routes.
1066 */
paula8d9c1f2006-01-25 06:31:04 +00001067 if (rib->type == ZEBRA_ROUTE_CONNECT)
1068 {
paula1038a12006-01-30 14:08:51 +00001069 if (select->type != ZEBRA_ROUTE_CONNECT
paula8d9c1f2006-01-25 06:31:04 +00001070 || rib->metric <= select->metric)
paula1038a12006-01-30 14:08:51 +00001071 select = rib;
1072 continue;
paula8d9c1f2006-01-25 06:31:04 +00001073 }
1074 else if (select->type == ZEBRA_ROUTE_CONNECT)
1075 continue;
1076
1077 /* higher distance loses */
1078 if (rib->distance > select->distance)
1079 continue;
1080
1081 /* lower wins */
1082 if (rib->distance < select->distance)
1083 {
paulaf887b52006-01-18 14:52:52 +00001084 select = rib;
paula8d9c1f2006-01-25 06:31:04 +00001085 continue;
1086 }
1087
1088 /* metric tie-breaks equal distance */
1089 if (rib->metric <= select->metric)
1090 select = rib;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001091 } /* for (rib = rn->info; rib; rib = next) */
1092
1093 /* After the cycle is finished, the following pointers will be set:
1094 * select --- the winner RIB entry, if any was found, otherwise NULL
1095 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1096 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1097 * rib --- NULL
1098 */
1099
1100 /* Same RIB entry is selected. Update FIB and finish. */
paul718e3742002-12-13 20:15:29 +00001101 if (select && select == fib)
1102 {
Paul Jakma6d691122006-07-27 21:49:00 +00001103 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001104 zlog_debug ("%s: %s/%d: Updating existing route, select %p, fib %p",
1105 __func__, buf, rn->p.prefixlen, select, fib);
paul718e3742002-12-13 20:15:29 +00001106 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +00001107 {
1108 redistribute_delete (&rn->p, select);
1109 if (! RIB_SYSTEM_ROUTE (select))
1110 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001111
paul4d38fdb2005-04-28 17:35:14 +00001112 /* Set real nexthop. */
1113 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +00001114
paul4d38fdb2005-04-28 17:35:14 +00001115 if (! RIB_SYSTEM_ROUTE (select))
1116 rib_install_kernel (rn, select);
1117 redistribute_add (&rn->p, select);
1118 }
pauld753e9e2003-01-22 19:45:50 +00001119 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001120 {
1121 /* Housekeeping code to deal with
1122 race conditions in kernel with linux
1123 netlink reporting interface up before IPv4 or IPv6 protocol
1124 is ready to add routes.
1125 This makes sure the routes are IN the kernel.
1126 */
pauld753e9e2003-01-22 19:45:50 +00001127
paul4d38fdb2005-04-28 17:35:14 +00001128 for (nexthop = select->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001129 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
paul4d38fdb2005-04-28 17:35:14 +00001130 {
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001131 installed = 1;
1132 break;
paul4d38fdb2005-04-28 17:35:14 +00001133 }
1134 if (! installed)
1135 rib_install_kernel (rn, select);
1136 }
Paul Jakma6d691122006-07-27 21:49:00 +00001137 goto end;
paul718e3742002-12-13 20:15:29 +00001138 }
1139
Denis Ovsienkodc958242007-08-13 16:03:06 +00001140 /* At this point we either haven't found the best RIB entry or it is
1141 * different from what we currently intend to flag with SELECTED. In both
1142 * cases, if a RIB block is present in FIB, it should be withdrawn.
1143 */
paul718e3742002-12-13 20:15:29 +00001144 if (fib)
1145 {
Paul Jakma6d691122006-07-27 21:49:00 +00001146 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001147 zlog_debug ("%s: %s/%d: Removing existing route, fib %p", __func__,
1148 buf, rn->p.prefixlen, fib);
paul718e3742002-12-13 20:15:29 +00001149 redistribute_delete (&rn->p, fib);
1150 if (! RIB_SYSTEM_ROUTE (fib))
1151 rib_uninstall_kernel (rn, fib);
1152 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1153
1154 /* Set real nexthop. */
1155 nexthop_active_update (rn, fib, 1);
1156 }
1157
Denis Ovsienkodc958242007-08-13 16:03:06 +00001158 /* Regardless of some RIB entry being SELECTED or not before, now we can
1159 * tell, that if a new winner exists, FIB is still not updated with this
1160 * data, but ready to be.
1161 */
paul718e3742002-12-13 20:15:29 +00001162 if (select)
1163 {
Paul Jakma6d691122006-07-27 21:49:00 +00001164 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001165 zlog_debug ("%s: %s/%d: Adding route, select %p", __func__, buf,
1166 rn->p.prefixlen, select);
paul718e3742002-12-13 20:15:29 +00001167 /* Set real nexthop. */
1168 nexthop_active_update (rn, select, 1);
1169
1170 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001171 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001172 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1173 redistribute_add (&rn->p, select);
1174 }
paul4d38fdb2005-04-28 17:35:14 +00001175
Paul Jakma6d691122006-07-27 21:49:00 +00001176 /* FIB route was removed, should be deleted */
1177 if (del)
1178 {
1179 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001180 zlog_debug ("%s: %s/%d: Deleting fib %p, rn %p", __func__, buf,
1181 rn->p.prefixlen, del, rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001182 rib_unlink (rn, del);
1183 }
paul4d38fdb2005-04-28 17:35:14 +00001184
Paul Jakma6d691122006-07-27 21:49:00 +00001185end:
1186 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma93bdada2007-08-06 19:25:11 +00001187 zlog_debug ("%s: %s/%d: rn %p dequeued", __func__, buf, rn->p.prefixlen, rn);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001188}
1189
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001190/* Take a list of route_node structs and return 1, if there was a record
1191 * picked from it and processed by rib_process(). Don't process more,
1192 * than one RN record; operate only in the specified sub-queue.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001193 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001194static unsigned int
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001195process_subq (struct list * subq, u_char qindex)
1196{
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001197 struct listnode *lnode = listhead (subq);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001198 struct route_node *rnode;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001199
1200 if (!lnode)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001201 return 0;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001202
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001203 rnode = listgetdata (lnode);
1204 rib_process (rnode);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001205
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001206 if (rnode->info) /* The first RIB record is holding the flags bitmask. */
1207 UNSET_FLAG (((struct rib *)rnode->info)->rn_status, RIB_ROUTE_QUEUED(qindex));
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001208 else
1209 {
1210 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1211 __func__, rnode, rnode->lock);
1212 zlog_backtrace(LOG_DEBUG);
1213 }
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001214 route_unlock_node (rnode);
1215 list_delete_node (subq, lnode);
1216 return 1;
1217}
1218
1219/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1220 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1221 * is pointed to the meta queue structure.
1222 */
1223static wq_item_status
1224meta_queue_process (struct work_queue *dummy, void *data)
1225{
1226 struct meta_queue * mq = data;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001227 unsigned i;
1228
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001229 for (i = 0; i < MQ_SIZE; i++)
1230 if (process_subq (mq->subq[i], i))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001231 {
1232 mq->size--;
1233 break;
1234 }
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001235 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1236}
1237
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001238/* Map from rib types to queue type (priority) in meta queue */
1239static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
1240 [ZEBRA_ROUTE_SYSTEM] = 4,
1241 [ZEBRA_ROUTE_KERNEL] = 0,
1242 [ZEBRA_ROUTE_CONNECT] = 0,
1243 [ZEBRA_ROUTE_STATIC] = 1,
1244 [ZEBRA_ROUTE_RIP] = 2,
1245 [ZEBRA_ROUTE_RIPNG] = 2,
1246 [ZEBRA_ROUTE_OSPF] = 2,
1247 [ZEBRA_ROUTE_OSPF6] = 2,
1248 [ZEBRA_ROUTE_ISIS] = 2,
1249 [ZEBRA_ROUTE_BGP] = 3,
1250 [ZEBRA_ROUTE_HSLS] = 4,
1251};
1252
1253/* Look into the RN and queue it into one or more priority queues,
1254 * increasing the size for each data push done.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001255 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001256static void
1257rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001258{
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001259 struct rib *rib;
1260 char buf[INET6_ADDRSTRLEN];
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001261
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001262 if (IS_ZEBRA_DEBUG_RIB_Q)
1263 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001264
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001265 for (rib = rn->info; rib; rib = rib->next)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001266 {
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001267 u_char qindex = meta_queue_map[rib->type];
1268
1269 /* Invariant: at this point we always have rn->info set. */
1270 if (CHECK_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED(qindex)))
1271 {
1272 if (IS_ZEBRA_DEBUG_RIB_Q)
1273 zlog_debug ("%s: %s/%d: rn %p is already queued in sub-queue %u",
1274 __func__, buf, rn->p.prefixlen, rn, qindex);
1275 continue;
1276 }
1277
1278 SET_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED(qindex));
1279 listnode_add (mq->subq[qindex], rn);
1280 route_lock_node (rn);
1281 mq->size++;
1282
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001283 if (IS_ZEBRA_DEBUG_RIB_Q)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001284 zlog_debug ("%s: %s/%d: queued rn %p into sub-queue %u",
1285 __func__, buf, rn->p.prefixlen, rn, qindex);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001286 }
paul4d38fdb2005-04-28 17:35:14 +00001287}
1288
Paul Jakma6d691122006-07-27 21:49:00 +00001289/* Add route_node to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001290static void
Paul Jakma6d691122006-07-27 21:49:00 +00001291rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
paul4d38fdb2005-04-28 17:35:14 +00001292{
Paul Jakma93bdada2007-08-06 19:25:11 +00001293 char buf[INET_ADDRSTRLEN];
Paul Jakma6d691122006-07-27 21:49:00 +00001294 assert (zebra && rn);
paul4d38fdb2005-04-28 17:35:14 +00001295
Paul Jakma93bdada2007-08-06 19:25:11 +00001296 if (IS_ZEBRA_DEBUG_RIB_Q)
1297 inet_ntop (AF_INET, &rn->p.u.prefix, buf, INET_ADDRSTRLEN);
1298
Paul Jakma6d691122006-07-27 21:49:00 +00001299 /* Pointless to queue a route_node with no RIB entries to add or remove */
1300 if (!rn->info)
1301 {
1302 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1303 __func__, rn, rn->lock);
1304 zlog_backtrace(LOG_DEBUG);
1305 return;
1306 }
paul4d38fdb2005-04-28 17:35:14 +00001307
Paul Jakma6d691122006-07-27 21:49:00 +00001308 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma93bdada2007-08-06 19:25:11 +00001309 zlog_info ("%s: %s/%d: work queue added", __func__, buf, rn->p.prefixlen);
Paul Jakma6d691122006-07-27 21:49:00 +00001310
1311 assert (zebra);
1312
paul4d38fdb2005-04-28 17:35:14 +00001313 if (zebra->ribq == NULL)
1314 {
Paul Jakma6d691122006-07-27 21:49:00 +00001315 zlog_err ("%s: work_queue does not exist!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001316 return;
1317 }
Paul Jakma6d691122006-07-27 21:49:00 +00001318
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001319 /* The RIB queue should normally be either empty or holding the only work_queue_item
1320 * element. In the latter case this element would hold a pointer to the meta queue
1321 * structure, which must be used to actually queue the route nodes to process. So
1322 * create the MQ holder, if necessary, then push the work into it in any case.
1323 * This semantics was introduced after 0.99.9 release.
1324 */
1325
1326 /* Should I invent work_queue_empty() and use it, or it's Ok to do as follows? */
1327 if (!zebra->ribq->items->count)
1328 work_queue_add (zebra->ribq, zebra->mq);
1329
1330 rib_meta_queue_add (zebra->mq, rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001331
1332 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma93bdada2007-08-06 19:25:11 +00001333 zlog_debug ("%s: %s/%d: rn %p queued", __func__, buf, rn->p.prefixlen, rn);
paul4d38fdb2005-04-28 17:35:14 +00001334
1335 return;
1336}
1337
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001338/* Create new meta queue.
1339 A destructor function doesn't seem to be necessary here.
1340 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001341static struct meta_queue *
1342meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001343{
1344 struct meta_queue *new;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001345 unsigned i;
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001346
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001347 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1348 assert(new);
1349
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001350 for (i = 0; i < MQ_SIZE; i++)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001351 {
1352 new->subq[i] = list_new ();
1353 assert(new->subq[i]);
1354 }
1355
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001356 return new;
1357}
1358
paul4d38fdb2005-04-28 17:35:14 +00001359/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001360static void
paul4d38fdb2005-04-28 17:35:14 +00001361rib_queue_init (struct zebra_t *zebra)
1362{
1363 assert (zebra);
1364
1365 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001366 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001367 {
Paul Jakma6d691122006-07-27 21:49:00 +00001368 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001369 return;
1370 }
1371
1372 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001373 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001374 zebra->ribq->spec.errorfunc = NULL;
paul4d38fdb2005-04-28 17:35:14 +00001375 /* XXX: TODO: These should be runtime configurable via vty */
1376 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001377 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001378
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001379 if (!(zebra->mq = meta_queue_new ()))
1380 {
1381 zlog_err ("%s: could not initialise meta queue!", __func__);
1382 return;
1383 }
paul4d38fdb2005-04-28 17:35:14 +00001384 return;
paul718e3742002-12-13 20:15:29 +00001385}
1386
Paul Jakma6d691122006-07-27 21:49:00 +00001387/* RIB updates are processed via a queue of pointers to route_nodes.
1388 *
1389 * The queue length is bounded by the maximal size of the routing table,
1390 * as a route_node will not be requeued, if already queued.
1391 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001392 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1393 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1394 * and then submit route_node to queue for best-path selection later.
1395 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001396 *
1397 * Deleted RIBs are reaped during best-path selection.
1398 *
1399 * rib_addnode
1400 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001401 * |-------->| | best RIB, if required
1402 * | |
1403 * static_install->|->rib_addqueue...... -> rib_process
1404 * | |
1405 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001406 * |-> set RIB_ENTRY_REMOVE |
1407 * rib_delnode (RIB freed)
1408 *
1409 *
1410 * Queueing state for a route_node is kept in the head RIB entry, this
1411 * state must be preserved as and when the head RIB entry of a
1412 * route_node is changed by rib_unlink / rib_link. A small complication,
1413 * but saves having to allocate a dedicated object for this.
1414 *
1415 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1416 *
1417 * - route_nodes: refcounted by:
1418 * - RIBs attached to route_node:
1419 * - managed by: rib_link/unlink
1420 * - route_node processing queue
1421 * - managed by: rib_addqueue, rib_process.
1422 *
1423 */
1424
paul718e3742002-12-13 20:15:29 +00001425/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001426static void
Paul Jakma6d691122006-07-27 21:49:00 +00001427rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001428{
1429 struct rib *head;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001430 char buf[INET6_ADDRSTRLEN];
paul4d38fdb2005-04-28 17:35:14 +00001431
1432 assert (rib && rn);
1433
Paul Jakma6d691122006-07-27 21:49:00 +00001434 route_lock_node (rn); /* rn route table reference */
1435
1436 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001437 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001438 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001439 zlog_debug ("%s: %s/%d: rn %p, rib %p", __func__,
1440 buf, rn->p.prefixlen, rn, rib);
1441 }
Paul Jakma6d691122006-07-27 21:49:00 +00001442
paul718e3742002-12-13 20:15:29 +00001443 head = rn->info;
1444 if (head)
Paul Jakma6d691122006-07-27 21:49:00 +00001445 {
1446 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001447 zlog_debug ("%s: %s/%d: new head, rn_status copied over", __func__,
1448 buf, rn->p.prefixlen);
Paul Jakma6d691122006-07-27 21:49:00 +00001449 head->prev = rib;
1450 /* Transfer the rn status flags to the new head RIB */
1451 rib->rn_status = head->rn_status;
1452 }
paul718e3742002-12-13 20:15:29 +00001453 rib->next = head;
1454 rn->info = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001455 rib_queue_add (&zebrad, rn);
1456}
1457
1458static void
1459rib_addnode (struct route_node *rn, struct rib *rib)
1460{
1461 /* RIB node has been un-removed before route-node is processed.
1462 * route_node must hence already be on the queue for processing..
1463 */
1464 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1465 {
1466 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001467 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001468 char buf[INET6_ADDRSTRLEN];
1469 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001470 zlog_debug ("%s: %s/%d: rn %p, un-removed rib %p",
1471 __func__, buf, rn->p.prefixlen, rn, rib);
1472 }
Paul Jakma6d691122006-07-27 21:49:00 +00001473 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1474 return;
1475 }
1476 rib_link (rn, rib);
1477}
1478
1479static void
1480rib_unlink (struct route_node *rn, struct rib *rib)
1481{
1482 struct nexthop *nexthop, *next;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001483 char buf[INET6_ADDRSTRLEN];
Paul Jakma6d691122006-07-27 21:49:00 +00001484
1485 assert (rn && rib);
1486
1487 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001488 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001489 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001490 zlog_debug ("%s: %s/%d: rn %p, rib %p",
1491 __func__, buf, rn->p.prefixlen, rn, rib);
1492 }
Paul Jakma6d691122006-07-27 21:49:00 +00001493
1494 if (rib->next)
1495 rib->next->prev = rib->prev;
1496
1497 if (rib->prev)
1498 rib->prev->next = rib->next;
1499 else
1500 {
1501 rn->info = rib->next;
1502
1503 if (rn->info)
1504 {
1505 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001506 zlog_debug ("%s: %s/%d: rn %p, rib %p, new head copy",
1507 __func__, buf, rn->p.prefixlen, rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001508 rib->next->rn_status = rib->rn_status;
1509 }
1510 }
1511
1512 /* free RIB and nexthops */
1513 for (nexthop = rib->nexthop; nexthop; nexthop = next)
1514 {
1515 next = nexthop->next;
1516 nexthop_free (nexthop);
1517 }
1518 XFREE (MTYPE_RIB, rib);
1519
1520 route_unlock_node (rn); /* rn route table reference */
paul718e3742002-12-13 20:15:29 +00001521}
1522
paula1ac18c2005-06-28 17:17:12 +00001523static void
paul718e3742002-12-13 20:15:29 +00001524rib_delnode (struct route_node *rn, struct rib *rib)
1525{
Paul Jakma6d691122006-07-27 21:49:00 +00001526 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001527 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001528 char buf[INET6_ADDRSTRLEN];
1529 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001530 zlog_debug ("%s: %s/%d: rn %p, rib %p, removing", __func__,
1531 buf, rn->p.prefixlen, rn, rib);
1532 }
Paul Jakma6d691122006-07-27 21:49:00 +00001533 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1534 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001535}
1536
1537int
1538rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001539 struct in_addr *gate, struct in_addr *src,
1540 unsigned int ifindex, u_int32_t vrf_id,
paul718e3742002-12-13 20:15:29 +00001541 u_int32_t metric, u_char distance)
1542{
1543 struct rib *rib;
1544 struct rib *same = NULL;
1545 struct route_table *table;
1546 struct route_node *rn;
1547 struct nexthop *nexthop;
1548
1549 /* Lookup table. */
1550 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1551 if (! table)
1552 return 0;
1553
1554 /* Make it sure prefixlen is applied to the prefix. */
1555 apply_mask_ipv4 (p);
1556
1557 /* Set default distance by route type. */
1558 if (distance == 0)
1559 {
1560 distance = route_info[type].distance;
1561
1562 /* iBGP distance is 200. */
1563 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1564 distance = 200;
1565 }
1566
1567 /* Lookup route node.*/
1568 rn = route_node_get (table, (struct prefix *) p);
1569
1570 /* If same type of route are installed, treat it as a implicit
1571 withdraw. */
1572 for (rib = rn->info; rib; rib = rib->next)
1573 {
Paul Jakma6d691122006-07-27 21:49:00 +00001574 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1575 continue;
1576
hassoebf1ead2005-09-21 14:58:20 +00001577 if (rib->type != type)
1578 continue;
1579 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001580 {
1581 same = rib;
1582 break;
1583 }
hassoebf1ead2005-09-21 14:58:20 +00001584 /* Duplicate connected route comes in. */
1585 else if ((nexthop = rib->nexthop) &&
1586 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001587 nexthop->ifindex == ifindex &&
1588 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001589 {
1590 rib->refcnt++;
1591 return 0 ;
1592 }
paul718e3742002-12-13 20:15:29 +00001593 }
1594
1595 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001596 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001597 rib->type = type;
1598 rib->distance = distance;
1599 rib->flags = flags;
1600 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001601 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001602 rib->nexthop_num = 0;
1603 rib->uptime = time (NULL);
1604
1605 /* Nexthop settings. */
1606 if (gate)
1607 {
1608 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001609 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001610 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001611 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001612 }
1613 else
1614 nexthop_ifindex_add (rib, ifindex);
1615
1616 /* If this route is kernel route, set FIB flag to the route. */
1617 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1618 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1619 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1620
1621 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001622 if (IS_ZEBRA_DEBUG_RIB)
1623 zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
paul718e3742002-12-13 20:15:29 +00001624 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001625
paul718e3742002-12-13 20:15:29 +00001626 /* Free implicit route.*/
1627 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001628 {
1629 if (IS_ZEBRA_DEBUG_RIB)
1630 zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001631 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001632 }
paul4d38fdb2005-04-28 17:35:14 +00001633
1634 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001635 return 0;
1636}
1637
Denis Ovsienkodc958242007-08-13 16:03:06 +00001638/* This function dumps the contents of a given RIB entry into
1639 * standard debug log. Calling function name and IP prefix in
1640 * question are passed as 1st and 2nd arguments.
1641 */
1642
1643void rib_dump (const char * func, const struct prefix_ipv4 * p, const struct rib * rib)
1644{
1645 char straddr1[INET_ADDRSTRLEN], straddr2[INET_ADDRSTRLEN];
1646 struct nexthop *nexthop;
1647
1648 inet_ntop (AF_INET, &p->prefix, straddr1, INET_ADDRSTRLEN);
1649 zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr1, p->prefixlen);
1650 zlog_debug
1651 (
1652 "%s: refcnt == %lu, uptime == %u, type == %u, table == %d",
1653 func,
1654 rib->refcnt,
1655 rib->uptime,
1656 rib->type,
1657 rib->table
1658 );
1659 zlog_debug
1660 (
1661 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1662 func,
1663 rib->metric,
1664 rib->distance,
1665 rib->flags,
1666 rib->status
1667 );
1668 zlog_debug
1669 (
1670 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1671 func,
1672 rib->nexthop_num,
1673 rib->nexthop_active_num,
1674 rib->nexthop_fib_num
1675 );
1676 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1677 {
1678 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, straddr1, INET_ADDRSTRLEN);
1679 inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, straddr2, INET_ADDRSTRLEN);
1680 zlog_debug
1681 (
1682 "%s: NH %s (%s) with flags %s%s%s",
1683 func,
1684 straddr1,
1685 straddr2,
1686 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1687 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1688 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1689 );
1690 }
1691 zlog_debug ("%s: dump complete", func);
1692}
1693
1694/* This is an exported helper to rtm_read() to dump the strange
1695 * RIB entry found by rib_lookup_ipv4_route()
1696 */
1697
1698void rib_lookup_and_dump (struct prefix_ipv4 * p)
1699{
1700 struct route_table *table;
1701 struct route_node *rn;
1702 struct rib *rib;
1703 char prefix_buf[INET_ADDRSTRLEN];
1704
1705 /* Lookup table. */
1706 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1707 if (! table)
1708 {
1709 zlog_err ("%s: vrf_table() returned NULL", __func__);
1710 return;
1711 }
1712
1713 inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
1714 /* Scan the RIB table for exactly matching RIB entry. */
1715 rn = route_node_lookup (table, (struct prefix *) p);
1716
1717 /* No route for this prefix. */
1718 if (! rn)
1719 {
1720 zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
1721 return;
1722 }
1723
1724 /* Unlock node. */
1725 route_unlock_node (rn);
1726
1727 /* let's go */
1728 for (rib = rn->info; rib; rib = rib->next)
1729 {
1730 zlog_debug
1731 (
1732 "%s: rn %p, rib %p: %s, %s",
1733 __func__,
1734 rn,
1735 rib,
1736 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
1737 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
1738 );
1739 rib_dump (__func__, p, rib);
1740 }
1741}
1742
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001743/* Check if requested address assignment will fail due to another
1744 * route being installed by zebra in FIB already. Take necessary
1745 * actions, if needed: remove such a route from FIB and deSELECT
1746 * corresponding RIB entry. Then put affected RN into RIBQ head.
1747 */
1748void rib_lookup_and_pushup (struct prefix_ipv4 * p)
1749{
1750 struct route_table *table;
1751 struct route_node *rn;
1752 struct rib *rib;
1753 unsigned changed = 0;
1754
1755 if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
1756 {
1757 zlog_err ("%s: vrf_table() returned NULL", __func__);
1758 return;
1759 }
1760
1761 /* No matches would be the simplest case. */
1762 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
1763 return;
1764
1765 /* Unlock node. */
1766 route_unlock_node (rn);
1767
1768 /* Check all RIB entries. In case any changes have to be done, requeue
1769 * the RN into RIBQ head. If the routing message about the new connected
1770 * route (generated by the IP address we are going to assign very soon)
1771 * comes before the RIBQ is processed, the new RIB entry will join
1772 * RIBQ record already on head. This is necessary for proper revalidation
1773 * of the rest of the RIB.
1774 */
1775 for (rib = rn->info; rib; rib = rib->next)
1776 {
1777 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
1778 ! RIB_SYSTEM_ROUTE (rib))
1779 {
1780 changed = 1;
1781 if (IS_ZEBRA_DEBUG_RIB)
1782 {
1783 char buf[INET_ADDRSTRLEN];
1784 inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
1785 zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
1786 rib_dump (__func__, (struct prefix_ipv4 *)&rn->p, rib);
1787 }
1788 rib_uninstall (rn, rib);
1789 }
1790 }
1791 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001792 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001793}
1794
paul718e3742002-12-13 20:15:29 +00001795int
1796rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib)
1797{
1798 struct route_table *table;
1799 struct route_node *rn;
1800 struct rib *same;
1801 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00001802
paul718e3742002-12-13 20:15:29 +00001803 /* Lookup table. */
1804 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1805 if (! table)
1806 return 0;
paul718e3742002-12-13 20:15:29 +00001807 /* Make it sure prefixlen is applied to the prefix. */
1808 apply_mask_ipv4 (p);
1809
1810 /* Set default distance by route type. */
1811 if (rib->distance == 0)
1812 {
1813 rib->distance = route_info[rib->type].distance;
1814
1815 /* iBGP distance is 200. */
1816 if (rib->type == ZEBRA_ROUTE_BGP
1817 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1818 rib->distance = 200;
1819 }
1820
1821 /* Lookup route node.*/
1822 rn = route_node_get (table, (struct prefix *) p);
1823
1824 /* If same type of route are installed, treat it as a implicit
1825 withdraw. */
1826 for (same = rn->info; same; same = same->next)
1827 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00001828 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00001829 continue;
1830
paul718e3742002-12-13 20:15:29 +00001831 if (same->type == rib->type && same->table == rib->table
1832 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001833 break;
paul718e3742002-12-13 20:15:29 +00001834 }
paul4d38fdb2005-04-28 17:35:14 +00001835
paul718e3742002-12-13 20:15:29 +00001836 /* If this route is kernel route, set FIB flag to the route. */
1837 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
1838 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1839 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1840
1841 /* Link new rib to node.*/
1842 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001843 if (IS_ZEBRA_DEBUG_RIB)
1844 {
1845 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
1846 __func__, rn, rib);
1847 rib_dump (__func__, p, rib);
1848 }
paul718e3742002-12-13 20:15:29 +00001849
paul718e3742002-12-13 20:15:29 +00001850 /* Free implicit route.*/
1851 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001852 {
1853 if (IS_ZEBRA_DEBUG_RIB)
1854 {
1855 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
1856 __func__, rn, same);
1857 rib_dump (__func__, p, same);
1858 }
paul4d38fdb2005-04-28 17:35:14 +00001859 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001860 }
paul4d38fdb2005-04-28 17:35:14 +00001861
1862 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001863 return 0;
1864}
1865
hassoebf1ead2005-09-21 14:58:20 +00001866/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00001867int
1868rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
1869 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1870{
1871 struct route_table *table;
1872 struct route_node *rn;
1873 struct rib *rib;
1874 struct rib *fib = NULL;
1875 struct rib *same = NULL;
1876 struct nexthop *nexthop;
Stephen Hemminger81cce012009-04-28 14:28:00 -07001877 char buf1[INET_ADDRSTRLEN];
1878 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00001879
1880 /* Lookup table. */
1881 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1882 if (! table)
1883 return 0;
1884
1885 /* Apply mask. */
1886 apply_mask_ipv4 (p);
1887
paul5ec90d22003-06-19 01:41:37 +00001888 if (IS_ZEBRA_DEBUG_KERNEL && gate)
ajsb6178002004-12-07 21:12:56 +00001889 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001890 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul5ec90d22003-06-19 01:41:37 +00001891 p->prefixlen,
1892 inet_ntoa (*gate),
1893 ifindex);
1894
paul718e3742002-12-13 20:15:29 +00001895 /* Lookup route node. */
1896 rn = route_node_lookup (table, (struct prefix *) p);
1897 if (! rn)
1898 {
1899 if (IS_ZEBRA_DEBUG_KERNEL)
1900 {
1901 if (gate)
ajsb6178002004-12-07 21:12:56 +00001902 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001903 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001904 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07001905 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001906 ifindex);
1907 else
ajsb6178002004-12-07 21:12:56 +00001908 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001909 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001910 p->prefixlen,
1911 ifindex);
1912 }
1913 return ZEBRA_ERR_RTNOEXIST;
1914 }
1915
1916 /* Lookup same type route. */
1917 for (rib = rn->info; rib; rib = rib->next)
1918 {
Paul Jakma6d691122006-07-27 21:49:00 +00001919 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1920 continue;
1921
paul718e3742002-12-13 20:15:29 +00001922 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1923 fib = rib;
1924
hassoebf1ead2005-09-21 14:58:20 +00001925 if (rib->type != type)
1926 continue;
1927 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
1928 nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex)
paul718e3742002-12-13 20:15:29 +00001929 {
hassoebf1ead2005-09-21 14:58:20 +00001930 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00001931 {
hassoebf1ead2005-09-21 14:58:20 +00001932 rib->refcnt--;
1933 route_unlock_node (rn);
1934 route_unlock_node (rn);
1935 return 0;
paul718e3742002-12-13 20:15:29 +00001936 }
hassoebf1ead2005-09-21 14:58:20 +00001937 same = rib;
1938 break;
paul718e3742002-12-13 20:15:29 +00001939 }
hassoebf1ead2005-09-21 14:58:20 +00001940 /* Make sure that the route found has the same gateway. */
1941 else if (gate == NULL ||
1942 ((nexthop = rib->nexthop) &&
1943 (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
1944 IPV4_ADDR_SAME (&nexthop->rgate.ipv4, gate))))
paul5ec90d22003-06-19 01:41:37 +00001945 {
hassoebf1ead2005-09-21 14:58:20 +00001946 same = rib;
1947 break;
paul718e3742002-12-13 20:15:29 +00001948 }
1949 }
1950
1951 /* If same type of route can't be found and this message is from
1952 kernel. */
1953 if (! same)
1954 {
1955 if (fib && type == ZEBRA_ROUTE_KERNEL)
1956 {
1957 /* Unset flags. */
1958 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1959 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1960
1961 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1962 }
1963 else
1964 {
1965 if (IS_ZEBRA_DEBUG_KERNEL)
1966 {
1967 if (gate)
ajsb6178002004-12-07 21:12:56 +00001968 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001969 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001970 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07001971 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001972 ifindex,
1973 type);
1974 else
ajsb6178002004-12-07 21:12:56 +00001975 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001976 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001977 p->prefixlen,
1978 ifindex,
1979 type);
1980 }
1981 route_unlock_node (rn);
1982 return ZEBRA_ERR_RTNOEXIST;
1983 }
1984 }
paul4d38fdb2005-04-28 17:35:14 +00001985
paul718e3742002-12-13 20:15:29 +00001986 if (same)
1987 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00001988
paul718e3742002-12-13 20:15:29 +00001989 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001990 return 0;
1991}
1992
1993/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00001994static void
paul718e3742002-12-13 20:15:29 +00001995static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
1996{
1997 struct rib *rib;
1998 struct route_node *rn;
1999 struct route_table *table;
2000
2001 /* Lookup table. */
2002 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2003 if (! table)
2004 return;
2005
2006 /* Lookup existing route */
2007 rn = route_node_get (table, p);
2008 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002009 {
2010 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2011 continue;
2012
2013 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2014 break;
2015 }
paul718e3742002-12-13 20:15:29 +00002016
2017 if (rib)
2018 {
2019 /* Same distance static route is there. Update it with new
2020 nexthop. */
paul718e3742002-12-13 20:15:29 +00002021 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002022 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002023 {
2024 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002025 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002026 break;
2027 case STATIC_IPV4_IFNAME:
2028 nexthop_ifname_add (rib, si->gate.ifname);
2029 break;
2030 case STATIC_IPV4_BLACKHOLE:
2031 nexthop_blackhole_add (rib);
2032 break;
paul4d38fdb2005-04-28 17:35:14 +00002033 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002034 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002035 }
2036 else
2037 {
2038 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002039 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2040
paul718e3742002-12-13 20:15:29 +00002041 rib->type = ZEBRA_ROUTE_STATIC;
2042 rib->distance = si->distance;
2043 rib->metric = 0;
2044 rib->nexthop_num = 0;
2045
2046 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002047 {
2048 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002049 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002050 break;
2051 case STATIC_IPV4_IFNAME:
2052 nexthop_ifname_add (rib, si->gate.ifname);
2053 break;
2054 case STATIC_IPV4_BLACKHOLE:
2055 nexthop_blackhole_add (rib);
2056 break;
2057 }
paul718e3742002-12-13 20:15:29 +00002058
hasso81dfcaa2003-05-25 19:21:25 +00002059 /* Save the flags of this static routes (reject, blackhole) */
2060 rib->flags = si->flags;
2061
paul718e3742002-12-13 20:15:29 +00002062 /* Link this rib to the tree. */
2063 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002064 }
2065}
2066
paula1ac18c2005-06-28 17:17:12 +00002067static int
paul718e3742002-12-13 20:15:29 +00002068static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2069{
2070 if (nexthop->type == NEXTHOP_TYPE_IPV4
2071 && si->type == STATIC_IPV4_GATEWAY
2072 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2073 return 1;
2074 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2075 && si->type == STATIC_IPV4_IFNAME
2076 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2077 return 1;
paul595db7f2003-05-25 21:35:06 +00002078 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2079 && si->type == STATIC_IPV4_BLACKHOLE)
2080 return 1;
paule8e19462006-01-19 20:16:55 +00002081 return 0;
paul718e3742002-12-13 20:15:29 +00002082}
2083
2084/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002085static void
paul718e3742002-12-13 20:15:29 +00002086static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
2087{
2088 struct route_node *rn;
2089 struct rib *rib;
2090 struct nexthop *nexthop;
2091 struct route_table *table;
2092
2093 /* Lookup table. */
2094 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2095 if (! table)
2096 return;
paul4d38fdb2005-04-28 17:35:14 +00002097
paul718e3742002-12-13 20:15:29 +00002098 /* Lookup existing route with type and distance. */
2099 rn = route_node_lookup (table, p);
2100 if (! rn)
2101 return;
2102
2103 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002104 {
2105 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2106 continue;
2107
2108 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2109 break;
2110 }
paul718e3742002-12-13 20:15:29 +00002111
2112 if (! rib)
2113 {
2114 route_unlock_node (rn);
2115 return;
2116 }
2117
2118 /* Lookup nexthop. */
2119 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2120 if (static_ipv4_nexthop_same (nexthop, si))
2121 break;
2122
2123 /* Can't find nexthop. */
2124 if (! nexthop)
2125 {
2126 route_unlock_node (rn);
2127 return;
2128 }
2129
2130 /* Check nexthop. */
2131 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002132 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002133 else
2134 {
paul6baeb982003-10-28 03:47:15 +00002135 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2136 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002137 nexthop_delete (rib, nexthop);
2138 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002139 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002140 }
paul718e3742002-12-13 20:15:29 +00002141 /* Unlock node. */
2142 route_unlock_node (rn);
2143}
2144
2145/* Add static route into static route configuration. */
2146int
hasso39db97e2004-10-12 20:50:58 +00002147static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00002148 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002149{
2150 u_char type = 0;
2151 struct route_node *rn;
2152 struct static_ipv4 *si;
2153 struct static_ipv4 *pp;
2154 struct static_ipv4 *cp;
2155 struct static_ipv4 *update = NULL;
2156 struct route_table *stable;
2157
2158 /* Lookup table. */
2159 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2160 if (! stable)
2161 return -1;
2162
2163 /* Lookup static route prefix. */
2164 rn = route_node_get (stable, p);
2165
2166 /* Make flags. */
2167 if (gate)
2168 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002169 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002170 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002171 else
2172 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002173
2174 /* Do nothing if there is a same static route. */
2175 for (si = rn->info; si; si = si->next)
2176 {
2177 if (type == si->type
2178 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2179 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2180 {
2181 if (distance == si->distance)
2182 {
2183 route_unlock_node (rn);
2184 return 0;
2185 }
2186 else
2187 update = si;
2188 }
2189 }
2190
Paul Jakma3c0755d2006-12-08 00:53:14 +00002191 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002192 if (update)
2193 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
2194
2195 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002196 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
paul718e3742002-12-13 20:15:29 +00002197
2198 si->type = type;
2199 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002200 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002201
2202 if (gate)
2203 si->gate.ipv4 = *gate;
2204 if (ifname)
2205 si->gate.ifname = XSTRDUP (0, ifname);
2206
2207 /* Add new static route information to the tree with sort by
2208 distance value and gateway address. */
2209 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2210 {
2211 if (si->distance < cp->distance)
2212 break;
2213 if (si->distance > cp->distance)
2214 continue;
2215 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2216 {
2217 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2218 break;
2219 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2220 continue;
2221 }
2222 }
2223
2224 /* Make linked list. */
2225 if (pp)
2226 pp->next = si;
2227 else
2228 rn->info = si;
2229 if (cp)
2230 cp->prev = si;
2231 si->prev = pp;
2232 si->next = cp;
2233
2234 /* Install into rib. */
2235 static_install_ipv4 (p, si);
2236
2237 return 1;
2238}
2239
2240/* Delete static route from static route configuration. */
2241int
hasso39db97e2004-10-12 20:50:58 +00002242static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00002243 u_char distance, u_int32_t vrf_id)
2244{
2245 u_char type = 0;
2246 struct route_node *rn;
2247 struct static_ipv4 *si;
2248 struct route_table *stable;
2249
2250 /* Lookup table. */
2251 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2252 if (! stable)
2253 return -1;
2254
2255 /* Lookup static route prefix. */
2256 rn = route_node_lookup (stable, p);
2257 if (! rn)
2258 return 0;
2259
2260 /* Make flags. */
2261 if (gate)
2262 type = STATIC_IPV4_GATEWAY;
2263 else if (ifname)
2264 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002265 else
2266 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002267
2268 /* Find same static route is the tree */
2269 for (si = rn->info; si; si = si->next)
2270 if (type == si->type
2271 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2272 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2273 break;
2274
2275 /* Can't find static route. */
2276 if (! si)
2277 {
2278 route_unlock_node (rn);
2279 return 0;
2280 }
2281
2282 /* Install into rib. */
2283 static_uninstall_ipv4 (p, si);
2284
2285 /* Unlink static route from linked list. */
2286 if (si->prev)
2287 si->prev->next = si->next;
2288 else
2289 rn->info = si->next;
2290 if (si->next)
2291 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002292 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002293
2294 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002295 if (ifname)
2296 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002297 XFREE (MTYPE_STATIC_IPV4, si);
2298
paul143a3852003-09-29 20:06:13 +00002299 route_unlock_node (rn);
2300
paul718e3742002-12-13 20:15:29 +00002301 return 1;
2302}
2303
2304
2305#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00002306static int
paul718e3742002-12-13 20:15:29 +00002307rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2308 struct in6_addr *gate, unsigned int ifindex, int table)
2309{
hasso726f9b22003-05-25 21:04:54 +00002310 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2311#if defined (MUSICA) || defined (LINUX)
2312 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2313 if (p->prefixlen == 96)
2314 return 0;
2315#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00002316 return 1;
hasso726f9b22003-05-25 21:04:54 +00002317 }
paul718e3742002-12-13 20:15:29 +00002318 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
2319 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
2320 {
2321 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
2322 return 1;
2323 }
2324 return 0;
2325}
2326
2327int
2328rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00002329 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
2330 u_int32_t metric, u_char distance)
paul718e3742002-12-13 20:15:29 +00002331{
2332 struct rib *rib;
2333 struct rib *same = NULL;
2334 struct route_table *table;
2335 struct route_node *rn;
2336 struct nexthop *nexthop;
2337
paul718e3742002-12-13 20:15:29 +00002338 /* Lookup table. */
2339 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2340 if (! table)
2341 return 0;
2342
2343 /* Make sure mask is applied. */
2344 apply_mask_ipv6 (p);
2345
2346 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002347 if (!distance)
2348 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002349
2350 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2351 distance = 200;
2352
2353 /* Filter bogus route. */
2354 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
2355 return 0;
2356
2357 /* Lookup route node.*/
2358 rn = route_node_get (table, (struct prefix *) p);
2359
2360 /* If same type of route are installed, treat it as a implicit
2361 withdraw. */
2362 for (rib = rn->info; rib; rib = rib->next)
2363 {
Paul Jakma6d691122006-07-27 21:49:00 +00002364 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2365 continue;
2366
hassoebf1ead2005-09-21 14:58:20 +00002367 if (rib->type != type)
2368 continue;
2369 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002370 {
2371 same = rib;
paul718e3742002-12-13 20:15:29 +00002372 break;
2373 }
hassoebf1ead2005-09-21 14:58:20 +00002374 else if ((nexthop = rib->nexthop) &&
2375 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2376 nexthop->ifindex == ifindex)
2377 {
2378 rib->refcnt++;
2379 return 0;
2380 }
paul718e3742002-12-13 20:15:29 +00002381 }
2382
2383 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002384 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2385
paul718e3742002-12-13 20:15:29 +00002386 rib->type = type;
2387 rib->distance = distance;
2388 rib->flags = flags;
2389 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00002390 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00002391 rib->nexthop_num = 0;
2392 rib->uptime = time (NULL);
2393
2394 /* Nexthop settings. */
2395 if (gate)
2396 {
2397 if (ifindex)
2398 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2399 else
2400 nexthop_ipv6_add (rib, gate);
2401 }
2402 else
2403 nexthop_ifindex_add (rib, ifindex);
2404
2405 /* If this route is kernel route, set FIB flag to the route. */
2406 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2407 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2408 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2409
2410 /* Link new rib to node.*/
2411 rib_addnode (rn, rib);
2412
paul718e3742002-12-13 20:15:29 +00002413 /* Free implicit route.*/
2414 if (same)
paul4d38fdb2005-04-28 17:35:14 +00002415 rib_delnode (rn, same);
2416
2417 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002418 return 0;
2419}
2420
hassoebf1ead2005-09-21 14:58:20 +00002421/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002422int
2423rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
2424 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
2425{
2426 struct route_table *table;
2427 struct route_node *rn;
2428 struct rib *rib;
2429 struct rib *fib = NULL;
2430 struct rib *same = NULL;
2431 struct nexthop *nexthop;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002432 char buf1[INET6_ADDRSTRLEN];
2433 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002434
2435 /* Apply mask. */
2436 apply_mask_ipv6 (p);
2437
2438 /* Lookup table. */
2439 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2440 if (! table)
2441 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002442
paul718e3742002-12-13 20:15:29 +00002443 /* Lookup route node. */
2444 rn = route_node_lookup (table, (struct prefix *) p);
2445 if (! rn)
2446 {
2447 if (IS_ZEBRA_DEBUG_KERNEL)
2448 {
2449 if (gate)
ajsb6178002004-12-07 21:12:56 +00002450 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002451 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002452 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002453 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002454 ifindex);
2455 else
ajsb6178002004-12-07 21:12:56 +00002456 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002457 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002458 p->prefixlen,
2459 ifindex);
2460 }
2461 return ZEBRA_ERR_RTNOEXIST;
2462 }
2463
2464 /* Lookup same type route. */
2465 for (rib = rn->info; rib; rib = rib->next)
2466 {
Paul Jakma6d691122006-07-27 21:49:00 +00002467 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2468 continue;
2469
paul718e3742002-12-13 20:15:29 +00002470 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2471 fib = rib;
2472
hassoebf1ead2005-09-21 14:58:20 +00002473 if (rib->type != type)
2474 continue;
2475 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
2476 nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex)
paul718e3742002-12-13 20:15:29 +00002477 {
hassoebf1ead2005-09-21 14:58:20 +00002478 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002479 {
hassoebf1ead2005-09-21 14:58:20 +00002480 rib->refcnt--;
2481 route_unlock_node (rn);
2482 route_unlock_node (rn);
2483 return 0;
paul718e3742002-12-13 20:15:29 +00002484 }
hassoebf1ead2005-09-21 14:58:20 +00002485 same = rib;
2486 break;
paul718e3742002-12-13 20:15:29 +00002487 }
hassoebf1ead2005-09-21 14:58:20 +00002488 /* Make sure that the route found has the same gateway. */
2489 else if (gate == NULL ||
2490 ((nexthop = rib->nexthop) &&
2491 (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate) ||
2492 IPV6_ADDR_SAME (&nexthop->rgate.ipv6, gate))))
paul718e3742002-12-13 20:15:29 +00002493 {
hassoebf1ead2005-09-21 14:58:20 +00002494 same = rib;
2495 break;
paul718e3742002-12-13 20:15:29 +00002496 }
2497 }
2498
2499 /* If same type of route can't be found and this message is from
2500 kernel. */
2501 if (! same)
2502 {
2503 if (fib && type == ZEBRA_ROUTE_KERNEL)
2504 {
2505 /* Unset flags. */
2506 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2507 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2508
2509 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2510 }
2511 else
2512 {
2513 if (IS_ZEBRA_DEBUG_KERNEL)
2514 {
2515 if (gate)
ajsb6178002004-12-07 21:12:56 +00002516 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002517 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002518 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002519 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002520 ifindex,
2521 type);
2522 else
ajsb6178002004-12-07 21:12:56 +00002523 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002524 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002525 p->prefixlen,
2526 ifindex,
2527 type);
2528 }
2529 route_unlock_node (rn);
2530 return ZEBRA_ERR_RTNOEXIST;
2531 }
2532 }
2533
2534 if (same)
2535 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002536
paul718e3742002-12-13 20:15:29 +00002537 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002538 return 0;
2539}
2540
2541/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002542static void
paul718e3742002-12-13 20:15:29 +00002543static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2544{
2545 struct rib *rib;
2546 struct route_table *table;
2547 struct route_node *rn;
2548
2549 /* Lookup table. */
2550 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2551 if (! table)
2552 return;
2553
2554 /* Lookup existing route */
2555 rn = route_node_get (table, p);
2556 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002557 {
2558 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2559 continue;
2560
2561 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2562 break;
2563 }
paul718e3742002-12-13 20:15:29 +00002564
2565 if (rib)
2566 {
2567 /* Same distance static route is there. Update it with new
2568 nexthop. */
paul718e3742002-12-13 20:15:29 +00002569 route_unlock_node (rn);
2570
2571 switch (si->type)
2572 {
2573 case STATIC_IPV6_GATEWAY:
2574 nexthop_ipv6_add (rib, &si->ipv6);
2575 break;
2576 case STATIC_IPV6_IFNAME:
2577 nexthop_ifname_add (rib, si->ifname);
2578 break;
2579 case STATIC_IPV6_GATEWAY_IFNAME:
2580 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2581 break;
2582 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002583 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002584 }
2585 else
2586 {
2587 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002588 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2589
paul718e3742002-12-13 20:15:29 +00002590 rib->type = ZEBRA_ROUTE_STATIC;
2591 rib->distance = si->distance;
2592 rib->metric = 0;
2593 rib->nexthop_num = 0;
2594
2595 switch (si->type)
2596 {
2597 case STATIC_IPV6_GATEWAY:
2598 nexthop_ipv6_add (rib, &si->ipv6);
2599 break;
2600 case STATIC_IPV6_IFNAME:
2601 nexthop_ifname_add (rib, si->ifname);
2602 break;
2603 case STATIC_IPV6_GATEWAY_IFNAME:
2604 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2605 break;
2606 }
2607
hasso81dfcaa2003-05-25 19:21:25 +00002608 /* Save the flags of this static routes (reject, blackhole) */
2609 rib->flags = si->flags;
2610
paul718e3742002-12-13 20:15:29 +00002611 /* Link this rib to the tree. */
2612 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002613 }
2614}
2615
paula1ac18c2005-06-28 17:17:12 +00002616static int
paul718e3742002-12-13 20:15:29 +00002617static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2618{
2619 if (nexthop->type == NEXTHOP_TYPE_IPV6
2620 && si->type == STATIC_IPV6_GATEWAY
2621 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2622 return 1;
2623 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2624 && si->type == STATIC_IPV6_IFNAME
2625 && strcmp (nexthop->ifname, si->ifname) == 0)
2626 return 1;
2627 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2628 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2629 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2630 && strcmp (nexthop->ifname, si->ifname) == 0)
2631 return 1;
paule8e19462006-01-19 20:16:55 +00002632 return 0;
paul718e3742002-12-13 20:15:29 +00002633}
2634
paula1ac18c2005-06-28 17:17:12 +00002635static void
paul718e3742002-12-13 20:15:29 +00002636static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2637{
2638 struct route_table *table;
2639 struct route_node *rn;
2640 struct rib *rib;
2641 struct nexthop *nexthop;
2642
2643 /* Lookup table. */
2644 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2645 if (! table)
2646 return;
2647
2648 /* Lookup existing route with type and distance. */
2649 rn = route_node_lookup (table, (struct prefix *) p);
2650 if (! rn)
2651 return;
2652
2653 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002654 {
2655 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2656 continue;
2657
2658 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2659 break;
2660 }
2661
paul718e3742002-12-13 20:15:29 +00002662 if (! rib)
2663 {
2664 route_unlock_node (rn);
2665 return;
2666 }
2667
2668 /* Lookup nexthop. */
2669 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2670 if (static_ipv6_nexthop_same (nexthop, si))
2671 break;
2672
2673 /* Can't find nexthop. */
2674 if (! nexthop)
2675 {
2676 route_unlock_node (rn);
2677 return;
2678 }
2679
2680 /* Check nexthop. */
2681 if (rib->nexthop_num == 1)
2682 {
2683 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002684 }
2685 else
2686 {
paul6baeb982003-10-28 03:47:15 +00002687 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2688 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002689 nexthop_delete (rib, nexthop);
2690 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002691 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002692 }
paul718e3742002-12-13 20:15:29 +00002693 /* Unlock node. */
2694 route_unlock_node (rn);
2695}
2696
2697/* Add static route into static route configuration. */
2698int
2699static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002700 const char *ifname, u_char flags, u_char distance,
2701 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002702{
2703 struct route_node *rn;
2704 struct static_ipv6 *si;
2705 struct static_ipv6 *pp;
2706 struct static_ipv6 *cp;
2707 struct route_table *stable;
2708
2709 /* Lookup table. */
2710 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2711 if (! stable)
2712 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00002713
2714 if (!gate &&
2715 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
2716 return -1;
2717
2718 if (!ifname &&
2719 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
2720 return -1;
paul718e3742002-12-13 20:15:29 +00002721
2722 /* Lookup static route prefix. */
2723 rn = route_node_get (stable, p);
2724
2725 /* Do nothing if there is a same static route. */
2726 for (si = rn->info; si; si = si->next)
2727 {
2728 if (distance == si->distance
2729 && type == si->type
2730 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2731 && (! ifname || strcmp (ifname, si->ifname) == 0))
2732 {
2733 route_unlock_node (rn);
2734 return 0;
2735 }
2736 }
2737
2738 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002739 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
paul718e3742002-12-13 20:15:29 +00002740
2741 si->type = type;
2742 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002743 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002744
2745 switch (type)
2746 {
2747 case STATIC_IPV6_GATEWAY:
2748 si->ipv6 = *gate;
2749 break;
2750 case STATIC_IPV6_IFNAME:
2751 si->ifname = XSTRDUP (0, ifname);
2752 break;
2753 case STATIC_IPV6_GATEWAY_IFNAME:
2754 si->ipv6 = *gate;
2755 si->ifname = XSTRDUP (0, ifname);
2756 break;
2757 }
2758
2759 /* Add new static route information to the tree with sort by
2760 distance value and gateway address. */
2761 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2762 {
2763 if (si->distance < cp->distance)
2764 break;
2765 if (si->distance > cp->distance)
2766 continue;
2767 }
2768
2769 /* Make linked list. */
2770 if (pp)
2771 pp->next = si;
2772 else
2773 rn->info = si;
2774 if (cp)
2775 cp->prev = si;
2776 si->prev = pp;
2777 si->next = cp;
2778
2779 /* Install into rib. */
2780 static_install_ipv6 (p, si);
2781
2782 return 1;
2783}
2784
2785/* Delete static route from static route configuration. */
2786int
2787static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002788 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002789{
2790 struct route_node *rn;
2791 struct static_ipv6 *si;
2792 struct route_table *stable;
2793
2794 /* Lookup table. */
2795 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2796 if (! stable)
2797 return -1;
2798
2799 /* Lookup static route prefix. */
2800 rn = route_node_lookup (stable, p);
2801 if (! rn)
2802 return 0;
2803
2804 /* Find same static route is the tree */
2805 for (si = rn->info; si; si = si->next)
2806 if (distance == si->distance
2807 && type == si->type
2808 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2809 && (! ifname || strcmp (ifname, si->ifname) == 0))
2810 break;
2811
2812 /* Can't find static route. */
2813 if (! si)
2814 {
2815 route_unlock_node (rn);
2816 return 0;
2817 }
2818
2819 /* Install into rib. */
2820 static_uninstall_ipv6 (p, si);
2821
2822 /* Unlink static route from linked list. */
2823 if (si->prev)
2824 si->prev->next = si->next;
2825 else
2826 rn->info = si->next;
2827 if (si->next)
2828 si->next->prev = si->prev;
2829
2830 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002831 if (ifname)
2832 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00002833 XFREE (MTYPE_STATIC_IPV6, si);
2834
2835 return 1;
2836}
2837#endif /* HAVE_IPV6 */
2838
2839/* RIB update function. */
2840void
paula1ac18c2005-06-28 17:17:12 +00002841rib_update (void)
paul718e3742002-12-13 20:15:29 +00002842{
2843 struct route_node *rn;
2844 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00002845
paul718e3742002-12-13 20:15:29 +00002846 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2847 if (table)
2848 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002849 if (rn->info)
Paul Jakma6d691122006-07-27 21:49:00 +00002850 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002851
2852 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2853 if (table)
2854 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002855 if (rn->info)
Paul Jakma6d691122006-07-27 21:49:00 +00002856 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002857}
2858
2859/* Interface goes up. */
paula1ac18c2005-06-28 17:17:12 +00002860static void
paul718e3742002-12-13 20:15:29 +00002861rib_if_up (struct interface *ifp)
2862{
2863 rib_update ();
2864}
2865
2866/* Interface goes down. */
paula1ac18c2005-06-28 17:17:12 +00002867static void
paul718e3742002-12-13 20:15:29 +00002868rib_if_down (struct interface *ifp)
2869{
2870 rib_update ();
2871}
2872
2873/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00002874static void
paul718e3742002-12-13 20:15:29 +00002875rib_weed_table (struct route_table *table)
2876{
2877 struct route_node *rn;
2878 struct rib *rib;
2879 struct rib *next;
2880
2881 if (table)
2882 for (rn = route_top (table); rn; rn = route_next (rn))
2883 for (rib = rn->info; rib; rib = next)
2884 {
2885 next = rib->next;
2886
Paul Jakma6d691122006-07-27 21:49:00 +00002887 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2888 continue;
2889
paulb21b19c2003-06-15 01:28:29 +00002890 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00002891 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00002892 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002893 }
2894}
2895
2896/* Delete all routes from non main table. */
2897void
paula1ac18c2005-06-28 17:17:12 +00002898rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00002899{
2900 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2901 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2902}
2903
2904/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00002905static void
paul718e3742002-12-13 20:15:29 +00002906rib_sweep_table (struct route_table *table)
2907{
2908 struct route_node *rn;
2909 struct rib *rib;
2910 struct rib *next;
2911 int ret = 0;
2912
2913 if (table)
2914 for (rn = route_top (table); rn; rn = route_next (rn))
2915 for (rib = rn->info; rib; rib = next)
2916 {
2917 next = rib->next;
2918
Paul Jakma6d691122006-07-27 21:49:00 +00002919 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2920 continue;
2921
paul718e3742002-12-13 20:15:29 +00002922 if (rib->type == ZEBRA_ROUTE_KERNEL &&
2923 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
2924 {
2925 ret = rib_uninstall_kernel (rn, rib);
2926 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00002927 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002928 }
2929 }
2930}
2931
2932/* Sweep all RIB tables. */
2933void
paula1ac18c2005-06-28 17:17:12 +00002934rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00002935{
2936 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2937 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2938}
2939
2940/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00002941static void
paul718e3742002-12-13 20:15:29 +00002942rib_close_table (struct route_table *table)
2943{
2944 struct route_node *rn;
2945 struct rib *rib;
2946
2947 if (table)
2948 for (rn = route_top (table); rn; rn = route_next (rn))
2949 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002950 {
2951 if (! RIB_SYSTEM_ROUTE (rib)
2952 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2953 rib_uninstall_kernel (rn, rib);
2954 }
paul718e3742002-12-13 20:15:29 +00002955}
2956
2957/* Close all RIB tables. */
2958void
paula1ac18c2005-06-28 17:17:12 +00002959rib_close (void)
paul718e3742002-12-13 20:15:29 +00002960{
2961 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2962 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2963}
2964
2965/* Routing information base initialize. */
2966void
paula1ac18c2005-06-28 17:17:12 +00002967rib_init (void)
paul718e3742002-12-13 20:15:29 +00002968{
paul4d38fdb2005-04-28 17:35:14 +00002969 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00002970 /* VRF initialization. */
2971 vrf_init ();
2972}