blob: c88264ba19c69fc7c20e13cb0a420e8b65236d00 [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
212 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
213 memset (nexthop, 0, sizeof (struct nexthop));
214 nexthop->type = NEXTHOP_TYPE_IFINDEX;
215 nexthop->ifindex = ifindex;
216
217 nexthop_add (rib, nexthop);
218
219 return nexthop;
220}
221
222struct nexthop *
223nexthop_ifname_add (struct rib *rib, char *ifname)
224{
225 struct nexthop *nexthop;
226
227 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
228 memset (nexthop, 0, sizeof (struct nexthop));
229 nexthop->type = NEXTHOP_TYPE_IFNAME;
paula4b70762003-05-16 17:19:48 +0000230 nexthop->ifname = XSTRDUP (0, ifname);
paul718e3742002-12-13 20:15:29 +0000231
232 nexthop_add (rib, nexthop);
233
234 return nexthop;
235}
236
237struct nexthop *
Paul Jakma7514fb72007-05-02 16:05:35 +0000238nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src)
paul718e3742002-12-13 20:15:29 +0000239{
240 struct nexthop *nexthop;
241
242 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
243 memset (nexthop, 0, sizeof (struct nexthop));
244 nexthop->type = NEXTHOP_TYPE_IPV4;
245 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000246 if (src)
247 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000248
249 nexthop_add (rib, nexthop);
250
251 return nexthop;
252}
253
paula1ac18c2005-06-28 17:17:12 +0000254static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000255nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
Paul Jakma7514fb72007-05-02 16:05:35 +0000256 struct in_addr *src, unsigned int ifindex)
paul718e3742002-12-13 20:15:29 +0000257{
258 struct nexthop *nexthop;
259
260 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
261 memset (nexthop, 0, sizeof (struct nexthop));
262 nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
263 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000264 if (src)
265 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000266 nexthop->ifindex = ifindex;
267
268 nexthop_add (rib, nexthop);
269
270 return nexthop;
271}
272
273#ifdef HAVE_IPV6
274struct nexthop *
275nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
276{
277 struct nexthop *nexthop;
278
279 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
280 memset (nexthop, 0, sizeof (struct nexthop));
281 nexthop->type = NEXTHOP_TYPE_IPV6;
282 nexthop->gate.ipv6 = *ipv6;
283
284 nexthop_add (rib, nexthop);
285
286 return nexthop;
287}
288
paula1ac18c2005-06-28 17:17:12 +0000289static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000290nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
291 char *ifname)
292{
293 struct nexthop *nexthop;
294
295 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
296 memset (nexthop, 0, sizeof (struct nexthop));
297 nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
298 nexthop->gate.ipv6 = *ipv6;
299 nexthop->ifname = XSTRDUP (0, ifname);
300
301 nexthop_add (rib, nexthop);
302
303 return nexthop;
304}
305
paula1ac18c2005-06-28 17:17:12 +0000306static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000307nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
308 unsigned int ifindex)
309{
310 struct nexthop *nexthop;
311
312 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
313 memset (nexthop, 0, sizeof (struct nexthop));
314 nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
315 nexthop->gate.ipv6 = *ipv6;
316 nexthop->ifindex = ifindex;
317
318 nexthop_add (rib, nexthop);
319
320 return nexthop;
321}
322#endif /* HAVE_IPV6 */
323
paul595db7f2003-05-25 21:35:06 +0000324struct nexthop *
325nexthop_blackhole_add (struct rib *rib)
326{
327 struct nexthop *nexthop;
328
329 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
330 memset (nexthop, 0, sizeof (struct nexthop));
331 nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
332 SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
333
334 nexthop_add (rib, nexthop);
335
336 return nexthop;
337}
338
paul718e3742002-12-13 20:15:29 +0000339/* If force flag is not set, do not modify falgs at all for uninstall
340 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000341static int
paul718e3742002-12-13 20:15:29 +0000342nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
343 struct route_node *top)
344{
345 struct prefix_ipv4 p;
346 struct route_table *table;
347 struct route_node *rn;
348 struct rib *match;
349 struct nexthop *newhop;
350
351 if (nexthop->type == NEXTHOP_TYPE_IPV4)
352 nexthop->ifindex = 0;
353
354 if (set)
355 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
356
357 /* Make lookup prefix. */
358 memset (&p, 0, sizeof (struct prefix_ipv4));
359 p.family = AF_INET;
360 p.prefixlen = IPV4_MAX_PREFIXLEN;
361 p.prefix = nexthop->gate.ipv4;
362
363 /* Lookup table. */
364 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
365 if (! table)
366 return 0;
367
368 rn = route_node_match (table, (struct prefix *) &p);
369 while (rn)
370 {
371 route_unlock_node (rn);
372
373 /* If lookup self prefix return immidiately. */
374 if (rn == top)
375 return 0;
376
377 /* Pick up selected route. */
378 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100379 {
380 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
381 continue;
382 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
383 break;
384 }
paul718e3742002-12-13 20:15:29 +0000385
386 /* If there is no selected route or matched route is EGP, go up
387 tree. */
388 if (! match
389 || match->type == ZEBRA_ROUTE_BGP)
390 {
391 do {
392 rn = rn->parent;
393 } while (rn && rn->info == NULL);
394 if (rn)
395 route_lock_node (rn);
396 }
397 else
398 {
399 if (match->type == ZEBRA_ROUTE_CONNECT)
400 {
401 /* Directly point connected route. */
402 newhop = match->nexthop;
403 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
404 nexthop->ifindex = newhop->ifindex;
405
406 return 1;
407 }
408 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
409 {
410 for (newhop = match->nexthop; newhop; newhop = newhop->next)
411 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
412 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
413 {
414 if (set)
415 {
416 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
417 nexthop->rtype = newhop->type;
418 if (newhop->type == NEXTHOP_TYPE_IPV4 ||
419 newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
420 nexthop->rgate.ipv4 = newhop->gate.ipv4;
421 if (newhop->type == NEXTHOP_TYPE_IFINDEX
422 || newhop->type == NEXTHOP_TYPE_IFNAME
423 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
424 nexthop->rifindex = newhop->ifindex;
425 }
426 return 1;
427 }
428 return 0;
429 }
430 else
431 {
432 return 0;
433 }
434 }
435 }
436 return 0;
437}
438
439#ifdef HAVE_IPV6
440/* If force flag is not set, do not modify falgs at all for uninstall
441 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000442static int
paul718e3742002-12-13 20:15:29 +0000443nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
444 struct route_node *top)
445{
446 struct prefix_ipv6 p;
447 struct route_table *table;
448 struct route_node *rn;
449 struct rib *match;
450 struct nexthop *newhop;
451
452 if (nexthop->type == NEXTHOP_TYPE_IPV6)
453 nexthop->ifindex = 0;
454
455 if (set)
456 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
457
458 /* Make lookup prefix. */
459 memset (&p, 0, sizeof (struct prefix_ipv6));
460 p.family = AF_INET6;
461 p.prefixlen = IPV6_MAX_PREFIXLEN;
462 p.prefix = nexthop->gate.ipv6;
463
464 /* Lookup table. */
465 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
466 if (! table)
467 return 0;
468
469 rn = route_node_match (table, (struct prefix *) &p);
470 while (rn)
471 {
472 route_unlock_node (rn);
473
474 /* If lookup self prefix return immidiately. */
475 if (rn == top)
476 return 0;
477
478 /* Pick up selected route. */
479 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100480 {
481 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
482 continue;
483 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
484 break;
485 }
paul718e3742002-12-13 20:15:29 +0000486
487 /* If there is no selected route or matched route is EGP, go up
488 tree. */
489 if (! match
490 || match->type == ZEBRA_ROUTE_BGP)
491 {
492 do {
493 rn = rn->parent;
494 } while (rn && rn->info == NULL);
495 if (rn)
496 route_lock_node (rn);
497 }
498 else
499 {
500 if (match->type == ZEBRA_ROUTE_CONNECT)
501 {
502 /* Directly point connected route. */
503 newhop = match->nexthop;
504
505 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
506 nexthop->ifindex = newhop->ifindex;
507
508 return 1;
509 }
510 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
511 {
512 for (newhop = match->nexthop; newhop; newhop = newhop->next)
513 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
514 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
515 {
516 if (set)
517 {
518 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
519 nexthop->rtype = newhop->type;
520 if (newhop->type == NEXTHOP_TYPE_IPV6
521 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
522 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
523 nexthop->rgate.ipv6 = newhop->gate.ipv6;
524 if (newhop->type == NEXTHOP_TYPE_IFINDEX
525 || newhop->type == NEXTHOP_TYPE_IFNAME
526 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
527 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
528 nexthop->rifindex = newhop->ifindex;
529 }
530 return 1;
531 }
532 return 0;
533 }
534 else
535 {
536 return 0;
537 }
538 }
539 }
540 return 0;
541}
542#endif /* HAVE_IPV6 */
543
544struct rib *
545rib_match_ipv4 (struct in_addr addr)
546{
547 struct prefix_ipv4 p;
548 struct route_table *table;
549 struct route_node *rn;
550 struct rib *match;
551 struct nexthop *newhop;
552
553 /* Lookup table. */
554 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
555 if (! table)
556 return 0;
557
558 memset (&p, 0, sizeof (struct prefix_ipv4));
559 p.family = AF_INET;
560 p.prefixlen = IPV4_MAX_PREFIXLEN;
561 p.prefix = addr;
562
563 rn = route_node_match (table, (struct prefix *) &p);
564
565 while (rn)
566 {
567 route_unlock_node (rn);
568
569 /* Pick up selected route. */
570 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100571 {
572 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
573 continue;
574 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
575 break;
576 }
paul718e3742002-12-13 20:15:29 +0000577
578 /* If there is no selected route or matched route is EGP, go up
579 tree. */
580 if (! match
581 || match->type == ZEBRA_ROUTE_BGP)
582 {
583 do {
584 rn = rn->parent;
585 } while (rn && rn->info == NULL);
586 if (rn)
587 route_lock_node (rn);
588 }
589 else
590 {
591 if (match->type == ZEBRA_ROUTE_CONNECT)
592 /* Directly point connected route. */
593 return match;
594 else
595 {
596 for (newhop = match->nexthop; newhop; newhop = newhop->next)
597 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
598 return match;
599 return NULL;
600 }
601 }
602 }
603 return NULL;
604}
605
606struct rib *
607rib_lookup_ipv4 (struct prefix_ipv4 *p)
608{
609 struct route_table *table;
610 struct route_node *rn;
611 struct rib *match;
612 struct nexthop *nexthop;
613
614 /* Lookup table. */
615 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
616 if (! table)
617 return 0;
618
619 rn = route_node_lookup (table, (struct prefix *) p);
620
621 /* No route for this prefix. */
622 if (! rn)
623 return NULL;
624
625 /* Unlock node. */
626 route_unlock_node (rn);
627
paul718e3742002-12-13 20:15:29 +0000628 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100629 {
630 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
631 continue;
632 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
633 break;
634 }
paul718e3742002-12-13 20:15:29 +0000635
636 if (! match || match->type == ZEBRA_ROUTE_BGP)
637 return NULL;
638
639 if (match->type == ZEBRA_ROUTE_CONNECT)
640 return match;
641
642 for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
643 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
644 return match;
645
646 return NULL;
647}
648
Denis Ovsienkodc958242007-08-13 16:03:06 +0000649/*
650 * This clone function, unlike its original rib_lookup_ipv4(), checks
651 * if specified IPv4 route record (prefix/mask -> gate) exists in
652 * the whole RIB and has ZEBRA_FLAG_SELECTED set.
653 *
654 * Return values:
655 * -1: error
656 * 0: exact match found
657 * 1: a match was found with a different gate
658 * 2: connected route found
659 * 3: no matches found
660 */
661int
662rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
663{
664 struct route_table *table;
665 struct route_node *rn;
666 struct rib *match;
667 struct nexthop *nexthop;
668
669 /* Lookup table. */
670 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
671 if (! table)
672 return ZEBRA_RIB_LOOKUP_ERROR;
673
674 /* Scan the RIB table for exactly matching RIB entry. */
675 rn = route_node_lookup (table, (struct prefix *) p);
676
677 /* No route for this prefix. */
678 if (! rn)
679 return ZEBRA_RIB_NOTFOUND;
680
681 /* Unlock node. */
682 route_unlock_node (rn);
683
684 /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
685 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100686 {
687 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
688 continue;
689 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
690 break;
691 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000692
693 /* None such found :( */
694 if (!match)
695 return ZEBRA_RIB_NOTFOUND;
696
697 if (match->type == ZEBRA_ROUTE_CONNECT)
698 return ZEBRA_RIB_FOUND_CONNECTED;
699
700 /* Ok, we have a cood candidate, let's check it's nexthop list... */
701 for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
702 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
703 {
704 /* We are happy with either direct or recursive hexthop */
705 if (nexthop->gate.ipv4.s_addr == qgate->sin.sin_addr.s_addr ||
706 nexthop->rgate.ipv4.s_addr == qgate->sin.sin_addr.s_addr)
707 return ZEBRA_RIB_FOUND_EXACT;
708 else
709 {
710 if (IS_ZEBRA_DEBUG_RIB)
711 {
712 char gate_buf[INET_ADDRSTRLEN], rgate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
713 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
714 inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, rgate_buf, INET_ADDRSTRLEN);
715 inet_ntop (AF_INET, &qgate->sin.sin_addr.s_addr, qgate_buf, INET_ADDRSTRLEN);
716 zlog_debug ("%s: qgate == %s, gate == %s, rgate == %s", __func__, qgate_buf, gate_buf, rgate_buf);
717 }
718 return ZEBRA_RIB_FOUND_NOGATE;
719 }
720 }
721
722 return ZEBRA_RIB_NOTFOUND;
723}
724
paul718e3742002-12-13 20:15:29 +0000725#ifdef HAVE_IPV6
726struct rib *
727rib_match_ipv6 (struct in6_addr *addr)
728{
729 struct prefix_ipv6 p;
730 struct route_table *table;
731 struct route_node *rn;
732 struct rib *match;
733 struct nexthop *newhop;
734
735 /* Lookup table. */
736 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
737 if (! table)
738 return 0;
739
740 memset (&p, 0, sizeof (struct prefix_ipv6));
741 p.family = AF_INET6;
742 p.prefixlen = IPV6_MAX_PREFIXLEN;
743 IPV6_ADDR_COPY (&p.prefix, addr);
744
745 rn = route_node_match (table, (struct prefix *) &p);
746
747 while (rn)
748 {
749 route_unlock_node (rn);
750
751 /* Pick up selected route. */
752 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100753 {
754 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
755 continue;
756 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
757 break;
758 }
paul718e3742002-12-13 20:15:29 +0000759
760 /* If there is no selected route or matched route is EGP, go up
761 tree. */
762 if (! match
763 || match->type == ZEBRA_ROUTE_BGP)
764 {
765 do {
766 rn = rn->parent;
767 } while (rn && rn->info == NULL);
768 if (rn)
769 route_lock_node (rn);
770 }
771 else
772 {
773 if (match->type == ZEBRA_ROUTE_CONNECT)
774 /* Directly point connected route. */
775 return match;
776 else
777 {
778 for (newhop = match->nexthop; newhop; newhop = newhop->next)
779 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
780 return match;
781 return NULL;
782 }
783 }
784 }
785 return NULL;
786}
787#endif /* HAVE_IPV6 */
788
Paul Jakma7514fb72007-05-02 16:05:35 +0000789#define RIB_SYSTEM_ROUTE(R) \
790 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
791
Denis Ovsienkodc958242007-08-13 16:03:06 +0000792/* This function verifies reachability of one given nexthop, which can be
793 * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
794 * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
795 * nexthop->ifindex will be updated appropriately as well.
796 * An existing route map can turn (otherwise active) nexthop into inactive, but
797 * not vice versa.
798 *
799 * The return value is the final value of 'ACTIVE' flag.
800 */
801
paula1ac18c2005-06-28 17:17:12 +0000802static int
paul718e3742002-12-13 20:15:29 +0000803nexthop_active_check (struct route_node *rn, struct rib *rib,
804 struct nexthop *nexthop, int set)
805{
806 struct interface *ifp;
Paul Jakma7514fb72007-05-02 16:05:35 +0000807 route_map_result_t ret = RMAP_MATCH;
808 extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
809 struct route_map *rmap;
810 int family;
paul718e3742002-12-13 20:15:29 +0000811
Paul Jakma7514fb72007-05-02 16:05:35 +0000812 family = 0;
paul718e3742002-12-13 20:15:29 +0000813 switch (nexthop->type)
814 {
815 case NEXTHOP_TYPE_IFINDEX:
816 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000817 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000818 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
819 else
820 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
821 break;
paul718e3742002-12-13 20:15:29 +0000822 case NEXTHOP_TYPE_IPV6_IFNAME:
Paul Jakma7514fb72007-05-02 16:05:35 +0000823 family = AFI_IP6;
824 case NEXTHOP_TYPE_IFNAME:
paul718e3742002-12-13 20:15:29 +0000825 ifp = if_lookup_by_name (nexthop->ifname);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000826 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000827 {
828 if (set)
829 nexthop->ifindex = ifp->ifindex;
830 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
831 }
832 else
833 {
834 if (set)
835 nexthop->ifindex = 0;
836 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
837 }
838 break;
839 case NEXTHOP_TYPE_IPV4:
840 case NEXTHOP_TYPE_IPV4_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000841 family = AFI_IP;
paul718e3742002-12-13 20:15:29 +0000842 if (nexthop_active_ipv4 (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#ifdef HAVE_IPV6
848 case NEXTHOP_TYPE_IPV6:
Paul Jakma7514fb72007-05-02 16:05:35 +0000849 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000850 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
851 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
852 else
853 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
854 break;
855 case NEXTHOP_TYPE_IPV6_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000856 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000857 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
858 {
859 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000860 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000861 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
862 else
863 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
864 }
865 else
866 {
867 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
868 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
869 else
870 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
871 }
872 break;
873#endif /* HAVE_IPV6 */
paul595db7f2003-05-25 21:35:06 +0000874 case NEXTHOP_TYPE_BLACKHOLE:
875 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
876 break;
paul718e3742002-12-13 20:15:29 +0000877 default:
878 break;
879 }
Paul Jakma7514fb72007-05-02 16:05:35 +0000880 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
881 return 0;
882
883 if (RIB_SYSTEM_ROUTE(rib) ||
884 (family == AFI_IP && rn->p.family != AF_INET) ||
885 (family == AFI_IP6 && rn->p.family != AF_INET6))
886 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
887
888 rmap = 0;
889 if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
890 proto_rm[family][rib->type])
891 rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
892 if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
893 rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
894 if (rmap) {
895 ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, nexthop);
896 }
897
898 if (ret == RMAP_DENYMATCH)
899 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
paul718e3742002-12-13 20:15:29 +0000900 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
901}
902
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000903/* Iterate over all nexthops of the given RIB entry and refresh their
904 * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
905 * nexthop is found to toggle the ACTIVE flag, the whole rib structure
906 * is flagged with ZEBRA_FLAG_CHANGED. The 4th 'set' argument is
907 * transparently passed to nexthop_active_check().
908 *
909 * Return value is the new number of active nexthops.
910 */
911
paula1ac18c2005-06-28 17:17:12 +0000912static int
paul718e3742002-12-13 20:15:29 +0000913nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
914{
915 struct nexthop *nexthop;
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000916 int prev_active, new_active;
paul718e3742002-12-13 20:15:29 +0000917
918 rib->nexthop_active_num = 0;
919 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
920
921 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000922 {
923 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
924 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
925 rib->nexthop_active_num++;
926 if (prev_active != new_active)
927 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
928 }
paul718e3742002-12-13 20:15:29 +0000929 return rib->nexthop_active_num;
930}
paul6baeb982003-10-28 03:47:15 +0000931
paul718e3742002-12-13 20:15:29 +0000932
paul718e3742002-12-13 20:15:29 +0000933
paula1ac18c2005-06-28 17:17:12 +0000934static void
paul718e3742002-12-13 20:15:29 +0000935rib_install_kernel (struct route_node *rn, struct rib *rib)
936{
937 int ret = 0;
938 struct nexthop *nexthop;
939
940 switch (PREFIX_FAMILY (&rn->p))
941 {
942 case AF_INET:
943 ret = kernel_add_ipv4 (&rn->p, rib);
944 break;
945#ifdef HAVE_IPV6
946 case AF_INET6:
947 ret = kernel_add_ipv6 (&rn->p, rib);
948 break;
949#endif /* HAVE_IPV6 */
950 }
951
Denis Ovsienkodc958242007-08-13 16:03:06 +0000952 /* This condition is never met, if we are using rt_socket.c */
paul718e3742002-12-13 20:15:29 +0000953 if (ret < 0)
954 {
955 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
956 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
957 }
958}
959
960/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +0000961static int
paul718e3742002-12-13 20:15:29 +0000962rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
963{
964 int ret = 0;
965 struct nexthop *nexthop;
966
967 switch (PREFIX_FAMILY (&rn->p))
968 {
969 case AF_INET:
970 ret = kernel_delete_ipv4 (&rn->p, rib);
971 break;
972#ifdef HAVE_IPV6
973 case AF_INET6:
Denis Ovsienkodc958242007-08-13 16:03:06 +0000974 if (IS_ZEBRA_DEBUG_RIB)
975 zlog_debug ("%s: calling kernel_delete_ipv4 (%p, %p)", __func__, rn, rib);
paul718e3742002-12-13 20:15:29 +0000976 ret = kernel_delete_ipv6 (&rn->p, rib);
977 break;
978#endif /* HAVE_IPV6 */
979 }
980
981 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
982 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
983
984 return ret;
985}
986
987/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +0000988static void
paul718e3742002-12-13 20:15:29 +0000989rib_uninstall (struct route_node *rn, struct rib *rib)
990{
991 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
992 {
993 redistribute_delete (&rn->p, rib);
994 if (! RIB_SYSTEM_ROUTE (rib))
995 rib_uninstall_kernel (rn, rib);
996 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
997 }
998}
999
Paul Jakma6d691122006-07-27 21:49:00 +00001000static void rib_unlink (struct route_node *, struct rib *);
1001
paul718e3742002-12-13 20:15:29 +00001002/* Core function for processing routing information base. */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001003static void
1004rib_process (struct route_node *rn)
paul718e3742002-12-13 20:15:29 +00001005{
1006 struct rib *rib;
1007 struct rib *next;
1008 struct rib *fib = NULL;
1009 struct rib *select = NULL;
Paul Jakma6d691122006-07-27 21:49:00 +00001010 struct rib *del = NULL;
pauld753e9e2003-01-22 19:45:50 +00001011 int installed = 0;
1012 struct nexthop *nexthop = NULL;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001013 char buf[INET6_ADDRSTRLEN];
paul4d38fdb2005-04-28 17:35:14 +00001014
1015 assert (rn);
1016
Paul Jakma93bdada2007-08-06 19:25:11 +00001017 if (IS_ZEBRA_DEBUG_RIB || IS_ZEBRA_DEBUG_RIB_Q)
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001018 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001019
paul718e3742002-12-13 20:15:29 +00001020 for (rib = rn->info; rib; rib = next)
1021 {
Denis Ovsienkodc958242007-08-13 16:03:06 +00001022 /* The next pointer is saved, because current pointer
1023 * may be passed to rib_unlink() in the middle of iteration.
1024 */
paul718e3742002-12-13 20:15:29 +00001025 next = rib->next;
pauld753e9e2003-01-22 19:45:50 +00001026
paul718e3742002-12-13 20:15:29 +00001027 /* Currently installed rib. */
1028 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Paul Jakma6d691122006-07-27 21:49:00 +00001029 {
1030 assert (fib == NULL);
1031 fib = rib;
1032 }
1033
1034 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1035 * which we need to do do further work with below.
1036 */
1037 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1038 {
1039 if (rib != fib)
1040 {
1041 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001042 zlog_debug ("%s: %s/%d: rn %p, removing rib %p", __func__,
1043 buf, rn->p.prefixlen, rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001044 rib_unlink (rn, rib);
1045 }
1046 else
1047 del = rib;
1048
1049 continue;
1050 }
paul4d38fdb2005-04-28 17:35:14 +00001051
paul718e3742002-12-13 20:15:29 +00001052 /* Skip unreachable nexthop. */
1053 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +00001054 continue;
paul718e3742002-12-13 20:15:29 +00001055
1056 /* Infinit distance. */
1057 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +00001058 continue;
paul718e3742002-12-13 20:15:29 +00001059
paulaf887b52006-01-18 14:52:52 +00001060 /* Newly selected rib, the common case. */
1061 if (!select)
1062 {
1063 select = rib;
1064 continue;
1065 }
1066
1067 /* filter route selection in following order:
paulaf887b52006-01-18 14:52:52 +00001068 * - connected beats other types
paula8d9c1f2006-01-25 06:31:04 +00001069 * - lower distance beats higher
paulaf887b52006-01-18 14:52:52 +00001070 * - lower metric beats higher for equal distance
1071 * - last, hence oldest, route wins tie break.
1072 */
paula1038a12006-01-30 14:08:51 +00001073
1074 /* Connected routes. Pick the last connected
1075 * route of the set of lowest metric connected routes.
1076 */
paula8d9c1f2006-01-25 06:31:04 +00001077 if (rib->type == ZEBRA_ROUTE_CONNECT)
1078 {
paula1038a12006-01-30 14:08:51 +00001079 if (select->type != ZEBRA_ROUTE_CONNECT
paula8d9c1f2006-01-25 06:31:04 +00001080 || rib->metric <= select->metric)
paula1038a12006-01-30 14:08:51 +00001081 select = rib;
1082 continue;
paula8d9c1f2006-01-25 06:31:04 +00001083 }
1084 else if (select->type == ZEBRA_ROUTE_CONNECT)
1085 continue;
1086
1087 /* higher distance loses */
1088 if (rib->distance > select->distance)
1089 continue;
1090
1091 /* lower wins */
1092 if (rib->distance < select->distance)
1093 {
paulaf887b52006-01-18 14:52:52 +00001094 select = rib;
paula8d9c1f2006-01-25 06:31:04 +00001095 continue;
1096 }
1097
1098 /* metric tie-breaks equal distance */
1099 if (rib->metric <= select->metric)
1100 select = rib;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001101 } /* for (rib = rn->info; rib; rib = next) */
1102
1103 /* After the cycle is finished, the following pointers will be set:
1104 * select --- the winner RIB entry, if any was found, otherwise NULL
1105 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1106 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1107 * rib --- NULL
1108 */
1109
1110 /* Same RIB entry is selected. Update FIB and finish. */
paul718e3742002-12-13 20:15:29 +00001111 if (select && select == fib)
1112 {
Paul Jakma6d691122006-07-27 21:49:00 +00001113 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001114 zlog_debug ("%s: %s/%d: Updating existing route, select %p, fib %p",
1115 __func__, buf, rn->p.prefixlen, select, fib);
paul718e3742002-12-13 20:15:29 +00001116 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +00001117 {
1118 redistribute_delete (&rn->p, select);
1119 if (! RIB_SYSTEM_ROUTE (select))
1120 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001121
paul4d38fdb2005-04-28 17:35:14 +00001122 /* Set real nexthop. */
1123 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +00001124
paul4d38fdb2005-04-28 17:35:14 +00001125 if (! RIB_SYSTEM_ROUTE (select))
1126 rib_install_kernel (rn, select);
1127 redistribute_add (&rn->p, select);
1128 }
pauld753e9e2003-01-22 19:45:50 +00001129 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001130 {
1131 /* Housekeeping code to deal with
1132 race conditions in kernel with linux
1133 netlink reporting interface up before IPv4 or IPv6 protocol
1134 is ready to add routes.
1135 This makes sure the routes are IN the kernel.
1136 */
pauld753e9e2003-01-22 19:45:50 +00001137
paul4d38fdb2005-04-28 17:35:14 +00001138 for (nexthop = select->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001139 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
paul4d38fdb2005-04-28 17:35:14 +00001140 {
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001141 installed = 1;
1142 break;
paul4d38fdb2005-04-28 17:35:14 +00001143 }
1144 if (! installed)
1145 rib_install_kernel (rn, select);
1146 }
Paul Jakma6d691122006-07-27 21:49:00 +00001147 goto end;
paul718e3742002-12-13 20:15:29 +00001148 }
1149
Denis Ovsienkodc958242007-08-13 16:03:06 +00001150 /* At this point we either haven't found the best RIB entry or it is
1151 * different from what we currently intend to flag with SELECTED. In both
1152 * cases, if a RIB block is present in FIB, it should be withdrawn.
1153 */
paul718e3742002-12-13 20:15:29 +00001154 if (fib)
1155 {
Paul Jakma6d691122006-07-27 21:49:00 +00001156 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001157 zlog_debug ("%s: %s/%d: Removing existing route, fib %p", __func__,
1158 buf, rn->p.prefixlen, fib);
paul718e3742002-12-13 20:15:29 +00001159 redistribute_delete (&rn->p, fib);
1160 if (! RIB_SYSTEM_ROUTE (fib))
1161 rib_uninstall_kernel (rn, fib);
1162 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1163
1164 /* Set real nexthop. */
1165 nexthop_active_update (rn, fib, 1);
1166 }
1167
Denis Ovsienkodc958242007-08-13 16:03:06 +00001168 /* Regardless of some RIB entry being SELECTED or not before, now we can
1169 * tell, that if a new winner exists, FIB is still not updated with this
1170 * data, but ready to be.
1171 */
paul718e3742002-12-13 20:15:29 +00001172 if (select)
1173 {
Paul Jakma6d691122006-07-27 21:49:00 +00001174 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001175 zlog_debug ("%s: %s/%d: Adding route, select %p", __func__, buf,
1176 rn->p.prefixlen, select);
paul718e3742002-12-13 20:15:29 +00001177 /* Set real nexthop. */
1178 nexthop_active_update (rn, select, 1);
1179
1180 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001181 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001182 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1183 redistribute_add (&rn->p, select);
1184 }
paul4d38fdb2005-04-28 17:35:14 +00001185
Paul Jakma6d691122006-07-27 21:49:00 +00001186 /* FIB route was removed, should be deleted */
1187 if (del)
1188 {
1189 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001190 zlog_debug ("%s: %s/%d: Deleting fib %p, rn %p", __func__, buf,
1191 rn->p.prefixlen, del, rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001192 rib_unlink (rn, del);
1193 }
paul4d38fdb2005-04-28 17:35:14 +00001194
Paul Jakma6d691122006-07-27 21:49:00 +00001195end:
1196 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma93bdada2007-08-06 19:25:11 +00001197 zlog_debug ("%s: %s/%d: rn %p dequeued", __func__, buf, rn->p.prefixlen, rn);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001198}
1199
1200/* Take a list of route_node structs and return 1, if there was a record picked from
1201 * it and processed by rib_process(). Don't process more, than one RN record; operate
1202 * only in the specified sub-queue.
1203 */
1204unsigned int
1205process_subq (struct list * subq, u_char qindex)
1206{
1207 struct listnode *lnode;
1208 struct route_node *rnode;
1209 if (!(lnode = listhead (subq)))
1210 return 0;
1211 rnode = listgetdata (lnode);
1212 rib_process (rnode);
1213 if (rnode->info) /* The first RIB record is holding the flags bitmask. */
1214 UNSET_FLAG (((struct rib *)rnode->info)->rn_status, RIB_ROUTE_QUEUED(qindex));
1215 route_unlock_node (rnode);
1216 list_delete_node (subq, lnode);
1217 return 1;
1218}
1219
1220/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1221 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1222 * is pointed to the meta queue structure.
1223 */
1224static wq_item_status
1225meta_queue_process (struct work_queue *dummy, void *data)
1226{
1227 struct meta_queue * mq = data;
1228 u_char i;
1229 for (i = 0; i < MQ_SIZE; i++)
1230 if (process_subq (mq->subq[i], i))
1231 {
1232 mq->size--;
1233 break;
1234 }
1235 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1236}
1237
1238/* Look into the RN and queue it into one or more priority queues, increasing the size
1239 * for each data push done.
1240 */
1241void rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
1242{
1243 u_char qindex;
1244 struct rib *rib;
1245 char buf[INET6_ADDRSTRLEN];
1246 if (IS_ZEBRA_DEBUG_RIB_Q)
1247 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
1248 for (rib = rn->info; rib; rib = rib->next)
1249 {
1250 switch (rib->type)
1251 {
1252 case ZEBRA_ROUTE_KERNEL:
1253 case ZEBRA_ROUTE_CONNECT:
1254 qindex = 0;
1255 break;
1256 case ZEBRA_ROUTE_STATIC:
1257 qindex = 1;
1258 break;
1259 case ZEBRA_ROUTE_RIP:
1260 case ZEBRA_ROUTE_RIPNG:
1261 case ZEBRA_ROUTE_OSPF:
1262 case ZEBRA_ROUTE_OSPF6:
1263 case ZEBRA_ROUTE_ISIS:
1264 qindex = 2;
1265 break;
1266 case ZEBRA_ROUTE_BGP:
1267 qindex = 3;
1268 break;
1269 default:
1270 qindex = 4;
1271 break;
1272 }
1273 /* Invariant: at this point we always have rn->info set. */
1274 if (CHECK_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED(qindex)))
1275 {
1276 if (IS_ZEBRA_DEBUG_RIB_Q)
1277 zlog_debug ("%s: %s/%d: rn %p is already queued in sub-queue %u", __func__, buf, rn->p.prefixlen, rn, qindex);
1278 continue;
1279 }
1280 SET_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED(qindex));
1281 listnode_add (mq->subq[qindex], rn);
1282 route_lock_node (rn);
1283 mq->size++;
1284 if (IS_ZEBRA_DEBUG_RIB_Q)
1285 zlog_debug ("%s: %s/%d: queued rn %p into sub-queue %u", __func__, buf, rn->p.prefixlen, rn, qindex);
1286 }
paul4d38fdb2005-04-28 17:35:14 +00001287}
1288
Paul Jakma6d691122006-07-27 21:49:00 +00001289/* Add route_node to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001290static void
Paul Jakma6d691122006-07-27 21:49:00 +00001291rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
paul4d38fdb2005-04-28 17:35:14 +00001292{
Paul Jakma93bdada2007-08-06 19:25:11 +00001293 char buf[INET_ADDRSTRLEN];
Paul Jakma6d691122006-07-27 21:49:00 +00001294 assert (zebra && rn);
paul4d38fdb2005-04-28 17:35:14 +00001295
Paul Jakma93bdada2007-08-06 19:25:11 +00001296 if (IS_ZEBRA_DEBUG_RIB_Q)
1297 inet_ntop (AF_INET, &rn->p.u.prefix, buf, INET_ADDRSTRLEN);
1298
Paul Jakma6d691122006-07-27 21:49:00 +00001299 /* Pointless to queue a route_node with no RIB entries to add or remove */
1300 if (!rn->info)
1301 {
1302 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1303 __func__, rn, rn->lock);
1304 zlog_backtrace(LOG_DEBUG);
1305 return;
1306 }
paul4d38fdb2005-04-28 17:35:14 +00001307
Paul Jakma6d691122006-07-27 21:49:00 +00001308 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma93bdada2007-08-06 19:25:11 +00001309 zlog_info ("%s: %s/%d: work queue added", __func__, buf, rn->p.prefixlen);
Paul Jakma6d691122006-07-27 21:49:00 +00001310
1311 assert (zebra);
1312
paul4d38fdb2005-04-28 17:35:14 +00001313 if (zebra->ribq == NULL)
1314 {
Paul Jakma6d691122006-07-27 21:49:00 +00001315 zlog_err ("%s: work_queue does not exist!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001316 return;
1317 }
Paul Jakma6d691122006-07-27 21:49:00 +00001318
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001319 /* The RIB queue should normally be either empty or holding the only work_queue_item
1320 * element. In the latter case this element would hold a pointer to the meta queue
1321 * structure, which must be used to actually queue the route nodes to process. So
1322 * create the MQ holder, if necessary, then push the work into it in any case.
1323 * This semantics was introduced after 0.99.9 release.
1324 */
1325
1326 /* Should I invent work_queue_empty() and use it, or it's Ok to do as follows? */
1327 if (!zebra->ribq->items->count)
1328 work_queue_add (zebra->ribq, zebra->mq);
1329
1330 rib_meta_queue_add (zebra->mq, rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001331
1332 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma93bdada2007-08-06 19:25:11 +00001333 zlog_debug ("%s: %s/%d: rn %p queued", __func__, buf, rn->p.prefixlen, rn);
paul4d38fdb2005-04-28 17:35:14 +00001334
1335 return;
1336}
1337
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001338/* Create new meta queue. A destructor function doesn't seem to be necessary here. */
1339struct meta_queue *
1340meta_queue_new ()
1341{
1342 struct meta_queue *new;
1343 unsigned i, failed = 0;
1344
1345 if ((new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue))) == NULL)
1346 return NULL;
1347 for (i = 0; i < MQ_SIZE; i++)
1348 if ((new->subq[i] = list_new ()) == NULL)
1349 failed = 1;
1350 if (failed)
1351 {
1352 for (i = 0; i < MQ_SIZE; i++)
1353 if (new->subq[i])
1354 list_delete (new->subq[i]);
1355 XFREE (MTYPE_WORK_QUEUE, new);
1356 return NULL;
1357 }
1358 new->size = 0;
1359 return new;
1360}
1361
paul4d38fdb2005-04-28 17:35:14 +00001362/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001363static void
paul4d38fdb2005-04-28 17:35:14 +00001364rib_queue_init (struct zebra_t *zebra)
1365{
1366 assert (zebra);
1367
1368 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001369 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001370 {
Paul Jakma6d691122006-07-27 21:49:00 +00001371 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001372 return;
1373 }
1374
1375 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001376 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001377 zebra->ribq->spec.errorfunc = NULL;
paul4d38fdb2005-04-28 17:35:14 +00001378 /* XXX: TODO: These should be runtime configurable via vty */
1379 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001380 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001381
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001382 if (!(zebra->mq = meta_queue_new ()))
1383 {
1384 zlog_err ("%s: could not initialise meta queue!", __func__);
1385 return;
1386 }
paul4d38fdb2005-04-28 17:35:14 +00001387 return;
paul718e3742002-12-13 20:15:29 +00001388}
1389
Paul Jakma6d691122006-07-27 21:49:00 +00001390/* RIB updates are processed via a queue of pointers to route_nodes.
1391 *
1392 * The queue length is bounded by the maximal size of the routing table,
1393 * as a route_node will not be requeued, if already queued.
1394 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001395 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1396 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1397 * and then submit route_node to queue for best-path selection later.
1398 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001399 *
1400 * Deleted RIBs are reaped during best-path selection.
1401 *
1402 * rib_addnode
1403 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001404 * |-------->| | best RIB, if required
1405 * | |
1406 * static_install->|->rib_addqueue...... -> rib_process
1407 * | |
1408 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001409 * |-> set RIB_ENTRY_REMOVE |
1410 * rib_delnode (RIB freed)
1411 *
1412 *
1413 * Queueing state for a route_node is kept in the head RIB entry, this
1414 * state must be preserved as and when the head RIB entry of a
1415 * route_node is changed by rib_unlink / rib_link. A small complication,
1416 * but saves having to allocate a dedicated object for this.
1417 *
1418 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1419 *
1420 * - route_nodes: refcounted by:
1421 * - RIBs attached to route_node:
1422 * - managed by: rib_link/unlink
1423 * - route_node processing queue
1424 * - managed by: rib_addqueue, rib_process.
1425 *
1426 */
1427
paul718e3742002-12-13 20:15:29 +00001428/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001429static void
Paul Jakma6d691122006-07-27 21:49:00 +00001430rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001431{
1432 struct rib *head;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001433 char buf[INET6_ADDRSTRLEN];
paul4d38fdb2005-04-28 17:35:14 +00001434
1435 assert (rib && rn);
1436
Paul Jakma6d691122006-07-27 21:49:00 +00001437 route_lock_node (rn); /* rn route table reference */
1438
1439 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001440 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001441 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001442 zlog_debug ("%s: %s/%d: rn %p, rib %p", __func__,
1443 buf, rn->p.prefixlen, rn, rib);
1444 }
Paul Jakma6d691122006-07-27 21:49:00 +00001445
paul718e3742002-12-13 20:15:29 +00001446 head = rn->info;
1447 if (head)
Paul Jakma6d691122006-07-27 21:49:00 +00001448 {
1449 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001450 zlog_debug ("%s: %s/%d: new head, rn_status copied over", __func__,
1451 buf, rn->p.prefixlen);
Paul Jakma6d691122006-07-27 21:49:00 +00001452 head->prev = rib;
1453 /* Transfer the rn status flags to the new head RIB */
1454 rib->rn_status = head->rn_status;
1455 }
paul718e3742002-12-13 20:15:29 +00001456 rib->next = head;
1457 rn->info = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001458 rib_queue_add (&zebrad, rn);
1459}
1460
1461static void
1462rib_addnode (struct route_node *rn, struct rib *rib)
1463{
1464 /* RIB node has been un-removed before route-node is processed.
1465 * route_node must hence already be on the queue for processing..
1466 */
1467 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1468 {
1469 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001470 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001471 char buf[INET6_ADDRSTRLEN];
1472 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001473 zlog_debug ("%s: %s/%d: rn %p, un-removed rib %p",
1474 __func__, buf, rn->p.prefixlen, rn, rib);
1475 }
Paul Jakma6d691122006-07-27 21:49:00 +00001476 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1477 return;
1478 }
1479 rib_link (rn, rib);
1480}
1481
1482static void
1483rib_unlink (struct route_node *rn, struct rib *rib)
1484{
1485 struct nexthop *nexthop, *next;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001486 char buf[INET6_ADDRSTRLEN];
Paul Jakma6d691122006-07-27 21:49:00 +00001487
1488 assert (rn && rib);
1489
1490 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001491 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001492 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001493 zlog_debug ("%s: %s/%d: rn %p, rib %p",
1494 __func__, buf, rn->p.prefixlen, rn, rib);
1495 }
Paul Jakma6d691122006-07-27 21:49:00 +00001496
1497 if (rib->next)
1498 rib->next->prev = rib->prev;
1499
1500 if (rib->prev)
1501 rib->prev->next = rib->next;
1502 else
1503 {
1504 rn->info = rib->next;
1505
1506 if (rn->info)
1507 {
1508 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001509 zlog_debug ("%s: %s/%d: rn %p, rib %p, new head copy",
1510 __func__, buf, rn->p.prefixlen, rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001511 rib->next->rn_status = rib->rn_status;
1512 }
1513 }
1514
1515 /* free RIB and nexthops */
1516 for (nexthop = rib->nexthop; nexthop; nexthop = next)
1517 {
1518 next = nexthop->next;
1519 nexthop_free (nexthop);
1520 }
1521 XFREE (MTYPE_RIB, rib);
1522
1523 route_unlock_node (rn); /* rn route table reference */
paul718e3742002-12-13 20:15:29 +00001524}
1525
paula1ac18c2005-06-28 17:17:12 +00001526static void
paul718e3742002-12-13 20:15:29 +00001527rib_delnode (struct route_node *rn, struct rib *rib)
1528{
Paul Jakma6d691122006-07-27 21:49:00 +00001529 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001530 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001531 char buf[INET6_ADDRSTRLEN];
1532 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001533 zlog_debug ("%s: %s/%d: rn %p, rib %p, removing", __func__,
1534 buf, rn->p.prefixlen, rn, rib);
1535 }
Paul Jakma6d691122006-07-27 21:49:00 +00001536 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1537 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001538}
1539
1540int
1541rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001542 struct in_addr *gate, struct in_addr *src,
1543 unsigned int ifindex, u_int32_t vrf_id,
paul718e3742002-12-13 20:15:29 +00001544 u_int32_t metric, u_char distance)
1545{
1546 struct rib *rib;
1547 struct rib *same = NULL;
1548 struct route_table *table;
1549 struct route_node *rn;
1550 struct nexthop *nexthop;
1551
1552 /* Lookup table. */
1553 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1554 if (! table)
1555 return 0;
1556
1557 /* Make it sure prefixlen is applied to the prefix. */
1558 apply_mask_ipv4 (p);
1559
1560 /* Set default distance by route type. */
1561 if (distance == 0)
1562 {
1563 distance = route_info[type].distance;
1564
1565 /* iBGP distance is 200. */
1566 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1567 distance = 200;
1568 }
1569
1570 /* Lookup route node.*/
1571 rn = route_node_get (table, (struct prefix *) p);
1572
1573 /* If same type of route are installed, treat it as a implicit
1574 withdraw. */
1575 for (rib = rn->info; rib; rib = rib->next)
1576 {
Paul Jakma6d691122006-07-27 21:49:00 +00001577 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1578 continue;
1579
hassoebf1ead2005-09-21 14:58:20 +00001580 if (rib->type != type)
1581 continue;
1582 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001583 {
1584 same = rib;
1585 break;
1586 }
hassoebf1ead2005-09-21 14:58:20 +00001587 /* Duplicate connected route comes in. */
1588 else if ((nexthop = rib->nexthop) &&
1589 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001590 nexthop->ifindex == ifindex &&
1591 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001592 {
1593 rib->refcnt++;
1594 return 0 ;
1595 }
paul718e3742002-12-13 20:15:29 +00001596 }
1597
1598 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001599 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001600 rib->type = type;
1601 rib->distance = distance;
1602 rib->flags = flags;
1603 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001604 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001605 rib->nexthop_num = 0;
1606 rib->uptime = time (NULL);
1607
1608 /* Nexthop settings. */
1609 if (gate)
1610 {
1611 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001612 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001613 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001614 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001615 }
1616 else
1617 nexthop_ifindex_add (rib, ifindex);
1618
1619 /* If this route is kernel route, set FIB flag to the route. */
1620 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1621 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1622 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1623
1624 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001625 if (IS_ZEBRA_DEBUG_RIB)
1626 zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
paul718e3742002-12-13 20:15:29 +00001627 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001628
paul718e3742002-12-13 20:15:29 +00001629 /* Free implicit route.*/
1630 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001631 {
1632 if (IS_ZEBRA_DEBUG_RIB)
1633 zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001634 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001635 }
paul4d38fdb2005-04-28 17:35:14 +00001636
1637 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001638 return 0;
1639}
1640
Denis Ovsienkodc958242007-08-13 16:03:06 +00001641/* This function dumps the contents of a given RIB entry into
1642 * standard debug log. Calling function name and IP prefix in
1643 * question are passed as 1st and 2nd arguments.
1644 */
1645
1646void rib_dump (const char * func, const struct prefix_ipv4 * p, const struct rib * rib)
1647{
1648 char straddr1[INET_ADDRSTRLEN], straddr2[INET_ADDRSTRLEN];
1649 struct nexthop *nexthop;
1650
1651 inet_ntop (AF_INET, &p->prefix, straddr1, INET_ADDRSTRLEN);
1652 zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr1, p->prefixlen);
1653 zlog_debug
1654 (
1655 "%s: refcnt == %lu, uptime == %u, type == %u, table == %d",
1656 func,
1657 rib->refcnt,
1658 rib->uptime,
1659 rib->type,
1660 rib->table
1661 );
1662 zlog_debug
1663 (
1664 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1665 func,
1666 rib->metric,
1667 rib->distance,
1668 rib->flags,
1669 rib->status
1670 );
1671 zlog_debug
1672 (
1673 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1674 func,
1675 rib->nexthop_num,
1676 rib->nexthop_active_num,
1677 rib->nexthop_fib_num
1678 );
1679 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1680 {
1681 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, straddr1, INET_ADDRSTRLEN);
1682 inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, straddr2, INET_ADDRSTRLEN);
1683 zlog_debug
1684 (
1685 "%s: NH %s (%s) with flags %s%s%s",
1686 func,
1687 straddr1,
1688 straddr2,
1689 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1690 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1691 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1692 );
1693 }
1694 zlog_debug ("%s: dump complete", func);
1695}
1696
1697/* This is an exported helper to rtm_read() to dump the strange
1698 * RIB entry found by rib_lookup_ipv4_route()
1699 */
1700
1701void rib_lookup_and_dump (struct prefix_ipv4 * p)
1702{
1703 struct route_table *table;
1704 struct route_node *rn;
1705 struct rib *rib;
1706 char prefix_buf[INET_ADDRSTRLEN];
1707
1708 /* Lookup table. */
1709 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1710 if (! table)
1711 {
1712 zlog_err ("%s: vrf_table() returned NULL", __func__);
1713 return;
1714 }
1715
1716 inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
1717 /* Scan the RIB table for exactly matching RIB entry. */
1718 rn = route_node_lookup (table, (struct prefix *) p);
1719
1720 /* No route for this prefix. */
1721 if (! rn)
1722 {
1723 zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
1724 return;
1725 }
1726
1727 /* Unlock node. */
1728 route_unlock_node (rn);
1729
1730 /* let's go */
1731 for (rib = rn->info; rib; rib = rib->next)
1732 {
1733 zlog_debug
1734 (
1735 "%s: rn %p, rib %p: %s, %s",
1736 __func__,
1737 rn,
1738 rib,
1739 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
1740 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
1741 );
1742 rib_dump (__func__, p, rib);
1743 }
1744}
1745
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001746/* Check if requested address assignment will fail due to another
1747 * route being installed by zebra in FIB already. Take necessary
1748 * actions, if needed: remove such a route from FIB and deSELECT
1749 * corresponding RIB entry. Then put affected RN into RIBQ head.
1750 */
1751void rib_lookup_and_pushup (struct prefix_ipv4 * p)
1752{
1753 struct route_table *table;
1754 struct route_node *rn;
1755 struct rib *rib;
1756 unsigned changed = 0;
1757
1758 if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
1759 {
1760 zlog_err ("%s: vrf_table() returned NULL", __func__);
1761 return;
1762 }
1763
1764 /* No matches would be the simplest case. */
1765 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
1766 return;
1767
1768 /* Unlock node. */
1769 route_unlock_node (rn);
1770
1771 /* Check all RIB entries. In case any changes have to be done, requeue
1772 * the RN into RIBQ head. If the routing message about the new connected
1773 * route (generated by the IP address we are going to assign very soon)
1774 * comes before the RIBQ is processed, the new RIB entry will join
1775 * RIBQ record already on head. This is necessary for proper revalidation
1776 * of the rest of the RIB.
1777 */
1778 for (rib = rn->info; rib; rib = rib->next)
1779 {
1780 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
1781 ! RIB_SYSTEM_ROUTE (rib))
1782 {
1783 changed = 1;
1784 if (IS_ZEBRA_DEBUG_RIB)
1785 {
1786 char buf[INET_ADDRSTRLEN];
1787 inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
1788 zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
1789 rib_dump (__func__, (struct prefix_ipv4 *)&rn->p, rib);
1790 }
1791 rib_uninstall (rn, rib);
1792 }
1793 }
1794 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001795 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001796}
1797
paul718e3742002-12-13 20:15:29 +00001798int
1799rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib)
1800{
1801 struct route_table *table;
1802 struct route_node *rn;
1803 struct rib *same;
1804 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00001805
paul718e3742002-12-13 20:15:29 +00001806 /* Lookup table. */
1807 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1808 if (! table)
1809 return 0;
paul718e3742002-12-13 20:15:29 +00001810 /* Make it sure prefixlen is applied to the prefix. */
1811 apply_mask_ipv4 (p);
1812
1813 /* Set default distance by route type. */
1814 if (rib->distance == 0)
1815 {
1816 rib->distance = route_info[rib->type].distance;
1817
1818 /* iBGP distance is 200. */
1819 if (rib->type == ZEBRA_ROUTE_BGP
1820 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1821 rib->distance = 200;
1822 }
1823
1824 /* Lookup route node.*/
1825 rn = route_node_get (table, (struct prefix *) p);
1826
1827 /* If same type of route are installed, treat it as a implicit
1828 withdraw. */
1829 for (same = rn->info; same; same = same->next)
1830 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00001831 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00001832 continue;
1833
paul718e3742002-12-13 20:15:29 +00001834 if (same->type == rib->type && same->table == rib->table
1835 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001836 break;
paul718e3742002-12-13 20:15:29 +00001837 }
paul4d38fdb2005-04-28 17:35:14 +00001838
paul718e3742002-12-13 20:15:29 +00001839 /* If this route is kernel route, set FIB flag to the route. */
1840 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
1841 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1842 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1843
1844 /* Link new rib to node.*/
1845 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001846 if (IS_ZEBRA_DEBUG_RIB)
1847 {
1848 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
1849 __func__, rn, rib);
1850 rib_dump (__func__, p, rib);
1851 }
paul718e3742002-12-13 20:15:29 +00001852
paul718e3742002-12-13 20:15:29 +00001853 /* Free implicit route.*/
1854 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001855 {
1856 if (IS_ZEBRA_DEBUG_RIB)
1857 {
1858 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
1859 __func__, rn, same);
1860 rib_dump (__func__, p, same);
1861 }
paul4d38fdb2005-04-28 17:35:14 +00001862 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001863 }
paul4d38fdb2005-04-28 17:35:14 +00001864
1865 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001866 return 0;
1867}
1868
hassoebf1ead2005-09-21 14:58:20 +00001869/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00001870int
1871rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
1872 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1873{
1874 struct route_table *table;
1875 struct route_node *rn;
1876 struct rib *rib;
1877 struct rib *fib = NULL;
1878 struct rib *same = NULL;
1879 struct nexthop *nexthop;
1880 char buf1[BUFSIZ];
1881 char buf2[BUFSIZ];
1882
1883 /* Lookup table. */
1884 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1885 if (! table)
1886 return 0;
1887
1888 /* Apply mask. */
1889 apply_mask_ipv4 (p);
1890
paul5ec90d22003-06-19 01:41:37 +00001891 if (IS_ZEBRA_DEBUG_KERNEL && gate)
ajsb6178002004-12-07 21:12:56 +00001892 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
paul5ec90d22003-06-19 01:41:37 +00001893 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1894 p->prefixlen,
1895 inet_ntoa (*gate),
1896 ifindex);
1897
paul718e3742002-12-13 20:15:29 +00001898 /* Lookup route node. */
1899 rn = route_node_lookup (table, (struct prefix *) p);
1900 if (! rn)
1901 {
1902 if (IS_ZEBRA_DEBUG_KERNEL)
1903 {
1904 if (gate)
ajsb6178002004-12-07 21:12:56 +00001905 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001906 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1907 p->prefixlen,
1908 inet_ntop (AF_INET, gate, buf2, BUFSIZ),
1909 ifindex);
1910 else
ajsb6178002004-12-07 21:12:56 +00001911 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001912 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1913 p->prefixlen,
1914 ifindex);
1915 }
1916 return ZEBRA_ERR_RTNOEXIST;
1917 }
1918
1919 /* Lookup same type route. */
1920 for (rib = rn->info; rib; rib = rib->next)
1921 {
Paul Jakma6d691122006-07-27 21:49:00 +00001922 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1923 continue;
1924
paul718e3742002-12-13 20:15:29 +00001925 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1926 fib = rib;
1927
hassoebf1ead2005-09-21 14:58:20 +00001928 if (rib->type != type)
1929 continue;
1930 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
1931 nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex)
paul718e3742002-12-13 20:15:29 +00001932 {
hassoebf1ead2005-09-21 14:58:20 +00001933 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00001934 {
hassoebf1ead2005-09-21 14:58:20 +00001935 rib->refcnt--;
1936 route_unlock_node (rn);
1937 route_unlock_node (rn);
1938 return 0;
paul718e3742002-12-13 20:15:29 +00001939 }
hassoebf1ead2005-09-21 14:58:20 +00001940 same = rib;
1941 break;
paul718e3742002-12-13 20:15:29 +00001942 }
hassoebf1ead2005-09-21 14:58:20 +00001943 /* Make sure that the route found has the same gateway. */
1944 else if (gate == NULL ||
1945 ((nexthop = rib->nexthop) &&
1946 (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
1947 IPV4_ADDR_SAME (&nexthop->rgate.ipv4, gate))))
paul5ec90d22003-06-19 01:41:37 +00001948 {
hassoebf1ead2005-09-21 14:58:20 +00001949 same = rib;
1950 break;
paul718e3742002-12-13 20:15:29 +00001951 }
1952 }
1953
1954 /* If same type of route can't be found and this message is from
1955 kernel. */
1956 if (! same)
1957 {
1958 if (fib && type == ZEBRA_ROUTE_KERNEL)
1959 {
1960 /* Unset flags. */
1961 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1962 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1963
1964 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1965 }
1966 else
1967 {
1968 if (IS_ZEBRA_DEBUG_KERNEL)
1969 {
1970 if (gate)
ajsb6178002004-12-07 21:12:56 +00001971 zlog_debug ("route %s/%d via %s 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 inet_ntop (AF_INET, gate, buf2, BUFSIZ),
1975 ifindex,
1976 type);
1977 else
ajsb6178002004-12-07 21:12:56 +00001978 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001979 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1980 p->prefixlen,
1981 ifindex,
1982 type);
1983 }
1984 route_unlock_node (rn);
1985 return ZEBRA_ERR_RTNOEXIST;
1986 }
1987 }
paul4d38fdb2005-04-28 17:35:14 +00001988
paul718e3742002-12-13 20:15:29 +00001989 if (same)
1990 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00001991
paul718e3742002-12-13 20:15:29 +00001992 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001993 return 0;
1994}
1995
1996/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00001997static void
paul718e3742002-12-13 20:15:29 +00001998static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
1999{
2000 struct rib *rib;
2001 struct route_node *rn;
2002 struct route_table *table;
2003
2004 /* Lookup table. */
2005 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2006 if (! table)
2007 return;
2008
2009 /* Lookup existing route */
2010 rn = route_node_get (table, p);
2011 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002012 {
2013 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2014 continue;
2015
2016 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2017 break;
2018 }
paul718e3742002-12-13 20:15:29 +00002019
2020 if (rib)
2021 {
2022 /* Same distance static route is there. Update it with new
2023 nexthop. */
paul718e3742002-12-13 20:15:29 +00002024 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002025 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002026 {
2027 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002028 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002029 break;
2030 case STATIC_IPV4_IFNAME:
2031 nexthop_ifname_add (rib, si->gate.ifname);
2032 break;
2033 case STATIC_IPV4_BLACKHOLE:
2034 nexthop_blackhole_add (rib);
2035 break;
paul4d38fdb2005-04-28 17:35:14 +00002036 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002037 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002038 }
2039 else
2040 {
2041 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002042 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2043
paul718e3742002-12-13 20:15:29 +00002044 rib->type = ZEBRA_ROUTE_STATIC;
2045 rib->distance = si->distance;
2046 rib->metric = 0;
2047 rib->nexthop_num = 0;
2048
2049 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002050 {
2051 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002052 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002053 break;
2054 case STATIC_IPV4_IFNAME:
2055 nexthop_ifname_add (rib, si->gate.ifname);
2056 break;
2057 case STATIC_IPV4_BLACKHOLE:
2058 nexthop_blackhole_add (rib);
2059 break;
2060 }
paul718e3742002-12-13 20:15:29 +00002061
hasso81dfcaa2003-05-25 19:21:25 +00002062 /* Save the flags of this static routes (reject, blackhole) */
2063 rib->flags = si->flags;
2064
paul718e3742002-12-13 20:15:29 +00002065 /* Link this rib to the tree. */
2066 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002067 }
2068}
2069
paula1ac18c2005-06-28 17:17:12 +00002070static int
paul718e3742002-12-13 20:15:29 +00002071static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2072{
2073 if (nexthop->type == NEXTHOP_TYPE_IPV4
2074 && si->type == STATIC_IPV4_GATEWAY
2075 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2076 return 1;
2077 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2078 && si->type == STATIC_IPV4_IFNAME
2079 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2080 return 1;
paul595db7f2003-05-25 21:35:06 +00002081 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2082 && si->type == STATIC_IPV4_BLACKHOLE)
2083 return 1;
paule8e19462006-01-19 20:16:55 +00002084 return 0;
paul718e3742002-12-13 20:15:29 +00002085}
2086
2087/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002088static void
paul718e3742002-12-13 20:15:29 +00002089static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
2090{
2091 struct route_node *rn;
2092 struct rib *rib;
2093 struct nexthop *nexthop;
2094 struct route_table *table;
2095
2096 /* Lookup table. */
2097 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2098 if (! table)
2099 return;
paul4d38fdb2005-04-28 17:35:14 +00002100
paul718e3742002-12-13 20:15:29 +00002101 /* Lookup existing route with type and distance. */
2102 rn = route_node_lookup (table, p);
2103 if (! rn)
2104 return;
2105
2106 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002107 {
2108 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2109 continue;
2110
2111 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2112 break;
2113 }
paul718e3742002-12-13 20:15:29 +00002114
2115 if (! rib)
2116 {
2117 route_unlock_node (rn);
2118 return;
2119 }
2120
2121 /* Lookup nexthop. */
2122 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2123 if (static_ipv4_nexthop_same (nexthop, si))
2124 break;
2125
2126 /* Can't find nexthop. */
2127 if (! nexthop)
2128 {
2129 route_unlock_node (rn);
2130 return;
2131 }
2132
2133 /* Check nexthop. */
2134 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002135 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002136 else
2137 {
paul6baeb982003-10-28 03:47:15 +00002138 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2139 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002140 nexthop_delete (rib, nexthop);
2141 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002142 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002143 }
paul718e3742002-12-13 20:15:29 +00002144 /* Unlock node. */
2145 route_unlock_node (rn);
2146}
2147
2148/* Add static route into static route configuration. */
2149int
hasso39db97e2004-10-12 20:50:58 +00002150static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00002151 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002152{
2153 u_char type = 0;
2154 struct route_node *rn;
2155 struct static_ipv4 *si;
2156 struct static_ipv4 *pp;
2157 struct static_ipv4 *cp;
2158 struct static_ipv4 *update = NULL;
2159 struct route_table *stable;
2160
2161 /* Lookup table. */
2162 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2163 if (! stable)
2164 return -1;
2165
2166 /* Lookup static route prefix. */
2167 rn = route_node_get (stable, p);
2168
2169 /* Make flags. */
2170 if (gate)
2171 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002172 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002173 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002174 else
2175 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002176
2177 /* Do nothing if there is a same static route. */
2178 for (si = rn->info; si; si = si->next)
2179 {
2180 if (type == si->type
2181 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2182 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2183 {
2184 if (distance == si->distance)
2185 {
2186 route_unlock_node (rn);
2187 return 0;
2188 }
2189 else
2190 update = si;
2191 }
2192 }
2193
Paul Jakma3c0755d2006-12-08 00:53:14 +00002194 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002195 if (update)
2196 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
2197
2198 /* Make new static route structure. */
2199 si = XMALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
2200 memset (si, 0, sizeof (struct static_ipv4));
2201
2202 si->type = type;
2203 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002204 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002205
2206 if (gate)
2207 si->gate.ipv4 = *gate;
2208 if (ifname)
2209 si->gate.ifname = XSTRDUP (0, ifname);
2210
2211 /* Add new static route information to the tree with sort by
2212 distance value and gateway address. */
2213 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2214 {
2215 if (si->distance < cp->distance)
2216 break;
2217 if (si->distance > cp->distance)
2218 continue;
2219 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2220 {
2221 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2222 break;
2223 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2224 continue;
2225 }
2226 }
2227
2228 /* Make linked list. */
2229 if (pp)
2230 pp->next = si;
2231 else
2232 rn->info = si;
2233 if (cp)
2234 cp->prev = si;
2235 si->prev = pp;
2236 si->next = cp;
2237
2238 /* Install into rib. */
2239 static_install_ipv4 (p, si);
2240
2241 return 1;
2242}
2243
2244/* Delete static route from static route configuration. */
2245int
hasso39db97e2004-10-12 20:50:58 +00002246static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00002247 u_char distance, u_int32_t vrf_id)
2248{
2249 u_char type = 0;
2250 struct route_node *rn;
2251 struct static_ipv4 *si;
2252 struct route_table *stable;
2253
2254 /* Lookup table. */
2255 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2256 if (! stable)
2257 return -1;
2258
2259 /* Lookup static route prefix. */
2260 rn = route_node_lookup (stable, p);
2261 if (! rn)
2262 return 0;
2263
2264 /* Make flags. */
2265 if (gate)
2266 type = STATIC_IPV4_GATEWAY;
2267 else if (ifname)
2268 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002269 else
2270 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002271
2272 /* Find same static route is the tree */
2273 for (si = rn->info; si; si = si->next)
2274 if (type == si->type
2275 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2276 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2277 break;
2278
2279 /* Can't find static route. */
2280 if (! si)
2281 {
2282 route_unlock_node (rn);
2283 return 0;
2284 }
2285
2286 /* Install into rib. */
2287 static_uninstall_ipv4 (p, si);
2288
2289 /* Unlink static route from linked list. */
2290 if (si->prev)
2291 si->prev->next = si->next;
2292 else
2293 rn->info = si->next;
2294 if (si->next)
2295 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002296 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002297
2298 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002299 if (ifname)
2300 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002301 XFREE (MTYPE_STATIC_IPV4, si);
2302
paul143a3852003-09-29 20:06:13 +00002303 route_unlock_node (rn);
2304
paul718e3742002-12-13 20:15:29 +00002305 return 1;
2306}
2307
2308
2309#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00002310static int
paul718e3742002-12-13 20:15:29 +00002311rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2312 struct in6_addr *gate, unsigned int ifindex, int table)
2313{
hasso726f9b22003-05-25 21:04:54 +00002314 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2315#if defined (MUSICA) || defined (LINUX)
2316 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2317 if (p->prefixlen == 96)
2318 return 0;
2319#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00002320 return 1;
hasso726f9b22003-05-25 21:04:54 +00002321 }
paul718e3742002-12-13 20:15:29 +00002322 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
2323 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
2324 {
2325 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
2326 return 1;
2327 }
2328 return 0;
2329}
2330
2331int
2332rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00002333 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
2334 u_int32_t metric, u_char distance)
paul718e3742002-12-13 20:15:29 +00002335{
2336 struct rib *rib;
2337 struct rib *same = NULL;
2338 struct route_table *table;
2339 struct route_node *rn;
2340 struct nexthop *nexthop;
2341
paul718e3742002-12-13 20:15:29 +00002342 /* Lookup table. */
2343 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2344 if (! table)
2345 return 0;
2346
2347 /* Make sure mask is applied. */
2348 apply_mask_ipv6 (p);
2349
2350 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002351 if (!distance)
2352 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002353
2354 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2355 distance = 200;
2356
2357 /* Filter bogus route. */
2358 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
2359 return 0;
2360
2361 /* Lookup route node.*/
2362 rn = route_node_get (table, (struct prefix *) p);
2363
2364 /* If same type of route are installed, treat it as a implicit
2365 withdraw. */
2366 for (rib = rn->info; rib; rib = rib->next)
2367 {
Paul Jakma6d691122006-07-27 21:49:00 +00002368 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2369 continue;
2370
hassoebf1ead2005-09-21 14:58:20 +00002371 if (rib->type != type)
2372 continue;
2373 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002374 {
2375 same = rib;
paul718e3742002-12-13 20:15:29 +00002376 break;
2377 }
hassoebf1ead2005-09-21 14:58:20 +00002378 else if ((nexthop = rib->nexthop) &&
2379 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2380 nexthop->ifindex == ifindex)
2381 {
2382 rib->refcnt++;
2383 return 0;
2384 }
paul718e3742002-12-13 20:15:29 +00002385 }
2386
2387 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002388 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2389
paul718e3742002-12-13 20:15:29 +00002390 rib->type = type;
2391 rib->distance = distance;
2392 rib->flags = flags;
2393 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00002394 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00002395 rib->nexthop_num = 0;
2396 rib->uptime = time (NULL);
2397
2398 /* Nexthop settings. */
2399 if (gate)
2400 {
2401 if (ifindex)
2402 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2403 else
2404 nexthop_ipv6_add (rib, gate);
2405 }
2406 else
2407 nexthop_ifindex_add (rib, ifindex);
2408
2409 /* If this route is kernel route, set FIB flag to the route. */
2410 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2411 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2412 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2413
2414 /* Link new rib to node.*/
2415 rib_addnode (rn, rib);
2416
paul718e3742002-12-13 20:15:29 +00002417 /* Free implicit route.*/
2418 if (same)
paul4d38fdb2005-04-28 17:35:14 +00002419 rib_delnode (rn, same);
2420
2421 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002422 return 0;
2423}
2424
hassoebf1ead2005-09-21 14:58:20 +00002425/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002426int
2427rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
2428 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
2429{
2430 struct route_table *table;
2431 struct route_node *rn;
2432 struct rib *rib;
2433 struct rib *fib = NULL;
2434 struct rib *same = NULL;
2435 struct nexthop *nexthop;
2436 char buf1[BUFSIZ];
2437 char buf2[BUFSIZ];
2438
2439 /* Apply mask. */
2440 apply_mask_ipv6 (p);
2441
2442 /* Lookup table. */
2443 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2444 if (! table)
2445 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002446
paul718e3742002-12-13 20:15:29 +00002447 /* Lookup route node. */
2448 rn = route_node_lookup (table, (struct prefix *) p);
2449 if (! rn)
2450 {
2451 if (IS_ZEBRA_DEBUG_KERNEL)
2452 {
2453 if (gate)
ajsb6178002004-12-07 21:12:56 +00002454 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00002455 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
2456 p->prefixlen,
2457 inet_ntop (AF_INET6, gate, buf2, BUFSIZ),
2458 ifindex);
2459 else
ajsb6178002004-12-07 21:12:56 +00002460 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00002461 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
2462 p->prefixlen,
2463 ifindex);
2464 }
2465 return ZEBRA_ERR_RTNOEXIST;
2466 }
2467
2468 /* Lookup same type route. */
2469 for (rib = rn->info; rib; rib = rib->next)
2470 {
Paul Jakma6d691122006-07-27 21:49:00 +00002471 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2472 continue;
2473
paul718e3742002-12-13 20:15:29 +00002474 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2475 fib = rib;
2476
hassoebf1ead2005-09-21 14:58:20 +00002477 if (rib->type != type)
2478 continue;
2479 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
2480 nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex)
paul718e3742002-12-13 20:15:29 +00002481 {
hassoebf1ead2005-09-21 14:58:20 +00002482 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002483 {
hassoebf1ead2005-09-21 14:58:20 +00002484 rib->refcnt--;
2485 route_unlock_node (rn);
2486 route_unlock_node (rn);
2487 return 0;
paul718e3742002-12-13 20:15:29 +00002488 }
hassoebf1ead2005-09-21 14:58:20 +00002489 same = rib;
2490 break;
paul718e3742002-12-13 20:15:29 +00002491 }
hassoebf1ead2005-09-21 14:58:20 +00002492 /* Make sure that the route found has the same gateway. */
2493 else if (gate == NULL ||
2494 ((nexthop = rib->nexthop) &&
2495 (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate) ||
2496 IPV6_ADDR_SAME (&nexthop->rgate.ipv6, gate))))
paul718e3742002-12-13 20:15:29 +00002497 {
hassoebf1ead2005-09-21 14:58:20 +00002498 same = rib;
2499 break;
paul718e3742002-12-13 20:15:29 +00002500 }
2501 }
2502
2503 /* If same type of route can't be found and this message is from
2504 kernel. */
2505 if (! same)
2506 {
2507 if (fib && type == ZEBRA_ROUTE_KERNEL)
2508 {
2509 /* Unset flags. */
2510 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2511 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2512
2513 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2514 }
2515 else
2516 {
2517 if (IS_ZEBRA_DEBUG_KERNEL)
2518 {
2519 if (gate)
ajsb6178002004-12-07 21:12:56 +00002520 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00002521 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
2522 p->prefixlen,
2523 inet_ntop (AF_INET6, gate, buf2, BUFSIZ),
2524 ifindex,
2525 type);
2526 else
ajsb6178002004-12-07 21:12:56 +00002527 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00002528 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
2529 p->prefixlen,
2530 ifindex,
2531 type);
2532 }
2533 route_unlock_node (rn);
2534 return ZEBRA_ERR_RTNOEXIST;
2535 }
2536 }
2537
2538 if (same)
2539 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002540
paul718e3742002-12-13 20:15:29 +00002541 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002542 return 0;
2543}
2544
2545/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002546static void
paul718e3742002-12-13 20:15:29 +00002547static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2548{
2549 struct rib *rib;
2550 struct route_table *table;
2551 struct route_node *rn;
2552
2553 /* Lookup table. */
2554 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2555 if (! table)
2556 return;
2557
2558 /* Lookup existing route */
2559 rn = route_node_get (table, p);
2560 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002561 {
2562 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2563 continue;
2564
2565 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2566 break;
2567 }
paul718e3742002-12-13 20:15:29 +00002568
2569 if (rib)
2570 {
2571 /* Same distance static route is there. Update it with new
2572 nexthop. */
paul718e3742002-12-13 20:15:29 +00002573 route_unlock_node (rn);
2574
2575 switch (si->type)
2576 {
2577 case STATIC_IPV6_GATEWAY:
2578 nexthop_ipv6_add (rib, &si->ipv6);
2579 break;
2580 case STATIC_IPV6_IFNAME:
2581 nexthop_ifname_add (rib, si->ifname);
2582 break;
2583 case STATIC_IPV6_GATEWAY_IFNAME:
2584 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2585 break;
2586 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002587 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002588 }
2589 else
2590 {
2591 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002592 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2593
paul718e3742002-12-13 20:15:29 +00002594 rib->type = ZEBRA_ROUTE_STATIC;
2595 rib->distance = si->distance;
2596 rib->metric = 0;
2597 rib->nexthop_num = 0;
2598
2599 switch (si->type)
2600 {
2601 case STATIC_IPV6_GATEWAY:
2602 nexthop_ipv6_add (rib, &si->ipv6);
2603 break;
2604 case STATIC_IPV6_IFNAME:
2605 nexthop_ifname_add (rib, si->ifname);
2606 break;
2607 case STATIC_IPV6_GATEWAY_IFNAME:
2608 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2609 break;
2610 }
2611
hasso81dfcaa2003-05-25 19:21:25 +00002612 /* Save the flags of this static routes (reject, blackhole) */
2613 rib->flags = si->flags;
2614
paul718e3742002-12-13 20:15:29 +00002615 /* Link this rib to the tree. */
2616 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002617 }
2618}
2619
paula1ac18c2005-06-28 17:17:12 +00002620static int
paul718e3742002-12-13 20:15:29 +00002621static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2622{
2623 if (nexthop->type == NEXTHOP_TYPE_IPV6
2624 && si->type == STATIC_IPV6_GATEWAY
2625 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2626 return 1;
2627 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2628 && si->type == STATIC_IPV6_IFNAME
2629 && strcmp (nexthop->ifname, si->ifname) == 0)
2630 return 1;
2631 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2632 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2633 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2634 && strcmp (nexthop->ifname, si->ifname) == 0)
2635 return 1;
paule8e19462006-01-19 20:16:55 +00002636 return 0;
paul718e3742002-12-13 20:15:29 +00002637}
2638
paula1ac18c2005-06-28 17:17:12 +00002639static void
paul718e3742002-12-13 20:15:29 +00002640static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2641{
2642 struct route_table *table;
2643 struct route_node *rn;
2644 struct rib *rib;
2645 struct nexthop *nexthop;
2646
2647 /* Lookup table. */
2648 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2649 if (! table)
2650 return;
2651
2652 /* Lookup existing route with type and distance. */
2653 rn = route_node_lookup (table, (struct prefix *) p);
2654 if (! rn)
2655 return;
2656
2657 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002658 {
2659 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2660 continue;
2661
2662 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2663 break;
2664 }
2665
paul718e3742002-12-13 20:15:29 +00002666 if (! rib)
2667 {
2668 route_unlock_node (rn);
2669 return;
2670 }
2671
2672 /* Lookup nexthop. */
2673 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2674 if (static_ipv6_nexthop_same (nexthop, si))
2675 break;
2676
2677 /* Can't find nexthop. */
2678 if (! nexthop)
2679 {
2680 route_unlock_node (rn);
2681 return;
2682 }
2683
2684 /* Check nexthop. */
2685 if (rib->nexthop_num == 1)
2686 {
2687 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002688 }
2689 else
2690 {
paul6baeb982003-10-28 03:47:15 +00002691 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2692 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002693 nexthop_delete (rib, nexthop);
2694 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002695 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002696 }
paul718e3742002-12-13 20:15:29 +00002697 /* Unlock node. */
2698 route_unlock_node (rn);
2699}
2700
2701/* Add static route into static route configuration. */
2702int
2703static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002704 const char *ifname, u_char flags, u_char distance,
2705 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002706{
2707 struct route_node *rn;
2708 struct static_ipv6 *si;
2709 struct static_ipv6 *pp;
2710 struct static_ipv6 *cp;
2711 struct route_table *stable;
2712
2713 /* Lookup table. */
2714 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2715 if (! stable)
2716 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00002717
2718 if (!gate &&
2719 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
2720 return -1;
2721
2722 if (!ifname &&
2723 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
2724 return -1;
paul718e3742002-12-13 20:15:29 +00002725
2726 /* Lookup static route prefix. */
2727 rn = route_node_get (stable, p);
2728
2729 /* Do nothing if there is a same static route. */
2730 for (si = rn->info; si; si = si->next)
2731 {
2732 if (distance == si->distance
2733 && type == si->type
2734 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2735 && (! ifname || strcmp (ifname, si->ifname) == 0))
2736 {
2737 route_unlock_node (rn);
2738 return 0;
2739 }
2740 }
2741
2742 /* Make new static route structure. */
2743 si = XMALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
2744 memset (si, 0, sizeof (struct static_ipv6));
2745
2746 si->type = type;
2747 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002748 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002749
2750 switch (type)
2751 {
2752 case STATIC_IPV6_GATEWAY:
2753 si->ipv6 = *gate;
2754 break;
2755 case STATIC_IPV6_IFNAME:
2756 si->ifname = XSTRDUP (0, ifname);
2757 break;
2758 case STATIC_IPV6_GATEWAY_IFNAME:
2759 si->ipv6 = *gate;
2760 si->ifname = XSTRDUP (0, ifname);
2761 break;
2762 }
2763
2764 /* Add new static route information to the tree with sort by
2765 distance value and gateway address. */
2766 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2767 {
2768 if (si->distance < cp->distance)
2769 break;
2770 if (si->distance > cp->distance)
2771 continue;
2772 }
2773
2774 /* Make linked list. */
2775 if (pp)
2776 pp->next = si;
2777 else
2778 rn->info = si;
2779 if (cp)
2780 cp->prev = si;
2781 si->prev = pp;
2782 si->next = cp;
2783
2784 /* Install into rib. */
2785 static_install_ipv6 (p, si);
2786
2787 return 1;
2788}
2789
2790/* Delete static route from static route configuration. */
2791int
2792static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002793 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002794{
2795 struct route_node *rn;
2796 struct static_ipv6 *si;
2797 struct route_table *stable;
2798
2799 /* Lookup table. */
2800 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2801 if (! stable)
2802 return -1;
2803
2804 /* Lookup static route prefix. */
2805 rn = route_node_lookup (stable, p);
2806 if (! rn)
2807 return 0;
2808
2809 /* Find same static route is the tree */
2810 for (si = rn->info; si; si = si->next)
2811 if (distance == si->distance
2812 && type == si->type
2813 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2814 && (! ifname || strcmp (ifname, si->ifname) == 0))
2815 break;
2816
2817 /* Can't find static route. */
2818 if (! si)
2819 {
2820 route_unlock_node (rn);
2821 return 0;
2822 }
2823
2824 /* Install into rib. */
2825 static_uninstall_ipv6 (p, si);
2826
2827 /* Unlink static route from linked list. */
2828 if (si->prev)
2829 si->prev->next = si->next;
2830 else
2831 rn->info = si->next;
2832 if (si->next)
2833 si->next->prev = si->prev;
2834
2835 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002836 if (ifname)
2837 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00002838 XFREE (MTYPE_STATIC_IPV6, si);
2839
2840 return 1;
2841}
2842#endif /* HAVE_IPV6 */
2843
2844/* RIB update function. */
2845void
paula1ac18c2005-06-28 17:17:12 +00002846rib_update (void)
paul718e3742002-12-13 20:15:29 +00002847{
2848 struct route_node *rn;
2849 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00002850
paul718e3742002-12-13 20:15:29 +00002851 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2852 if (table)
2853 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002854 if (rn->info)
Paul Jakma6d691122006-07-27 21:49:00 +00002855 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002856
2857 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2858 if (table)
2859 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002860 if (rn->info)
Paul Jakma6d691122006-07-27 21:49:00 +00002861 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002862}
2863
2864/* Interface goes up. */
paula1ac18c2005-06-28 17:17:12 +00002865static void
paul718e3742002-12-13 20:15:29 +00002866rib_if_up (struct interface *ifp)
2867{
2868 rib_update ();
2869}
2870
2871/* Interface goes down. */
paula1ac18c2005-06-28 17:17:12 +00002872static void
paul718e3742002-12-13 20:15:29 +00002873rib_if_down (struct interface *ifp)
2874{
2875 rib_update ();
2876}
2877
2878/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00002879static void
paul718e3742002-12-13 20:15:29 +00002880rib_weed_table (struct route_table *table)
2881{
2882 struct route_node *rn;
2883 struct rib *rib;
2884 struct rib *next;
2885
2886 if (table)
2887 for (rn = route_top (table); rn; rn = route_next (rn))
2888 for (rib = rn->info; rib; rib = next)
2889 {
2890 next = rib->next;
2891
Paul Jakma6d691122006-07-27 21:49:00 +00002892 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2893 continue;
2894
paulb21b19c2003-06-15 01:28:29 +00002895 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00002896 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00002897 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002898 }
2899}
2900
2901/* Delete all routes from non main table. */
2902void
paula1ac18c2005-06-28 17:17:12 +00002903rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00002904{
2905 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2906 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2907}
2908
2909/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00002910static void
paul718e3742002-12-13 20:15:29 +00002911rib_sweep_table (struct route_table *table)
2912{
2913 struct route_node *rn;
2914 struct rib *rib;
2915 struct rib *next;
2916 int ret = 0;
2917
2918 if (table)
2919 for (rn = route_top (table); rn; rn = route_next (rn))
2920 for (rib = rn->info; rib; rib = next)
2921 {
2922 next = rib->next;
2923
Paul Jakma6d691122006-07-27 21:49:00 +00002924 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2925 continue;
2926
paul718e3742002-12-13 20:15:29 +00002927 if (rib->type == ZEBRA_ROUTE_KERNEL &&
2928 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
2929 {
2930 ret = rib_uninstall_kernel (rn, rib);
2931 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00002932 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002933 }
2934 }
2935}
2936
2937/* Sweep all RIB tables. */
2938void
paula1ac18c2005-06-28 17:17:12 +00002939rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00002940{
2941 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2942 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2943}
2944
2945/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00002946static void
paul718e3742002-12-13 20:15:29 +00002947rib_close_table (struct route_table *table)
2948{
2949 struct route_node *rn;
2950 struct rib *rib;
2951
2952 if (table)
2953 for (rn = route_top (table); rn; rn = route_next (rn))
2954 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002955 {
2956 if (! RIB_SYSTEM_ROUTE (rib)
2957 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2958 rib_uninstall_kernel (rn, rib);
2959 }
paul718e3742002-12-13 20:15:29 +00002960}
2961
2962/* Close all RIB tables. */
2963void
paula1ac18c2005-06-28 17:17:12 +00002964rib_close (void)
paul718e3742002-12-13 20:15:29 +00002965{
2966 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2967 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2968}
2969
2970/* Routing information base initialize. */
2971void
paula1ac18c2005-06-28 17:17:12 +00002972rib_init (void)
paul718e3742002-12-13 20:15:29 +00002973{
paul4d38fdb2005-04-28 17:35:14 +00002974 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00002975 /* VRF initialization. */
2976 vrf_init ();
2977}