blob: cc63dba0561993699ed8608e22f8b76aaac2621f [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:
Denis Ovsienkodc958242007-08-13 16:03:06 +0000966 if (IS_ZEBRA_DEBUG_RIB)
967 zlog_debug ("%s: calling kernel_delete_ipv4 (%p, %p)", __func__, rn, rib);
paul718e3742002-12-13 20:15:29 +0000968 ret = kernel_delete_ipv6 (&rn->p, rib);
969 break;
970#endif /* HAVE_IPV6 */
971 }
972
973 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
974 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
975
976 return ret;
977}
978
979/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +0000980static void
paul718e3742002-12-13 20:15:29 +0000981rib_uninstall (struct route_node *rn, struct rib *rib)
982{
983 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
984 {
985 redistribute_delete (&rn->p, rib);
986 if (! RIB_SYSTEM_ROUTE (rib))
987 rib_uninstall_kernel (rn, rib);
988 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
989 }
990}
991
Paul Jakma6d691122006-07-27 21:49:00 +0000992static void rib_unlink (struct route_node *, struct rib *);
993
paul718e3742002-12-13 20:15:29 +0000994/* Core function for processing routing information base. */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +0000995static void
996rib_process (struct route_node *rn)
paul718e3742002-12-13 20:15:29 +0000997{
998 struct rib *rib;
999 struct rib *next;
1000 struct rib *fib = NULL;
1001 struct rib *select = NULL;
Paul Jakma6d691122006-07-27 21:49:00 +00001002 struct rib *del = NULL;
pauld753e9e2003-01-22 19:45:50 +00001003 int installed = 0;
1004 struct nexthop *nexthop = NULL;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001005 char buf[INET6_ADDRSTRLEN];
paul4d38fdb2005-04-28 17:35:14 +00001006
1007 assert (rn);
1008
Paul Jakma93bdada2007-08-06 19:25:11 +00001009 if (IS_ZEBRA_DEBUG_RIB || IS_ZEBRA_DEBUG_RIB_Q)
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001010 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001011
paul718e3742002-12-13 20:15:29 +00001012 for (rib = rn->info; rib; rib = next)
1013 {
Denis Ovsienkodc958242007-08-13 16:03:06 +00001014 /* The next pointer is saved, because current pointer
1015 * may be passed to rib_unlink() in the middle of iteration.
1016 */
paul718e3742002-12-13 20:15:29 +00001017 next = rib->next;
pauld753e9e2003-01-22 19:45:50 +00001018
paul718e3742002-12-13 20:15:29 +00001019 /* Currently installed rib. */
1020 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Paul Jakma6d691122006-07-27 21:49:00 +00001021 {
1022 assert (fib == NULL);
1023 fib = rib;
1024 }
1025
1026 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1027 * which we need to do do further work with below.
1028 */
1029 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1030 {
1031 if (rib != fib)
1032 {
1033 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001034 zlog_debug ("%s: %s/%d: rn %p, removing rib %p", __func__,
1035 buf, rn->p.prefixlen, rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001036 rib_unlink (rn, rib);
1037 }
1038 else
1039 del = rib;
1040
1041 continue;
1042 }
paul4d38fdb2005-04-28 17:35:14 +00001043
paul718e3742002-12-13 20:15:29 +00001044 /* Skip unreachable nexthop. */
1045 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +00001046 continue;
paul718e3742002-12-13 20:15:29 +00001047
1048 /* Infinit distance. */
1049 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +00001050 continue;
paul718e3742002-12-13 20:15:29 +00001051
paulaf887b52006-01-18 14:52:52 +00001052 /* Newly selected rib, the common case. */
1053 if (!select)
1054 {
1055 select = rib;
1056 continue;
1057 }
1058
1059 /* filter route selection in following order:
paulaf887b52006-01-18 14:52:52 +00001060 * - connected beats other types
paula8d9c1f2006-01-25 06:31:04 +00001061 * - lower distance beats higher
paulaf887b52006-01-18 14:52:52 +00001062 * - lower metric beats higher for equal distance
1063 * - last, hence oldest, route wins tie break.
1064 */
paula1038a12006-01-30 14:08:51 +00001065
1066 /* Connected routes. Pick the last connected
1067 * route of the set of lowest metric connected routes.
1068 */
paula8d9c1f2006-01-25 06:31:04 +00001069 if (rib->type == ZEBRA_ROUTE_CONNECT)
1070 {
paula1038a12006-01-30 14:08:51 +00001071 if (select->type != ZEBRA_ROUTE_CONNECT
paula8d9c1f2006-01-25 06:31:04 +00001072 || rib->metric <= select->metric)
paula1038a12006-01-30 14:08:51 +00001073 select = rib;
1074 continue;
paula8d9c1f2006-01-25 06:31:04 +00001075 }
1076 else if (select->type == ZEBRA_ROUTE_CONNECT)
1077 continue;
1078
1079 /* higher distance loses */
1080 if (rib->distance > select->distance)
1081 continue;
1082
1083 /* lower wins */
1084 if (rib->distance < select->distance)
1085 {
paulaf887b52006-01-18 14:52:52 +00001086 select = rib;
paula8d9c1f2006-01-25 06:31:04 +00001087 continue;
1088 }
1089
1090 /* metric tie-breaks equal distance */
1091 if (rib->metric <= select->metric)
1092 select = rib;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001093 } /* for (rib = rn->info; rib; rib = next) */
1094
1095 /* After the cycle is finished, the following pointers will be set:
1096 * select --- the winner RIB entry, if any was found, otherwise NULL
1097 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1098 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1099 * rib --- NULL
1100 */
1101
1102 /* Same RIB entry is selected. Update FIB and finish. */
paul718e3742002-12-13 20:15:29 +00001103 if (select && select == fib)
1104 {
Paul Jakma6d691122006-07-27 21:49:00 +00001105 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001106 zlog_debug ("%s: %s/%d: Updating existing route, select %p, fib %p",
1107 __func__, buf, rn->p.prefixlen, select, fib);
paul718e3742002-12-13 20:15:29 +00001108 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +00001109 {
1110 redistribute_delete (&rn->p, select);
1111 if (! RIB_SYSTEM_ROUTE (select))
1112 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001113
paul4d38fdb2005-04-28 17:35:14 +00001114 /* Set real nexthop. */
1115 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +00001116
paul4d38fdb2005-04-28 17:35:14 +00001117 if (! RIB_SYSTEM_ROUTE (select))
1118 rib_install_kernel (rn, select);
1119 redistribute_add (&rn->p, select);
1120 }
pauld753e9e2003-01-22 19:45:50 +00001121 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001122 {
1123 /* Housekeeping code to deal with
1124 race conditions in kernel with linux
1125 netlink reporting interface up before IPv4 or IPv6 protocol
1126 is ready to add routes.
1127 This makes sure the routes are IN the kernel.
1128 */
pauld753e9e2003-01-22 19:45:50 +00001129
paul4d38fdb2005-04-28 17:35:14 +00001130 for (nexthop = select->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001131 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
paul4d38fdb2005-04-28 17:35:14 +00001132 {
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001133 installed = 1;
1134 break;
paul4d38fdb2005-04-28 17:35:14 +00001135 }
1136 if (! installed)
1137 rib_install_kernel (rn, select);
1138 }
Paul Jakma6d691122006-07-27 21:49:00 +00001139 goto end;
paul718e3742002-12-13 20:15:29 +00001140 }
1141
Denis Ovsienkodc958242007-08-13 16:03:06 +00001142 /* At this point we either haven't found the best RIB entry or it is
1143 * different from what we currently intend to flag with SELECTED. In both
1144 * cases, if a RIB block is present in FIB, it should be withdrawn.
1145 */
paul718e3742002-12-13 20:15:29 +00001146 if (fib)
1147 {
Paul Jakma6d691122006-07-27 21:49:00 +00001148 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001149 zlog_debug ("%s: %s/%d: Removing existing route, fib %p", __func__,
1150 buf, rn->p.prefixlen, fib);
paul718e3742002-12-13 20:15:29 +00001151 redistribute_delete (&rn->p, fib);
1152 if (! RIB_SYSTEM_ROUTE (fib))
1153 rib_uninstall_kernel (rn, fib);
1154 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1155
1156 /* Set real nexthop. */
1157 nexthop_active_update (rn, fib, 1);
1158 }
1159
Denis Ovsienkodc958242007-08-13 16:03:06 +00001160 /* Regardless of some RIB entry being SELECTED or not before, now we can
1161 * tell, that if a new winner exists, FIB is still not updated with this
1162 * data, but ready to be.
1163 */
paul718e3742002-12-13 20:15:29 +00001164 if (select)
1165 {
Paul Jakma6d691122006-07-27 21:49:00 +00001166 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001167 zlog_debug ("%s: %s/%d: Adding route, select %p", __func__, buf,
1168 rn->p.prefixlen, select);
paul718e3742002-12-13 20:15:29 +00001169 /* Set real nexthop. */
1170 nexthop_active_update (rn, select, 1);
1171
1172 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001173 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001174 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1175 redistribute_add (&rn->p, select);
1176 }
paul4d38fdb2005-04-28 17:35:14 +00001177
Paul Jakma6d691122006-07-27 21:49:00 +00001178 /* FIB route was removed, should be deleted */
1179 if (del)
1180 {
1181 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001182 zlog_debug ("%s: %s/%d: Deleting fib %p, rn %p", __func__, buf,
1183 rn->p.prefixlen, del, rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001184 rib_unlink (rn, del);
1185 }
paul4d38fdb2005-04-28 17:35:14 +00001186
Paul Jakma6d691122006-07-27 21:49:00 +00001187end:
1188 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma93bdada2007-08-06 19:25:11 +00001189 zlog_debug ("%s: %s/%d: rn %p dequeued", __func__, buf, rn->p.prefixlen, rn);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001190}
1191
1192/* Take a list of route_node structs and return 1, if there was a record picked from
1193 * it and processed by rib_process(). Don't process more, than one RN record; operate
1194 * only in the specified sub-queue.
1195 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001196static unsigned int
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001197process_subq (struct list * subq, u_char qindex)
1198{
1199 struct listnode *lnode;
1200 struct route_node *rnode;
1201 if (!(lnode = listhead (subq)))
1202 return 0;
1203 rnode = listgetdata (lnode);
1204 rib_process (rnode);
1205 if (rnode->info) /* The first RIB record is holding the flags bitmask. */
1206 UNSET_FLAG (((struct rib *)rnode->info)->rn_status, RIB_ROUTE_QUEUED(qindex));
1207 route_unlock_node (rnode);
1208 list_delete_node (subq, lnode);
1209 return 1;
1210}
1211
1212/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1213 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1214 * is pointed to the meta queue structure.
1215 */
1216static wq_item_status
1217meta_queue_process (struct work_queue *dummy, void *data)
1218{
1219 struct meta_queue * mq = data;
1220 u_char i;
1221 for (i = 0; i < MQ_SIZE; i++)
1222 if (process_subq (mq->subq[i], i))
1223 {
1224 mq->size--;
1225 break;
1226 }
1227 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1228}
1229
1230/* Look into the RN and queue it into one or more priority queues, increasing the size
1231 * for each data push done.
1232 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001233static void
1234rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001235{
1236 u_char qindex;
1237 struct rib *rib;
1238 char buf[INET6_ADDRSTRLEN];
1239 if (IS_ZEBRA_DEBUG_RIB_Q)
1240 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
1241 for (rib = rn->info; rib; rib = rib->next)
1242 {
1243 switch (rib->type)
1244 {
1245 case ZEBRA_ROUTE_KERNEL:
1246 case ZEBRA_ROUTE_CONNECT:
1247 qindex = 0;
1248 break;
1249 case ZEBRA_ROUTE_STATIC:
1250 qindex = 1;
1251 break;
1252 case ZEBRA_ROUTE_RIP:
1253 case ZEBRA_ROUTE_RIPNG:
1254 case ZEBRA_ROUTE_OSPF:
1255 case ZEBRA_ROUTE_OSPF6:
1256 case ZEBRA_ROUTE_ISIS:
1257 qindex = 2;
1258 break;
1259 case ZEBRA_ROUTE_BGP:
1260 qindex = 3;
1261 break;
1262 default:
1263 qindex = 4;
1264 break;
1265 }
1266 /* Invariant: at this point we always have rn->info set. */
1267 if (CHECK_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED(qindex)))
1268 {
1269 if (IS_ZEBRA_DEBUG_RIB_Q)
1270 zlog_debug ("%s: %s/%d: rn %p is already queued in sub-queue %u", __func__, buf, rn->p.prefixlen, rn, qindex);
1271 continue;
1272 }
1273 SET_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED(qindex));
1274 listnode_add (mq->subq[qindex], rn);
1275 route_lock_node (rn);
1276 mq->size++;
1277 if (IS_ZEBRA_DEBUG_RIB_Q)
1278 zlog_debug ("%s: %s/%d: queued rn %p into sub-queue %u", __func__, buf, rn->p.prefixlen, rn, qindex);
1279 }
paul4d38fdb2005-04-28 17:35:14 +00001280}
1281
Paul Jakma6d691122006-07-27 21:49:00 +00001282/* Add route_node to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001283static void
Paul Jakma6d691122006-07-27 21:49:00 +00001284rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
paul4d38fdb2005-04-28 17:35:14 +00001285{
Paul Jakma93bdada2007-08-06 19:25:11 +00001286 char buf[INET_ADDRSTRLEN];
Paul Jakma6d691122006-07-27 21:49:00 +00001287 assert (zebra && rn);
paul4d38fdb2005-04-28 17:35:14 +00001288
Paul Jakma93bdada2007-08-06 19:25:11 +00001289 if (IS_ZEBRA_DEBUG_RIB_Q)
1290 inet_ntop (AF_INET, &rn->p.u.prefix, buf, INET_ADDRSTRLEN);
1291
Paul Jakma6d691122006-07-27 21:49:00 +00001292 /* Pointless to queue a route_node with no RIB entries to add or remove */
1293 if (!rn->info)
1294 {
1295 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1296 __func__, rn, rn->lock);
1297 zlog_backtrace(LOG_DEBUG);
1298 return;
1299 }
paul4d38fdb2005-04-28 17:35:14 +00001300
Paul Jakma6d691122006-07-27 21:49:00 +00001301 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma93bdada2007-08-06 19:25:11 +00001302 zlog_info ("%s: %s/%d: work queue added", __func__, buf, rn->p.prefixlen);
Paul Jakma6d691122006-07-27 21:49:00 +00001303
1304 assert (zebra);
1305
paul4d38fdb2005-04-28 17:35:14 +00001306 if (zebra->ribq == NULL)
1307 {
Paul Jakma6d691122006-07-27 21:49:00 +00001308 zlog_err ("%s: work_queue does not exist!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001309 return;
1310 }
Paul Jakma6d691122006-07-27 21:49:00 +00001311
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001312 /* The RIB queue should normally be either empty or holding the only work_queue_item
1313 * element. In the latter case this element would hold a pointer to the meta queue
1314 * structure, which must be used to actually queue the route nodes to process. So
1315 * create the MQ holder, if necessary, then push the work into it in any case.
1316 * This semantics was introduced after 0.99.9 release.
1317 */
1318
1319 /* Should I invent work_queue_empty() and use it, or it's Ok to do as follows? */
1320 if (!zebra->ribq->items->count)
1321 work_queue_add (zebra->ribq, zebra->mq);
1322
1323 rib_meta_queue_add (zebra->mq, rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001324
1325 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma93bdada2007-08-06 19:25:11 +00001326 zlog_debug ("%s: %s/%d: rn %p queued", __func__, buf, rn->p.prefixlen, rn);
paul4d38fdb2005-04-28 17:35:14 +00001327
1328 return;
1329}
1330
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001331/* Create new meta queue. A destructor function doesn't seem to be necessary here. */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001332static struct meta_queue *
1333meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001334{
1335 struct meta_queue *new;
1336 unsigned i, failed = 0;
1337
1338 if ((new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue))) == NULL)
1339 return NULL;
1340 for (i = 0; i < MQ_SIZE; i++)
1341 if ((new->subq[i] = list_new ()) == NULL)
1342 failed = 1;
1343 if (failed)
1344 {
1345 for (i = 0; i < MQ_SIZE; i++)
1346 if (new->subq[i])
1347 list_delete (new->subq[i]);
1348 XFREE (MTYPE_WORK_QUEUE, new);
1349 return NULL;
1350 }
1351 new->size = 0;
1352 return new;
1353}
1354
paul4d38fdb2005-04-28 17:35:14 +00001355/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001356static void
paul4d38fdb2005-04-28 17:35:14 +00001357rib_queue_init (struct zebra_t *zebra)
1358{
1359 assert (zebra);
1360
1361 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001362 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001363 {
Paul Jakma6d691122006-07-27 21:49:00 +00001364 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001365 return;
1366 }
1367
1368 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001369 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001370 zebra->ribq->spec.errorfunc = NULL;
paul4d38fdb2005-04-28 17:35:14 +00001371 /* XXX: TODO: These should be runtime configurable via vty */
1372 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001373 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001374
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001375 if (!(zebra->mq = meta_queue_new ()))
1376 {
1377 zlog_err ("%s: could not initialise meta queue!", __func__);
1378 return;
1379 }
paul4d38fdb2005-04-28 17:35:14 +00001380 return;
paul718e3742002-12-13 20:15:29 +00001381}
1382
Paul Jakma6d691122006-07-27 21:49:00 +00001383/* RIB updates are processed via a queue of pointers to route_nodes.
1384 *
1385 * The queue length is bounded by the maximal size of the routing table,
1386 * as a route_node will not be requeued, if already queued.
1387 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001388 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1389 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1390 * and then submit route_node to queue for best-path selection later.
1391 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001392 *
1393 * Deleted RIBs are reaped during best-path selection.
1394 *
1395 * rib_addnode
1396 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001397 * |-------->| | best RIB, if required
1398 * | |
1399 * static_install->|->rib_addqueue...... -> rib_process
1400 * | |
1401 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001402 * |-> set RIB_ENTRY_REMOVE |
1403 * rib_delnode (RIB freed)
1404 *
1405 *
1406 * Queueing state for a route_node is kept in the head RIB entry, this
1407 * state must be preserved as and when the head RIB entry of a
1408 * route_node is changed by rib_unlink / rib_link. A small complication,
1409 * but saves having to allocate a dedicated object for this.
1410 *
1411 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1412 *
1413 * - route_nodes: refcounted by:
1414 * - RIBs attached to route_node:
1415 * - managed by: rib_link/unlink
1416 * - route_node processing queue
1417 * - managed by: rib_addqueue, rib_process.
1418 *
1419 */
1420
paul718e3742002-12-13 20:15:29 +00001421/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001422static void
Paul Jakma6d691122006-07-27 21:49:00 +00001423rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001424{
1425 struct rib *head;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001426 char buf[INET6_ADDRSTRLEN];
paul4d38fdb2005-04-28 17:35:14 +00001427
1428 assert (rib && rn);
1429
Paul Jakma6d691122006-07-27 21:49:00 +00001430 route_lock_node (rn); /* rn route table reference */
1431
1432 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001433 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001434 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001435 zlog_debug ("%s: %s/%d: rn %p, rib %p", __func__,
1436 buf, rn->p.prefixlen, rn, rib);
1437 }
Paul Jakma6d691122006-07-27 21:49:00 +00001438
paul718e3742002-12-13 20:15:29 +00001439 head = rn->info;
1440 if (head)
Paul Jakma6d691122006-07-27 21:49:00 +00001441 {
1442 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001443 zlog_debug ("%s: %s/%d: new head, rn_status copied over", __func__,
1444 buf, rn->p.prefixlen);
Paul Jakma6d691122006-07-27 21:49:00 +00001445 head->prev = rib;
1446 /* Transfer the rn status flags to the new head RIB */
1447 rib->rn_status = head->rn_status;
1448 }
paul718e3742002-12-13 20:15:29 +00001449 rib->next = head;
1450 rn->info = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001451 rib_queue_add (&zebrad, rn);
1452}
1453
1454static void
1455rib_addnode (struct route_node *rn, struct rib *rib)
1456{
1457 /* RIB node has been un-removed before route-node is processed.
1458 * route_node must hence already be on the queue for processing..
1459 */
1460 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1461 {
1462 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001463 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001464 char buf[INET6_ADDRSTRLEN];
1465 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001466 zlog_debug ("%s: %s/%d: rn %p, un-removed rib %p",
1467 __func__, buf, rn->p.prefixlen, rn, rib);
1468 }
Paul Jakma6d691122006-07-27 21:49:00 +00001469 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1470 return;
1471 }
1472 rib_link (rn, rib);
1473}
1474
1475static void
1476rib_unlink (struct route_node *rn, struct rib *rib)
1477{
1478 struct nexthop *nexthop, *next;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001479 char buf[INET6_ADDRSTRLEN];
Paul Jakma6d691122006-07-27 21:49:00 +00001480
1481 assert (rn && rib);
1482
1483 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001484 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001485 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001486 zlog_debug ("%s: %s/%d: rn %p, rib %p",
1487 __func__, buf, rn->p.prefixlen, rn, rib);
1488 }
Paul Jakma6d691122006-07-27 21:49:00 +00001489
1490 if (rib->next)
1491 rib->next->prev = rib->prev;
1492
1493 if (rib->prev)
1494 rib->prev->next = rib->next;
1495 else
1496 {
1497 rn->info = rib->next;
1498
1499 if (rn->info)
1500 {
1501 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001502 zlog_debug ("%s: %s/%d: rn %p, rib %p, new head copy",
1503 __func__, buf, rn->p.prefixlen, rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001504 rib->next->rn_status = rib->rn_status;
1505 }
1506 }
1507
1508 /* free RIB and nexthops */
1509 for (nexthop = rib->nexthop; nexthop; nexthop = next)
1510 {
1511 next = nexthop->next;
1512 nexthop_free (nexthop);
1513 }
1514 XFREE (MTYPE_RIB, rib);
1515
1516 route_unlock_node (rn); /* rn route table reference */
paul718e3742002-12-13 20:15:29 +00001517}
1518
paula1ac18c2005-06-28 17:17:12 +00001519static void
paul718e3742002-12-13 20:15:29 +00001520rib_delnode (struct route_node *rn, struct rib *rib)
1521{
Paul Jakma6d691122006-07-27 21:49:00 +00001522 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001523 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001524 char buf[INET6_ADDRSTRLEN];
1525 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001526 zlog_debug ("%s: %s/%d: rn %p, rib %p, removing", __func__,
1527 buf, rn->p.prefixlen, rn, rib);
1528 }
Paul Jakma6d691122006-07-27 21:49:00 +00001529 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1530 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001531}
1532
1533int
1534rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001535 struct in_addr *gate, struct in_addr *src,
1536 unsigned int ifindex, u_int32_t vrf_id,
paul718e3742002-12-13 20:15:29 +00001537 u_int32_t metric, u_char distance)
1538{
1539 struct rib *rib;
1540 struct rib *same = NULL;
1541 struct route_table *table;
1542 struct route_node *rn;
1543 struct nexthop *nexthop;
1544
1545 /* Lookup table. */
1546 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1547 if (! table)
1548 return 0;
1549
1550 /* Make it sure prefixlen is applied to the prefix. */
1551 apply_mask_ipv4 (p);
1552
1553 /* Set default distance by route type. */
1554 if (distance == 0)
1555 {
1556 distance = route_info[type].distance;
1557
1558 /* iBGP distance is 200. */
1559 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1560 distance = 200;
1561 }
1562
1563 /* Lookup route node.*/
1564 rn = route_node_get (table, (struct prefix *) p);
1565
1566 /* If same type of route are installed, treat it as a implicit
1567 withdraw. */
1568 for (rib = rn->info; rib; rib = rib->next)
1569 {
Paul Jakma6d691122006-07-27 21:49:00 +00001570 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1571 continue;
1572
hassoebf1ead2005-09-21 14:58:20 +00001573 if (rib->type != type)
1574 continue;
1575 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001576 {
1577 same = rib;
1578 break;
1579 }
hassoebf1ead2005-09-21 14:58:20 +00001580 /* Duplicate connected route comes in. */
1581 else if ((nexthop = rib->nexthop) &&
1582 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001583 nexthop->ifindex == ifindex &&
1584 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001585 {
1586 rib->refcnt++;
1587 return 0 ;
1588 }
paul718e3742002-12-13 20:15:29 +00001589 }
1590
1591 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001592 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001593 rib->type = type;
1594 rib->distance = distance;
1595 rib->flags = flags;
1596 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001597 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001598 rib->nexthop_num = 0;
1599 rib->uptime = time (NULL);
1600
1601 /* Nexthop settings. */
1602 if (gate)
1603 {
1604 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001605 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001606 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001607 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001608 }
1609 else
1610 nexthop_ifindex_add (rib, ifindex);
1611
1612 /* If this route is kernel route, set FIB flag to the route. */
1613 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1614 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1615 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1616
1617 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001618 if (IS_ZEBRA_DEBUG_RIB)
1619 zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
paul718e3742002-12-13 20:15:29 +00001620 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001621
paul718e3742002-12-13 20:15:29 +00001622 /* Free implicit route.*/
1623 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001624 {
1625 if (IS_ZEBRA_DEBUG_RIB)
1626 zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001627 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001628 }
paul4d38fdb2005-04-28 17:35:14 +00001629
1630 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001631 return 0;
1632}
1633
Denis Ovsienkodc958242007-08-13 16:03:06 +00001634/* This function dumps the contents of a given RIB entry into
1635 * standard debug log. Calling function name and IP prefix in
1636 * question are passed as 1st and 2nd arguments.
1637 */
1638
1639void rib_dump (const char * func, const struct prefix_ipv4 * p, const struct rib * rib)
1640{
1641 char straddr1[INET_ADDRSTRLEN], straddr2[INET_ADDRSTRLEN];
1642 struct nexthop *nexthop;
1643
1644 inet_ntop (AF_INET, &p->prefix, straddr1, INET_ADDRSTRLEN);
1645 zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr1, p->prefixlen);
1646 zlog_debug
1647 (
1648 "%s: refcnt == %lu, uptime == %u, type == %u, table == %d",
1649 func,
1650 rib->refcnt,
1651 rib->uptime,
1652 rib->type,
1653 rib->table
1654 );
1655 zlog_debug
1656 (
1657 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1658 func,
1659 rib->metric,
1660 rib->distance,
1661 rib->flags,
1662 rib->status
1663 );
1664 zlog_debug
1665 (
1666 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1667 func,
1668 rib->nexthop_num,
1669 rib->nexthop_active_num,
1670 rib->nexthop_fib_num
1671 );
1672 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1673 {
1674 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, straddr1, INET_ADDRSTRLEN);
1675 inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, straddr2, INET_ADDRSTRLEN);
1676 zlog_debug
1677 (
1678 "%s: NH %s (%s) with flags %s%s%s",
1679 func,
1680 straddr1,
1681 straddr2,
1682 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1683 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1684 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1685 );
1686 }
1687 zlog_debug ("%s: dump complete", func);
1688}
1689
1690/* This is an exported helper to rtm_read() to dump the strange
1691 * RIB entry found by rib_lookup_ipv4_route()
1692 */
1693
1694void rib_lookup_and_dump (struct prefix_ipv4 * p)
1695{
1696 struct route_table *table;
1697 struct route_node *rn;
1698 struct rib *rib;
1699 char prefix_buf[INET_ADDRSTRLEN];
1700
1701 /* Lookup table. */
1702 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1703 if (! table)
1704 {
1705 zlog_err ("%s: vrf_table() returned NULL", __func__);
1706 return;
1707 }
1708
1709 inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
1710 /* Scan the RIB table for exactly matching RIB entry. */
1711 rn = route_node_lookup (table, (struct prefix *) p);
1712
1713 /* No route for this prefix. */
1714 if (! rn)
1715 {
1716 zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
1717 return;
1718 }
1719
1720 /* Unlock node. */
1721 route_unlock_node (rn);
1722
1723 /* let's go */
1724 for (rib = rn->info; rib; rib = rib->next)
1725 {
1726 zlog_debug
1727 (
1728 "%s: rn %p, rib %p: %s, %s",
1729 __func__,
1730 rn,
1731 rib,
1732 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
1733 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
1734 );
1735 rib_dump (__func__, p, rib);
1736 }
1737}
1738
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001739/* Check if requested address assignment will fail due to another
1740 * route being installed by zebra in FIB already. Take necessary
1741 * actions, if needed: remove such a route from FIB and deSELECT
1742 * corresponding RIB entry. Then put affected RN into RIBQ head.
1743 */
1744void rib_lookup_and_pushup (struct prefix_ipv4 * p)
1745{
1746 struct route_table *table;
1747 struct route_node *rn;
1748 struct rib *rib;
1749 unsigned changed = 0;
1750
1751 if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
1752 {
1753 zlog_err ("%s: vrf_table() returned NULL", __func__);
1754 return;
1755 }
1756
1757 /* No matches would be the simplest case. */
1758 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
1759 return;
1760
1761 /* Unlock node. */
1762 route_unlock_node (rn);
1763
1764 /* Check all RIB entries. In case any changes have to be done, requeue
1765 * the RN into RIBQ head. If the routing message about the new connected
1766 * route (generated by the IP address we are going to assign very soon)
1767 * comes before the RIBQ is processed, the new RIB entry will join
1768 * RIBQ record already on head. This is necessary for proper revalidation
1769 * of the rest of the RIB.
1770 */
1771 for (rib = rn->info; rib; rib = rib->next)
1772 {
1773 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
1774 ! RIB_SYSTEM_ROUTE (rib))
1775 {
1776 changed = 1;
1777 if (IS_ZEBRA_DEBUG_RIB)
1778 {
1779 char buf[INET_ADDRSTRLEN];
1780 inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
1781 zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
1782 rib_dump (__func__, (struct prefix_ipv4 *)&rn->p, rib);
1783 }
1784 rib_uninstall (rn, rib);
1785 }
1786 }
1787 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001788 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001789}
1790
paul718e3742002-12-13 20:15:29 +00001791int
1792rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib)
1793{
1794 struct route_table *table;
1795 struct route_node *rn;
1796 struct rib *same;
1797 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00001798
paul718e3742002-12-13 20:15:29 +00001799 /* Lookup table. */
1800 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1801 if (! table)
1802 return 0;
paul718e3742002-12-13 20:15:29 +00001803 /* Make it sure prefixlen is applied to the prefix. */
1804 apply_mask_ipv4 (p);
1805
1806 /* Set default distance by route type. */
1807 if (rib->distance == 0)
1808 {
1809 rib->distance = route_info[rib->type].distance;
1810
1811 /* iBGP distance is 200. */
1812 if (rib->type == ZEBRA_ROUTE_BGP
1813 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1814 rib->distance = 200;
1815 }
1816
1817 /* Lookup route node.*/
1818 rn = route_node_get (table, (struct prefix *) p);
1819
1820 /* If same type of route are installed, treat it as a implicit
1821 withdraw. */
1822 for (same = rn->info; same; same = same->next)
1823 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00001824 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00001825 continue;
1826
paul718e3742002-12-13 20:15:29 +00001827 if (same->type == rib->type && same->table == rib->table
1828 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001829 break;
paul718e3742002-12-13 20:15:29 +00001830 }
paul4d38fdb2005-04-28 17:35:14 +00001831
paul718e3742002-12-13 20:15:29 +00001832 /* If this route is kernel route, set FIB flag to the route. */
1833 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
1834 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1835 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1836
1837 /* Link new rib to node.*/
1838 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001839 if (IS_ZEBRA_DEBUG_RIB)
1840 {
1841 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
1842 __func__, rn, rib);
1843 rib_dump (__func__, p, rib);
1844 }
paul718e3742002-12-13 20:15:29 +00001845
paul718e3742002-12-13 20:15:29 +00001846 /* Free implicit route.*/
1847 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001848 {
1849 if (IS_ZEBRA_DEBUG_RIB)
1850 {
1851 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
1852 __func__, rn, same);
1853 rib_dump (__func__, p, same);
1854 }
paul4d38fdb2005-04-28 17:35:14 +00001855 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001856 }
paul4d38fdb2005-04-28 17:35:14 +00001857
1858 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001859 return 0;
1860}
1861
hassoebf1ead2005-09-21 14:58:20 +00001862/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00001863int
1864rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
1865 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1866{
1867 struct route_table *table;
1868 struct route_node *rn;
1869 struct rib *rib;
1870 struct rib *fib = NULL;
1871 struct rib *same = NULL;
1872 struct nexthop *nexthop;
1873 char buf1[BUFSIZ];
1874 char buf2[BUFSIZ];
1875
1876 /* Lookup table. */
1877 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1878 if (! table)
1879 return 0;
1880
1881 /* Apply mask. */
1882 apply_mask_ipv4 (p);
1883
paul5ec90d22003-06-19 01:41:37 +00001884 if (IS_ZEBRA_DEBUG_KERNEL && gate)
ajsb6178002004-12-07 21:12:56 +00001885 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
paul5ec90d22003-06-19 01:41:37 +00001886 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1887 p->prefixlen,
1888 inet_ntoa (*gate),
1889 ifindex);
1890
paul718e3742002-12-13 20:15:29 +00001891 /* Lookup route node. */
1892 rn = route_node_lookup (table, (struct prefix *) p);
1893 if (! rn)
1894 {
1895 if (IS_ZEBRA_DEBUG_KERNEL)
1896 {
1897 if (gate)
ajsb6178002004-12-07 21:12:56 +00001898 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001899 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1900 p->prefixlen,
1901 inet_ntop (AF_INET, gate, buf2, BUFSIZ),
1902 ifindex);
1903 else
ajsb6178002004-12-07 21:12:56 +00001904 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001905 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1906 p->prefixlen,
1907 ifindex);
1908 }
1909 return ZEBRA_ERR_RTNOEXIST;
1910 }
1911
1912 /* Lookup same type route. */
1913 for (rib = rn->info; rib; rib = rib->next)
1914 {
Paul Jakma6d691122006-07-27 21:49:00 +00001915 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1916 continue;
1917
paul718e3742002-12-13 20:15:29 +00001918 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1919 fib = rib;
1920
hassoebf1ead2005-09-21 14:58:20 +00001921 if (rib->type != type)
1922 continue;
1923 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
1924 nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex)
paul718e3742002-12-13 20:15:29 +00001925 {
hassoebf1ead2005-09-21 14:58:20 +00001926 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00001927 {
hassoebf1ead2005-09-21 14:58:20 +00001928 rib->refcnt--;
1929 route_unlock_node (rn);
1930 route_unlock_node (rn);
1931 return 0;
paul718e3742002-12-13 20:15:29 +00001932 }
hassoebf1ead2005-09-21 14:58:20 +00001933 same = rib;
1934 break;
paul718e3742002-12-13 20:15:29 +00001935 }
hassoebf1ead2005-09-21 14:58:20 +00001936 /* Make sure that the route found has the same gateway. */
1937 else if (gate == NULL ||
1938 ((nexthop = rib->nexthop) &&
1939 (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
1940 IPV4_ADDR_SAME (&nexthop->rgate.ipv4, gate))))
paul5ec90d22003-06-19 01:41:37 +00001941 {
hassoebf1ead2005-09-21 14:58:20 +00001942 same = rib;
1943 break;
paul718e3742002-12-13 20:15:29 +00001944 }
1945 }
1946
1947 /* If same type of route can't be found and this message is from
1948 kernel. */
1949 if (! same)
1950 {
1951 if (fib && type == ZEBRA_ROUTE_KERNEL)
1952 {
1953 /* Unset flags. */
1954 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1955 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1956
1957 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1958 }
1959 else
1960 {
1961 if (IS_ZEBRA_DEBUG_KERNEL)
1962 {
1963 if (gate)
ajsb6178002004-12-07 21:12:56 +00001964 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001965 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1966 p->prefixlen,
1967 inet_ntop (AF_INET, gate, buf2, BUFSIZ),
1968 ifindex,
1969 type);
1970 else
ajsb6178002004-12-07 21:12:56 +00001971 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001972 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1973 p->prefixlen,
1974 ifindex,
1975 type);
1976 }
1977 route_unlock_node (rn);
1978 return ZEBRA_ERR_RTNOEXIST;
1979 }
1980 }
paul4d38fdb2005-04-28 17:35:14 +00001981
paul718e3742002-12-13 20:15:29 +00001982 if (same)
1983 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00001984
paul718e3742002-12-13 20:15:29 +00001985 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001986 return 0;
1987}
1988
1989/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00001990static void
paul718e3742002-12-13 20:15:29 +00001991static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
1992{
1993 struct rib *rib;
1994 struct route_node *rn;
1995 struct route_table *table;
1996
1997 /* Lookup table. */
1998 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1999 if (! table)
2000 return;
2001
2002 /* Lookup existing route */
2003 rn = route_node_get (table, p);
2004 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002005 {
2006 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2007 continue;
2008
2009 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2010 break;
2011 }
paul718e3742002-12-13 20:15:29 +00002012
2013 if (rib)
2014 {
2015 /* Same distance static route is there. Update it with new
2016 nexthop. */
paul718e3742002-12-13 20:15:29 +00002017 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002018 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002019 {
2020 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002021 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002022 break;
2023 case STATIC_IPV4_IFNAME:
2024 nexthop_ifname_add (rib, si->gate.ifname);
2025 break;
2026 case STATIC_IPV4_BLACKHOLE:
2027 nexthop_blackhole_add (rib);
2028 break;
paul4d38fdb2005-04-28 17:35:14 +00002029 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002030 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002031 }
2032 else
2033 {
2034 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002035 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2036
paul718e3742002-12-13 20:15:29 +00002037 rib->type = ZEBRA_ROUTE_STATIC;
2038 rib->distance = si->distance;
2039 rib->metric = 0;
2040 rib->nexthop_num = 0;
2041
2042 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002043 {
2044 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002045 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002046 break;
2047 case STATIC_IPV4_IFNAME:
2048 nexthop_ifname_add (rib, si->gate.ifname);
2049 break;
2050 case STATIC_IPV4_BLACKHOLE:
2051 nexthop_blackhole_add (rib);
2052 break;
2053 }
paul718e3742002-12-13 20:15:29 +00002054
hasso81dfcaa2003-05-25 19:21:25 +00002055 /* Save the flags of this static routes (reject, blackhole) */
2056 rib->flags = si->flags;
2057
paul718e3742002-12-13 20:15:29 +00002058 /* Link this rib to the tree. */
2059 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002060 }
2061}
2062
paula1ac18c2005-06-28 17:17:12 +00002063static int
paul718e3742002-12-13 20:15:29 +00002064static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2065{
2066 if (nexthop->type == NEXTHOP_TYPE_IPV4
2067 && si->type == STATIC_IPV4_GATEWAY
2068 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2069 return 1;
2070 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2071 && si->type == STATIC_IPV4_IFNAME
2072 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2073 return 1;
paul595db7f2003-05-25 21:35:06 +00002074 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2075 && si->type == STATIC_IPV4_BLACKHOLE)
2076 return 1;
paule8e19462006-01-19 20:16:55 +00002077 return 0;
paul718e3742002-12-13 20:15:29 +00002078}
2079
2080/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002081static void
paul718e3742002-12-13 20:15:29 +00002082static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
2083{
2084 struct route_node *rn;
2085 struct rib *rib;
2086 struct nexthop *nexthop;
2087 struct route_table *table;
2088
2089 /* Lookup table. */
2090 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2091 if (! table)
2092 return;
paul4d38fdb2005-04-28 17:35:14 +00002093
paul718e3742002-12-13 20:15:29 +00002094 /* Lookup existing route with type and distance. */
2095 rn = route_node_lookup (table, p);
2096 if (! rn)
2097 return;
2098
2099 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002100 {
2101 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2102 continue;
2103
2104 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2105 break;
2106 }
paul718e3742002-12-13 20:15:29 +00002107
2108 if (! rib)
2109 {
2110 route_unlock_node (rn);
2111 return;
2112 }
2113
2114 /* Lookup nexthop. */
2115 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2116 if (static_ipv4_nexthop_same (nexthop, si))
2117 break;
2118
2119 /* Can't find nexthop. */
2120 if (! nexthop)
2121 {
2122 route_unlock_node (rn);
2123 return;
2124 }
2125
2126 /* Check nexthop. */
2127 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002128 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002129 else
2130 {
paul6baeb982003-10-28 03:47:15 +00002131 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2132 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002133 nexthop_delete (rib, nexthop);
2134 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002135 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002136 }
paul718e3742002-12-13 20:15:29 +00002137 /* Unlock node. */
2138 route_unlock_node (rn);
2139}
2140
2141/* Add static route into static route configuration. */
2142int
hasso39db97e2004-10-12 20:50:58 +00002143static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00002144 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002145{
2146 u_char type = 0;
2147 struct route_node *rn;
2148 struct static_ipv4 *si;
2149 struct static_ipv4 *pp;
2150 struct static_ipv4 *cp;
2151 struct static_ipv4 *update = NULL;
2152 struct route_table *stable;
2153
2154 /* Lookup table. */
2155 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2156 if (! stable)
2157 return -1;
2158
2159 /* Lookup static route prefix. */
2160 rn = route_node_get (stable, p);
2161
2162 /* Make flags. */
2163 if (gate)
2164 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002165 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002166 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002167 else
2168 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002169
2170 /* Do nothing if there is a same static route. */
2171 for (si = rn->info; si; si = si->next)
2172 {
2173 if (type == si->type
2174 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2175 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2176 {
2177 if (distance == si->distance)
2178 {
2179 route_unlock_node (rn);
2180 return 0;
2181 }
2182 else
2183 update = si;
2184 }
2185 }
2186
Paul Jakma3c0755d2006-12-08 00:53:14 +00002187 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002188 if (update)
2189 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
2190
2191 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002192 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
paul718e3742002-12-13 20:15:29 +00002193
2194 si->type = type;
2195 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002196 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002197
2198 if (gate)
2199 si->gate.ipv4 = *gate;
2200 if (ifname)
2201 si->gate.ifname = XSTRDUP (0, ifname);
2202
2203 /* Add new static route information to the tree with sort by
2204 distance value and gateway address. */
2205 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2206 {
2207 if (si->distance < cp->distance)
2208 break;
2209 if (si->distance > cp->distance)
2210 continue;
2211 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2212 {
2213 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2214 break;
2215 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2216 continue;
2217 }
2218 }
2219
2220 /* Make linked list. */
2221 if (pp)
2222 pp->next = si;
2223 else
2224 rn->info = si;
2225 if (cp)
2226 cp->prev = si;
2227 si->prev = pp;
2228 si->next = cp;
2229
2230 /* Install into rib. */
2231 static_install_ipv4 (p, si);
2232
2233 return 1;
2234}
2235
2236/* Delete static route from static route configuration. */
2237int
hasso39db97e2004-10-12 20:50:58 +00002238static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00002239 u_char distance, u_int32_t vrf_id)
2240{
2241 u_char type = 0;
2242 struct route_node *rn;
2243 struct static_ipv4 *si;
2244 struct route_table *stable;
2245
2246 /* Lookup table. */
2247 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2248 if (! stable)
2249 return -1;
2250
2251 /* Lookup static route prefix. */
2252 rn = route_node_lookup (stable, p);
2253 if (! rn)
2254 return 0;
2255
2256 /* Make flags. */
2257 if (gate)
2258 type = STATIC_IPV4_GATEWAY;
2259 else if (ifname)
2260 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002261 else
2262 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002263
2264 /* Find same static route is the tree */
2265 for (si = rn->info; si; si = si->next)
2266 if (type == si->type
2267 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2268 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2269 break;
2270
2271 /* Can't find static route. */
2272 if (! si)
2273 {
2274 route_unlock_node (rn);
2275 return 0;
2276 }
2277
2278 /* Install into rib. */
2279 static_uninstall_ipv4 (p, si);
2280
2281 /* Unlink static route from linked list. */
2282 if (si->prev)
2283 si->prev->next = si->next;
2284 else
2285 rn->info = si->next;
2286 if (si->next)
2287 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002288 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002289
2290 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002291 if (ifname)
2292 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002293 XFREE (MTYPE_STATIC_IPV4, si);
2294
paul143a3852003-09-29 20:06:13 +00002295 route_unlock_node (rn);
2296
paul718e3742002-12-13 20:15:29 +00002297 return 1;
2298}
2299
2300
2301#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00002302static int
paul718e3742002-12-13 20:15:29 +00002303rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2304 struct in6_addr *gate, unsigned int ifindex, int table)
2305{
hasso726f9b22003-05-25 21:04:54 +00002306 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2307#if defined (MUSICA) || defined (LINUX)
2308 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2309 if (p->prefixlen == 96)
2310 return 0;
2311#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00002312 return 1;
hasso726f9b22003-05-25 21:04:54 +00002313 }
paul718e3742002-12-13 20:15:29 +00002314 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
2315 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
2316 {
2317 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
2318 return 1;
2319 }
2320 return 0;
2321}
2322
2323int
2324rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00002325 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
2326 u_int32_t metric, u_char distance)
paul718e3742002-12-13 20:15:29 +00002327{
2328 struct rib *rib;
2329 struct rib *same = NULL;
2330 struct route_table *table;
2331 struct route_node *rn;
2332 struct nexthop *nexthop;
2333
paul718e3742002-12-13 20:15:29 +00002334 /* Lookup table. */
2335 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2336 if (! table)
2337 return 0;
2338
2339 /* Make sure mask is applied. */
2340 apply_mask_ipv6 (p);
2341
2342 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002343 if (!distance)
2344 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002345
2346 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2347 distance = 200;
2348
2349 /* Filter bogus route. */
2350 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
2351 return 0;
2352
2353 /* Lookup route node.*/
2354 rn = route_node_get (table, (struct prefix *) p);
2355
2356 /* If same type of route are installed, treat it as a implicit
2357 withdraw. */
2358 for (rib = rn->info; rib; rib = rib->next)
2359 {
Paul Jakma6d691122006-07-27 21:49:00 +00002360 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2361 continue;
2362
hassoebf1ead2005-09-21 14:58:20 +00002363 if (rib->type != type)
2364 continue;
2365 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002366 {
2367 same = rib;
paul718e3742002-12-13 20:15:29 +00002368 break;
2369 }
hassoebf1ead2005-09-21 14:58:20 +00002370 else if ((nexthop = rib->nexthop) &&
2371 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2372 nexthop->ifindex == ifindex)
2373 {
2374 rib->refcnt++;
2375 return 0;
2376 }
paul718e3742002-12-13 20:15:29 +00002377 }
2378
2379 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002380 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2381
paul718e3742002-12-13 20:15:29 +00002382 rib->type = type;
2383 rib->distance = distance;
2384 rib->flags = flags;
2385 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00002386 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00002387 rib->nexthop_num = 0;
2388 rib->uptime = time (NULL);
2389
2390 /* Nexthop settings. */
2391 if (gate)
2392 {
2393 if (ifindex)
2394 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2395 else
2396 nexthop_ipv6_add (rib, gate);
2397 }
2398 else
2399 nexthop_ifindex_add (rib, ifindex);
2400
2401 /* If this route is kernel route, set FIB flag to the route. */
2402 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2403 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2404 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2405
2406 /* Link new rib to node.*/
2407 rib_addnode (rn, rib);
2408
paul718e3742002-12-13 20:15:29 +00002409 /* Free implicit route.*/
2410 if (same)
paul4d38fdb2005-04-28 17:35:14 +00002411 rib_delnode (rn, same);
2412
2413 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002414 return 0;
2415}
2416
hassoebf1ead2005-09-21 14:58:20 +00002417/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002418int
2419rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
2420 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
2421{
2422 struct route_table *table;
2423 struct route_node *rn;
2424 struct rib *rib;
2425 struct rib *fib = NULL;
2426 struct rib *same = NULL;
2427 struct nexthop *nexthop;
2428 char buf1[BUFSIZ];
2429 char buf2[BUFSIZ];
2430
2431 /* Apply mask. */
2432 apply_mask_ipv6 (p);
2433
2434 /* Lookup table. */
2435 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2436 if (! table)
2437 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002438
paul718e3742002-12-13 20:15:29 +00002439 /* Lookup route node. */
2440 rn = route_node_lookup (table, (struct prefix *) p);
2441 if (! rn)
2442 {
2443 if (IS_ZEBRA_DEBUG_KERNEL)
2444 {
2445 if (gate)
ajsb6178002004-12-07 21:12:56 +00002446 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00002447 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
2448 p->prefixlen,
2449 inet_ntop (AF_INET6, gate, buf2, BUFSIZ),
2450 ifindex);
2451 else
ajsb6178002004-12-07 21:12:56 +00002452 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00002453 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
2454 p->prefixlen,
2455 ifindex);
2456 }
2457 return ZEBRA_ERR_RTNOEXIST;
2458 }
2459
2460 /* Lookup same type route. */
2461 for (rib = rn->info; rib; rib = rib->next)
2462 {
Paul Jakma6d691122006-07-27 21:49:00 +00002463 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2464 continue;
2465
paul718e3742002-12-13 20:15:29 +00002466 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2467 fib = rib;
2468
hassoebf1ead2005-09-21 14:58:20 +00002469 if (rib->type != type)
2470 continue;
2471 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
2472 nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex)
paul718e3742002-12-13 20:15:29 +00002473 {
hassoebf1ead2005-09-21 14:58:20 +00002474 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002475 {
hassoebf1ead2005-09-21 14:58:20 +00002476 rib->refcnt--;
2477 route_unlock_node (rn);
2478 route_unlock_node (rn);
2479 return 0;
paul718e3742002-12-13 20:15:29 +00002480 }
hassoebf1ead2005-09-21 14:58:20 +00002481 same = rib;
2482 break;
paul718e3742002-12-13 20:15:29 +00002483 }
hassoebf1ead2005-09-21 14:58:20 +00002484 /* Make sure that the route found has the same gateway. */
2485 else if (gate == NULL ||
2486 ((nexthop = rib->nexthop) &&
2487 (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate) ||
2488 IPV6_ADDR_SAME (&nexthop->rgate.ipv6, gate))))
paul718e3742002-12-13 20:15:29 +00002489 {
hassoebf1ead2005-09-21 14:58:20 +00002490 same = rib;
2491 break;
paul718e3742002-12-13 20:15:29 +00002492 }
2493 }
2494
2495 /* If same type of route can't be found and this message is from
2496 kernel. */
2497 if (! same)
2498 {
2499 if (fib && type == ZEBRA_ROUTE_KERNEL)
2500 {
2501 /* Unset flags. */
2502 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2503 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2504
2505 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2506 }
2507 else
2508 {
2509 if (IS_ZEBRA_DEBUG_KERNEL)
2510 {
2511 if (gate)
ajsb6178002004-12-07 21:12:56 +00002512 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00002513 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
2514 p->prefixlen,
2515 inet_ntop (AF_INET6, gate, buf2, BUFSIZ),
2516 ifindex,
2517 type);
2518 else
ajsb6178002004-12-07 21:12:56 +00002519 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00002520 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
2521 p->prefixlen,
2522 ifindex,
2523 type);
2524 }
2525 route_unlock_node (rn);
2526 return ZEBRA_ERR_RTNOEXIST;
2527 }
2528 }
2529
2530 if (same)
2531 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002532
paul718e3742002-12-13 20:15:29 +00002533 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002534 return 0;
2535}
2536
2537/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002538static void
paul718e3742002-12-13 20:15:29 +00002539static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2540{
2541 struct rib *rib;
2542 struct route_table *table;
2543 struct route_node *rn;
2544
2545 /* Lookup table. */
2546 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2547 if (! table)
2548 return;
2549
2550 /* Lookup existing route */
2551 rn = route_node_get (table, p);
2552 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002553 {
2554 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2555 continue;
2556
2557 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2558 break;
2559 }
paul718e3742002-12-13 20:15:29 +00002560
2561 if (rib)
2562 {
2563 /* Same distance static route is there. Update it with new
2564 nexthop. */
paul718e3742002-12-13 20:15:29 +00002565 route_unlock_node (rn);
2566
2567 switch (si->type)
2568 {
2569 case STATIC_IPV6_GATEWAY:
2570 nexthop_ipv6_add (rib, &si->ipv6);
2571 break;
2572 case STATIC_IPV6_IFNAME:
2573 nexthop_ifname_add (rib, si->ifname);
2574 break;
2575 case STATIC_IPV6_GATEWAY_IFNAME:
2576 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2577 break;
2578 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002579 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002580 }
2581 else
2582 {
2583 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002584 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2585
paul718e3742002-12-13 20:15:29 +00002586 rib->type = ZEBRA_ROUTE_STATIC;
2587 rib->distance = si->distance;
2588 rib->metric = 0;
2589 rib->nexthop_num = 0;
2590
2591 switch (si->type)
2592 {
2593 case STATIC_IPV6_GATEWAY:
2594 nexthop_ipv6_add (rib, &si->ipv6);
2595 break;
2596 case STATIC_IPV6_IFNAME:
2597 nexthop_ifname_add (rib, si->ifname);
2598 break;
2599 case STATIC_IPV6_GATEWAY_IFNAME:
2600 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2601 break;
2602 }
2603
hasso81dfcaa2003-05-25 19:21:25 +00002604 /* Save the flags of this static routes (reject, blackhole) */
2605 rib->flags = si->flags;
2606
paul718e3742002-12-13 20:15:29 +00002607 /* Link this rib to the tree. */
2608 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002609 }
2610}
2611
paula1ac18c2005-06-28 17:17:12 +00002612static int
paul718e3742002-12-13 20:15:29 +00002613static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2614{
2615 if (nexthop->type == NEXTHOP_TYPE_IPV6
2616 && si->type == STATIC_IPV6_GATEWAY
2617 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2618 return 1;
2619 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2620 && si->type == STATIC_IPV6_IFNAME
2621 && strcmp (nexthop->ifname, si->ifname) == 0)
2622 return 1;
2623 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2624 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2625 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2626 && strcmp (nexthop->ifname, si->ifname) == 0)
2627 return 1;
paule8e19462006-01-19 20:16:55 +00002628 return 0;
paul718e3742002-12-13 20:15:29 +00002629}
2630
paula1ac18c2005-06-28 17:17:12 +00002631static void
paul718e3742002-12-13 20:15:29 +00002632static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2633{
2634 struct route_table *table;
2635 struct route_node *rn;
2636 struct rib *rib;
2637 struct nexthop *nexthop;
2638
2639 /* Lookup table. */
2640 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2641 if (! table)
2642 return;
2643
2644 /* Lookup existing route with type and distance. */
2645 rn = route_node_lookup (table, (struct prefix *) p);
2646 if (! rn)
2647 return;
2648
2649 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002650 {
2651 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2652 continue;
2653
2654 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2655 break;
2656 }
2657
paul718e3742002-12-13 20:15:29 +00002658 if (! rib)
2659 {
2660 route_unlock_node (rn);
2661 return;
2662 }
2663
2664 /* Lookup nexthop. */
2665 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2666 if (static_ipv6_nexthop_same (nexthop, si))
2667 break;
2668
2669 /* Can't find nexthop. */
2670 if (! nexthop)
2671 {
2672 route_unlock_node (rn);
2673 return;
2674 }
2675
2676 /* Check nexthop. */
2677 if (rib->nexthop_num == 1)
2678 {
2679 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002680 }
2681 else
2682 {
paul6baeb982003-10-28 03:47:15 +00002683 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2684 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002685 nexthop_delete (rib, nexthop);
2686 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002687 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002688 }
paul718e3742002-12-13 20:15:29 +00002689 /* Unlock node. */
2690 route_unlock_node (rn);
2691}
2692
2693/* Add static route into static route configuration. */
2694int
2695static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002696 const char *ifname, u_char flags, u_char distance,
2697 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002698{
2699 struct route_node *rn;
2700 struct static_ipv6 *si;
2701 struct static_ipv6 *pp;
2702 struct static_ipv6 *cp;
2703 struct route_table *stable;
2704
2705 /* Lookup table. */
2706 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2707 if (! stable)
2708 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00002709
2710 if (!gate &&
2711 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
2712 return -1;
2713
2714 if (!ifname &&
2715 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
2716 return -1;
paul718e3742002-12-13 20:15:29 +00002717
2718 /* Lookup static route prefix. */
2719 rn = route_node_get (stable, p);
2720
2721 /* Do nothing if there is a same static route. */
2722 for (si = rn->info; si; si = si->next)
2723 {
2724 if (distance == si->distance
2725 && type == si->type
2726 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2727 && (! ifname || strcmp (ifname, si->ifname) == 0))
2728 {
2729 route_unlock_node (rn);
2730 return 0;
2731 }
2732 }
2733
2734 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002735 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
paul718e3742002-12-13 20:15:29 +00002736
2737 si->type = type;
2738 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002739 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002740
2741 switch (type)
2742 {
2743 case STATIC_IPV6_GATEWAY:
2744 si->ipv6 = *gate;
2745 break;
2746 case STATIC_IPV6_IFNAME:
2747 si->ifname = XSTRDUP (0, ifname);
2748 break;
2749 case STATIC_IPV6_GATEWAY_IFNAME:
2750 si->ipv6 = *gate;
2751 si->ifname = XSTRDUP (0, ifname);
2752 break;
2753 }
2754
2755 /* Add new static route information to the tree with sort by
2756 distance value and gateway address. */
2757 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2758 {
2759 if (si->distance < cp->distance)
2760 break;
2761 if (si->distance > cp->distance)
2762 continue;
2763 }
2764
2765 /* Make linked list. */
2766 if (pp)
2767 pp->next = si;
2768 else
2769 rn->info = si;
2770 if (cp)
2771 cp->prev = si;
2772 si->prev = pp;
2773 si->next = cp;
2774
2775 /* Install into rib. */
2776 static_install_ipv6 (p, si);
2777
2778 return 1;
2779}
2780
2781/* Delete static route from static route configuration. */
2782int
2783static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002784 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002785{
2786 struct route_node *rn;
2787 struct static_ipv6 *si;
2788 struct route_table *stable;
2789
2790 /* Lookup table. */
2791 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2792 if (! stable)
2793 return -1;
2794
2795 /* Lookup static route prefix. */
2796 rn = route_node_lookup (stable, p);
2797 if (! rn)
2798 return 0;
2799
2800 /* Find same static route is the tree */
2801 for (si = rn->info; si; si = si->next)
2802 if (distance == si->distance
2803 && type == si->type
2804 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2805 && (! ifname || strcmp (ifname, si->ifname) == 0))
2806 break;
2807
2808 /* Can't find static route. */
2809 if (! si)
2810 {
2811 route_unlock_node (rn);
2812 return 0;
2813 }
2814
2815 /* Install into rib. */
2816 static_uninstall_ipv6 (p, si);
2817
2818 /* Unlink static route from linked list. */
2819 if (si->prev)
2820 si->prev->next = si->next;
2821 else
2822 rn->info = si->next;
2823 if (si->next)
2824 si->next->prev = si->prev;
2825
2826 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002827 if (ifname)
2828 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00002829 XFREE (MTYPE_STATIC_IPV6, si);
2830
2831 return 1;
2832}
2833#endif /* HAVE_IPV6 */
2834
2835/* RIB update function. */
2836void
paula1ac18c2005-06-28 17:17:12 +00002837rib_update (void)
paul718e3742002-12-13 20:15:29 +00002838{
2839 struct route_node *rn;
2840 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00002841
paul718e3742002-12-13 20:15:29 +00002842 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2843 if (table)
2844 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002845 if (rn->info)
Paul Jakma6d691122006-07-27 21:49:00 +00002846 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002847
2848 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2849 if (table)
2850 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002851 if (rn->info)
Paul Jakma6d691122006-07-27 21:49:00 +00002852 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002853}
2854
2855/* Interface goes up. */
paula1ac18c2005-06-28 17:17:12 +00002856static void
paul718e3742002-12-13 20:15:29 +00002857rib_if_up (struct interface *ifp)
2858{
2859 rib_update ();
2860}
2861
2862/* Interface goes down. */
paula1ac18c2005-06-28 17:17:12 +00002863static void
paul718e3742002-12-13 20:15:29 +00002864rib_if_down (struct interface *ifp)
2865{
2866 rib_update ();
2867}
2868
2869/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00002870static void
paul718e3742002-12-13 20:15:29 +00002871rib_weed_table (struct route_table *table)
2872{
2873 struct route_node *rn;
2874 struct rib *rib;
2875 struct rib *next;
2876
2877 if (table)
2878 for (rn = route_top (table); rn; rn = route_next (rn))
2879 for (rib = rn->info; rib; rib = next)
2880 {
2881 next = rib->next;
2882
Paul Jakma6d691122006-07-27 21:49:00 +00002883 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2884 continue;
2885
paulb21b19c2003-06-15 01:28:29 +00002886 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00002887 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00002888 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002889 }
2890}
2891
2892/* Delete all routes from non main table. */
2893void
paula1ac18c2005-06-28 17:17:12 +00002894rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00002895{
2896 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2897 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2898}
2899
2900/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00002901static void
paul718e3742002-12-13 20:15:29 +00002902rib_sweep_table (struct route_table *table)
2903{
2904 struct route_node *rn;
2905 struct rib *rib;
2906 struct rib *next;
2907 int ret = 0;
2908
2909 if (table)
2910 for (rn = route_top (table); rn; rn = route_next (rn))
2911 for (rib = rn->info; rib; rib = next)
2912 {
2913 next = rib->next;
2914
Paul Jakma6d691122006-07-27 21:49:00 +00002915 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2916 continue;
2917
paul718e3742002-12-13 20:15:29 +00002918 if (rib->type == ZEBRA_ROUTE_KERNEL &&
2919 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
2920 {
2921 ret = rib_uninstall_kernel (rn, rib);
2922 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00002923 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002924 }
2925 }
2926}
2927
2928/* Sweep all RIB tables. */
2929void
paula1ac18c2005-06-28 17:17:12 +00002930rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00002931{
2932 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2933 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2934}
2935
2936/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00002937static void
paul718e3742002-12-13 20:15:29 +00002938rib_close_table (struct route_table *table)
2939{
2940 struct route_node *rn;
2941 struct rib *rib;
2942
2943 if (table)
2944 for (rn = route_top (table); rn; rn = route_next (rn))
2945 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002946 {
2947 if (! RIB_SYSTEM_ROUTE (rib)
2948 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2949 rib_uninstall_kernel (rn, rib);
2950 }
paul718e3742002-12-13 20:15:29 +00002951}
2952
2953/* Close all RIB tables. */
2954void
paula1ac18c2005-06-28 17:17:12 +00002955rib_close (void)
paul718e3742002-12-13 20:15:29 +00002956{
2957 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2958 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2959}
2960
2961/* Routing information base initialize. */
2962void
paula1ac18c2005-06-28 17:17:12 +00002963rib_init (void)
paul718e3742002-12-13 20:15:29 +00002964{
paul4d38fdb2005-04-28 17:35:14 +00002965 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00002966 /* VRF initialization. */
2967 vrf_init ();
2968}