blob: 90db932b856645c1d582b6b58fefc6f588a3a322 [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 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001204static unsigned int
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001205process_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 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001241static void
1242rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001243{
1244 u_char qindex;
1245 struct rib *rib;
1246 char buf[INET6_ADDRSTRLEN];
1247 if (IS_ZEBRA_DEBUG_RIB_Q)
1248 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
1249 for (rib = rn->info; rib; rib = rib->next)
1250 {
1251 switch (rib->type)
1252 {
1253 case ZEBRA_ROUTE_KERNEL:
1254 case ZEBRA_ROUTE_CONNECT:
1255 qindex = 0;
1256 break;
1257 case ZEBRA_ROUTE_STATIC:
1258 qindex = 1;
1259 break;
1260 case ZEBRA_ROUTE_RIP:
1261 case ZEBRA_ROUTE_RIPNG:
1262 case ZEBRA_ROUTE_OSPF:
1263 case ZEBRA_ROUTE_OSPF6:
1264 case ZEBRA_ROUTE_ISIS:
1265 qindex = 2;
1266 break;
1267 case ZEBRA_ROUTE_BGP:
1268 qindex = 3;
1269 break;
1270 default:
1271 qindex = 4;
1272 break;
1273 }
1274 /* Invariant: at this point we always have rn->info set. */
1275 if (CHECK_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED(qindex)))
1276 {
1277 if (IS_ZEBRA_DEBUG_RIB_Q)
1278 zlog_debug ("%s: %s/%d: rn %p is already queued in sub-queue %u", __func__, buf, rn->p.prefixlen, rn, qindex);
1279 continue;
1280 }
1281 SET_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED(qindex));
1282 listnode_add (mq->subq[qindex], rn);
1283 route_lock_node (rn);
1284 mq->size++;
1285 if (IS_ZEBRA_DEBUG_RIB_Q)
1286 zlog_debug ("%s: %s/%d: queued rn %p into sub-queue %u", __func__, buf, rn->p.prefixlen, rn, qindex);
1287 }
paul4d38fdb2005-04-28 17:35:14 +00001288}
1289
Paul Jakma6d691122006-07-27 21:49:00 +00001290/* Add route_node to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001291static void
Paul Jakma6d691122006-07-27 21:49:00 +00001292rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
paul4d38fdb2005-04-28 17:35:14 +00001293{
Paul Jakma93bdada2007-08-06 19:25:11 +00001294 char buf[INET_ADDRSTRLEN];
Paul Jakma6d691122006-07-27 21:49:00 +00001295 assert (zebra && rn);
paul4d38fdb2005-04-28 17:35:14 +00001296
Paul Jakma93bdada2007-08-06 19:25:11 +00001297 if (IS_ZEBRA_DEBUG_RIB_Q)
1298 inet_ntop (AF_INET, &rn->p.u.prefix, buf, INET_ADDRSTRLEN);
1299
Paul Jakma6d691122006-07-27 21:49:00 +00001300 /* Pointless to queue a route_node with no RIB entries to add or remove */
1301 if (!rn->info)
1302 {
1303 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1304 __func__, rn, rn->lock);
1305 zlog_backtrace(LOG_DEBUG);
1306 return;
1307 }
paul4d38fdb2005-04-28 17:35:14 +00001308
Paul Jakma6d691122006-07-27 21:49:00 +00001309 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma93bdada2007-08-06 19:25:11 +00001310 zlog_info ("%s: %s/%d: work queue added", __func__, buf, rn->p.prefixlen);
Paul Jakma6d691122006-07-27 21:49:00 +00001311
1312 assert (zebra);
1313
paul4d38fdb2005-04-28 17:35:14 +00001314 if (zebra->ribq == NULL)
1315 {
Paul Jakma6d691122006-07-27 21:49:00 +00001316 zlog_err ("%s: work_queue does not exist!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001317 return;
1318 }
Paul Jakma6d691122006-07-27 21:49:00 +00001319
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001320 /* The RIB queue should normally be either empty or holding the only work_queue_item
1321 * element. In the latter case this element would hold a pointer to the meta queue
1322 * structure, which must be used to actually queue the route nodes to process. So
1323 * create the MQ holder, if necessary, then push the work into it in any case.
1324 * This semantics was introduced after 0.99.9 release.
1325 */
1326
1327 /* Should I invent work_queue_empty() and use it, or it's Ok to do as follows? */
1328 if (!zebra->ribq->items->count)
1329 work_queue_add (zebra->ribq, zebra->mq);
1330
1331 rib_meta_queue_add (zebra->mq, rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001332
1333 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma93bdada2007-08-06 19:25:11 +00001334 zlog_debug ("%s: %s/%d: rn %p queued", __func__, buf, rn->p.prefixlen, rn);
paul4d38fdb2005-04-28 17:35:14 +00001335
1336 return;
1337}
1338
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001339/* Create new meta queue. A destructor function doesn't seem to be necessary here. */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001340static struct meta_queue *
1341meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001342{
1343 struct meta_queue *new;
1344 unsigned i, failed = 0;
1345
1346 if ((new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue))) == NULL)
1347 return NULL;
1348 for (i = 0; i < MQ_SIZE; i++)
1349 if ((new->subq[i] = list_new ()) == NULL)
1350 failed = 1;
1351 if (failed)
1352 {
1353 for (i = 0; i < MQ_SIZE; i++)
1354 if (new->subq[i])
1355 list_delete (new->subq[i]);
1356 XFREE (MTYPE_WORK_QUEUE, new);
1357 return NULL;
1358 }
1359 new->size = 0;
1360 return new;
1361}
1362
paul4d38fdb2005-04-28 17:35:14 +00001363/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001364static void
paul4d38fdb2005-04-28 17:35:14 +00001365rib_queue_init (struct zebra_t *zebra)
1366{
1367 assert (zebra);
1368
1369 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001370 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001371 {
Paul Jakma6d691122006-07-27 21:49:00 +00001372 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001373 return;
1374 }
1375
1376 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001377 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001378 zebra->ribq->spec.errorfunc = NULL;
paul4d38fdb2005-04-28 17:35:14 +00001379 /* XXX: TODO: These should be runtime configurable via vty */
1380 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001381 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001382
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001383 if (!(zebra->mq = meta_queue_new ()))
1384 {
1385 zlog_err ("%s: could not initialise meta queue!", __func__);
1386 return;
1387 }
paul4d38fdb2005-04-28 17:35:14 +00001388 return;
paul718e3742002-12-13 20:15:29 +00001389}
1390
Paul Jakma6d691122006-07-27 21:49:00 +00001391/* RIB updates are processed via a queue of pointers to route_nodes.
1392 *
1393 * The queue length is bounded by the maximal size of the routing table,
1394 * as a route_node will not be requeued, if already queued.
1395 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001396 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1397 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1398 * and then submit route_node to queue for best-path selection later.
1399 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001400 *
1401 * Deleted RIBs are reaped during best-path selection.
1402 *
1403 * rib_addnode
1404 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001405 * |-------->| | best RIB, if required
1406 * | |
1407 * static_install->|->rib_addqueue...... -> rib_process
1408 * | |
1409 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001410 * |-> set RIB_ENTRY_REMOVE |
1411 * rib_delnode (RIB freed)
1412 *
1413 *
1414 * Queueing state for a route_node is kept in the head RIB entry, this
1415 * state must be preserved as and when the head RIB entry of a
1416 * route_node is changed by rib_unlink / rib_link. A small complication,
1417 * but saves having to allocate a dedicated object for this.
1418 *
1419 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1420 *
1421 * - route_nodes: refcounted by:
1422 * - RIBs attached to route_node:
1423 * - managed by: rib_link/unlink
1424 * - route_node processing queue
1425 * - managed by: rib_addqueue, rib_process.
1426 *
1427 */
1428
paul718e3742002-12-13 20:15:29 +00001429/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001430static void
Paul Jakma6d691122006-07-27 21:49:00 +00001431rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001432{
1433 struct rib *head;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001434 char buf[INET6_ADDRSTRLEN];
paul4d38fdb2005-04-28 17:35:14 +00001435
1436 assert (rib && rn);
1437
Paul Jakma6d691122006-07-27 21:49:00 +00001438 route_lock_node (rn); /* rn route table reference */
1439
1440 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001441 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001442 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001443 zlog_debug ("%s: %s/%d: rn %p, rib %p", __func__,
1444 buf, rn->p.prefixlen, rn, rib);
1445 }
Paul Jakma6d691122006-07-27 21:49:00 +00001446
paul718e3742002-12-13 20:15:29 +00001447 head = rn->info;
1448 if (head)
Paul Jakma6d691122006-07-27 21:49:00 +00001449 {
1450 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001451 zlog_debug ("%s: %s/%d: new head, rn_status copied over", __func__,
1452 buf, rn->p.prefixlen);
Paul Jakma6d691122006-07-27 21:49:00 +00001453 head->prev = rib;
1454 /* Transfer the rn status flags to the new head RIB */
1455 rib->rn_status = head->rn_status;
1456 }
paul718e3742002-12-13 20:15:29 +00001457 rib->next = head;
1458 rn->info = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001459 rib_queue_add (&zebrad, rn);
1460}
1461
1462static void
1463rib_addnode (struct route_node *rn, struct rib *rib)
1464{
1465 /* RIB node has been un-removed before route-node is processed.
1466 * route_node must hence already be on the queue for processing..
1467 */
1468 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1469 {
1470 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001471 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001472 char buf[INET6_ADDRSTRLEN];
1473 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001474 zlog_debug ("%s: %s/%d: rn %p, un-removed rib %p",
1475 __func__, buf, rn->p.prefixlen, rn, rib);
1476 }
Paul Jakma6d691122006-07-27 21:49:00 +00001477 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1478 return;
1479 }
1480 rib_link (rn, rib);
1481}
1482
1483static void
1484rib_unlink (struct route_node *rn, struct rib *rib)
1485{
1486 struct nexthop *nexthop, *next;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001487 char buf[INET6_ADDRSTRLEN];
Paul Jakma6d691122006-07-27 21:49:00 +00001488
1489 assert (rn && rib);
1490
1491 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001492 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001493 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001494 zlog_debug ("%s: %s/%d: rn %p, rib %p",
1495 __func__, buf, rn->p.prefixlen, rn, rib);
1496 }
Paul Jakma6d691122006-07-27 21:49:00 +00001497
1498 if (rib->next)
1499 rib->next->prev = rib->prev;
1500
1501 if (rib->prev)
1502 rib->prev->next = rib->next;
1503 else
1504 {
1505 rn->info = rib->next;
1506
1507 if (rn->info)
1508 {
1509 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001510 zlog_debug ("%s: %s/%d: rn %p, rib %p, new head copy",
1511 __func__, buf, rn->p.prefixlen, rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001512 rib->next->rn_status = rib->rn_status;
1513 }
1514 }
1515
1516 /* free RIB and nexthops */
1517 for (nexthop = rib->nexthop; nexthop; nexthop = next)
1518 {
1519 next = nexthop->next;
1520 nexthop_free (nexthop);
1521 }
1522 XFREE (MTYPE_RIB, rib);
1523
1524 route_unlock_node (rn); /* rn route table reference */
paul718e3742002-12-13 20:15:29 +00001525}
1526
paula1ac18c2005-06-28 17:17:12 +00001527static void
paul718e3742002-12-13 20:15:29 +00001528rib_delnode (struct route_node *rn, struct rib *rib)
1529{
Paul Jakma6d691122006-07-27 21:49:00 +00001530 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001531 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001532 char buf[INET6_ADDRSTRLEN];
1533 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001534 zlog_debug ("%s: %s/%d: rn %p, rib %p, removing", __func__,
1535 buf, rn->p.prefixlen, rn, rib);
1536 }
Paul Jakma6d691122006-07-27 21:49:00 +00001537 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1538 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001539}
1540
1541int
1542rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001543 struct in_addr *gate, struct in_addr *src,
1544 unsigned int ifindex, u_int32_t vrf_id,
paul718e3742002-12-13 20:15:29 +00001545 u_int32_t metric, u_char distance)
1546{
1547 struct rib *rib;
1548 struct rib *same = NULL;
1549 struct route_table *table;
1550 struct route_node *rn;
1551 struct nexthop *nexthop;
1552
1553 /* Lookup table. */
1554 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1555 if (! table)
1556 return 0;
1557
1558 /* Make it sure prefixlen is applied to the prefix. */
1559 apply_mask_ipv4 (p);
1560
1561 /* Set default distance by route type. */
1562 if (distance == 0)
1563 {
1564 distance = route_info[type].distance;
1565
1566 /* iBGP distance is 200. */
1567 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1568 distance = 200;
1569 }
1570
1571 /* Lookup route node.*/
1572 rn = route_node_get (table, (struct prefix *) p);
1573
1574 /* If same type of route are installed, treat it as a implicit
1575 withdraw. */
1576 for (rib = rn->info; rib; rib = rib->next)
1577 {
Paul Jakma6d691122006-07-27 21:49:00 +00001578 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1579 continue;
1580
hassoebf1ead2005-09-21 14:58:20 +00001581 if (rib->type != type)
1582 continue;
1583 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001584 {
1585 same = rib;
1586 break;
1587 }
hassoebf1ead2005-09-21 14:58:20 +00001588 /* Duplicate connected route comes in. */
1589 else if ((nexthop = rib->nexthop) &&
1590 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001591 nexthop->ifindex == ifindex &&
1592 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001593 {
1594 rib->refcnt++;
1595 return 0 ;
1596 }
paul718e3742002-12-13 20:15:29 +00001597 }
1598
1599 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001600 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001601 rib->type = type;
1602 rib->distance = distance;
1603 rib->flags = flags;
1604 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001605 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001606 rib->nexthop_num = 0;
1607 rib->uptime = time (NULL);
1608
1609 /* Nexthop settings. */
1610 if (gate)
1611 {
1612 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001613 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001614 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001615 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001616 }
1617 else
1618 nexthop_ifindex_add (rib, ifindex);
1619
1620 /* If this route is kernel route, set FIB flag to the route. */
1621 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1622 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1623 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1624
1625 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001626 if (IS_ZEBRA_DEBUG_RIB)
1627 zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
paul718e3742002-12-13 20:15:29 +00001628 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001629
paul718e3742002-12-13 20:15:29 +00001630 /* Free implicit route.*/
1631 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001632 {
1633 if (IS_ZEBRA_DEBUG_RIB)
1634 zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001635 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001636 }
paul4d38fdb2005-04-28 17:35:14 +00001637
1638 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001639 return 0;
1640}
1641
Denis Ovsienkodc958242007-08-13 16:03:06 +00001642/* This function dumps the contents of a given RIB entry into
1643 * standard debug log. Calling function name and IP prefix in
1644 * question are passed as 1st and 2nd arguments.
1645 */
1646
1647void rib_dump (const char * func, const struct prefix_ipv4 * p, const struct rib * rib)
1648{
1649 char straddr1[INET_ADDRSTRLEN], straddr2[INET_ADDRSTRLEN];
1650 struct nexthop *nexthop;
1651
1652 inet_ntop (AF_INET, &p->prefix, straddr1, INET_ADDRSTRLEN);
1653 zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr1, p->prefixlen);
1654 zlog_debug
1655 (
1656 "%s: refcnt == %lu, uptime == %u, type == %u, table == %d",
1657 func,
1658 rib->refcnt,
1659 rib->uptime,
1660 rib->type,
1661 rib->table
1662 );
1663 zlog_debug
1664 (
1665 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1666 func,
1667 rib->metric,
1668 rib->distance,
1669 rib->flags,
1670 rib->status
1671 );
1672 zlog_debug
1673 (
1674 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1675 func,
1676 rib->nexthop_num,
1677 rib->nexthop_active_num,
1678 rib->nexthop_fib_num
1679 );
1680 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1681 {
1682 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, straddr1, INET_ADDRSTRLEN);
1683 inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, straddr2, INET_ADDRSTRLEN);
1684 zlog_debug
1685 (
1686 "%s: NH %s (%s) with flags %s%s%s",
1687 func,
1688 straddr1,
1689 straddr2,
1690 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1691 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1692 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1693 );
1694 }
1695 zlog_debug ("%s: dump complete", func);
1696}
1697
1698/* This is an exported helper to rtm_read() to dump the strange
1699 * RIB entry found by rib_lookup_ipv4_route()
1700 */
1701
1702void rib_lookup_and_dump (struct prefix_ipv4 * p)
1703{
1704 struct route_table *table;
1705 struct route_node *rn;
1706 struct rib *rib;
1707 char prefix_buf[INET_ADDRSTRLEN];
1708
1709 /* Lookup table. */
1710 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1711 if (! table)
1712 {
1713 zlog_err ("%s: vrf_table() returned NULL", __func__);
1714 return;
1715 }
1716
1717 inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
1718 /* Scan the RIB table for exactly matching RIB entry. */
1719 rn = route_node_lookup (table, (struct prefix *) p);
1720
1721 /* No route for this prefix. */
1722 if (! rn)
1723 {
1724 zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
1725 return;
1726 }
1727
1728 /* Unlock node. */
1729 route_unlock_node (rn);
1730
1731 /* let's go */
1732 for (rib = rn->info; rib; rib = rib->next)
1733 {
1734 zlog_debug
1735 (
1736 "%s: rn %p, rib %p: %s, %s",
1737 __func__,
1738 rn,
1739 rib,
1740 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
1741 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
1742 );
1743 rib_dump (__func__, p, rib);
1744 }
1745}
1746
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001747/* Check if requested address assignment will fail due to another
1748 * route being installed by zebra in FIB already. Take necessary
1749 * actions, if needed: remove such a route from FIB and deSELECT
1750 * corresponding RIB entry. Then put affected RN into RIBQ head.
1751 */
1752void rib_lookup_and_pushup (struct prefix_ipv4 * p)
1753{
1754 struct route_table *table;
1755 struct route_node *rn;
1756 struct rib *rib;
1757 unsigned changed = 0;
1758
1759 if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
1760 {
1761 zlog_err ("%s: vrf_table() returned NULL", __func__);
1762 return;
1763 }
1764
1765 /* No matches would be the simplest case. */
1766 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
1767 return;
1768
1769 /* Unlock node. */
1770 route_unlock_node (rn);
1771
1772 /* Check all RIB entries. In case any changes have to be done, requeue
1773 * the RN into RIBQ head. If the routing message about the new connected
1774 * route (generated by the IP address we are going to assign very soon)
1775 * comes before the RIBQ is processed, the new RIB entry will join
1776 * RIBQ record already on head. This is necessary for proper revalidation
1777 * of the rest of the RIB.
1778 */
1779 for (rib = rn->info; rib; rib = rib->next)
1780 {
1781 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
1782 ! RIB_SYSTEM_ROUTE (rib))
1783 {
1784 changed = 1;
1785 if (IS_ZEBRA_DEBUG_RIB)
1786 {
1787 char buf[INET_ADDRSTRLEN];
1788 inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
1789 zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
1790 rib_dump (__func__, (struct prefix_ipv4 *)&rn->p, rib);
1791 }
1792 rib_uninstall (rn, rib);
1793 }
1794 }
1795 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001796 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001797}
1798
paul718e3742002-12-13 20:15:29 +00001799int
1800rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib)
1801{
1802 struct route_table *table;
1803 struct route_node *rn;
1804 struct rib *same;
1805 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00001806
paul718e3742002-12-13 20:15:29 +00001807 /* Lookup table. */
1808 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1809 if (! table)
1810 return 0;
paul718e3742002-12-13 20:15:29 +00001811 /* Make it sure prefixlen is applied to the prefix. */
1812 apply_mask_ipv4 (p);
1813
1814 /* Set default distance by route type. */
1815 if (rib->distance == 0)
1816 {
1817 rib->distance = route_info[rib->type].distance;
1818
1819 /* iBGP distance is 200. */
1820 if (rib->type == ZEBRA_ROUTE_BGP
1821 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1822 rib->distance = 200;
1823 }
1824
1825 /* Lookup route node.*/
1826 rn = route_node_get (table, (struct prefix *) p);
1827
1828 /* If same type of route are installed, treat it as a implicit
1829 withdraw. */
1830 for (same = rn->info; same; same = same->next)
1831 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00001832 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00001833 continue;
1834
paul718e3742002-12-13 20:15:29 +00001835 if (same->type == rib->type && same->table == rib->table
1836 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001837 break;
paul718e3742002-12-13 20:15:29 +00001838 }
paul4d38fdb2005-04-28 17:35:14 +00001839
paul718e3742002-12-13 20:15:29 +00001840 /* If this route is kernel route, set FIB flag to the route. */
1841 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
1842 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1843 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1844
1845 /* Link new rib to node.*/
1846 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001847 if (IS_ZEBRA_DEBUG_RIB)
1848 {
1849 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
1850 __func__, rn, rib);
1851 rib_dump (__func__, p, rib);
1852 }
paul718e3742002-12-13 20:15:29 +00001853
paul718e3742002-12-13 20:15:29 +00001854 /* Free implicit route.*/
1855 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001856 {
1857 if (IS_ZEBRA_DEBUG_RIB)
1858 {
1859 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
1860 __func__, rn, same);
1861 rib_dump (__func__, p, same);
1862 }
paul4d38fdb2005-04-28 17:35:14 +00001863 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001864 }
paul4d38fdb2005-04-28 17:35:14 +00001865
1866 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001867 return 0;
1868}
1869
hassoebf1ead2005-09-21 14:58:20 +00001870/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00001871int
1872rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
1873 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1874{
1875 struct route_table *table;
1876 struct route_node *rn;
1877 struct rib *rib;
1878 struct rib *fib = NULL;
1879 struct rib *same = NULL;
1880 struct nexthop *nexthop;
1881 char buf1[BUFSIZ];
1882 char buf2[BUFSIZ];
1883
1884 /* Lookup table. */
1885 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1886 if (! table)
1887 return 0;
1888
1889 /* Apply mask. */
1890 apply_mask_ipv4 (p);
1891
paul5ec90d22003-06-19 01:41:37 +00001892 if (IS_ZEBRA_DEBUG_KERNEL && gate)
ajsb6178002004-12-07 21:12:56 +00001893 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
paul5ec90d22003-06-19 01:41:37 +00001894 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1895 p->prefixlen,
1896 inet_ntoa (*gate),
1897 ifindex);
1898
paul718e3742002-12-13 20:15:29 +00001899 /* Lookup route node. */
1900 rn = route_node_lookup (table, (struct prefix *) p);
1901 if (! rn)
1902 {
1903 if (IS_ZEBRA_DEBUG_KERNEL)
1904 {
1905 if (gate)
ajsb6178002004-12-07 21:12:56 +00001906 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001907 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1908 p->prefixlen,
1909 inet_ntop (AF_INET, gate, buf2, BUFSIZ),
1910 ifindex);
1911 else
ajsb6178002004-12-07 21:12:56 +00001912 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001913 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1914 p->prefixlen,
1915 ifindex);
1916 }
1917 return ZEBRA_ERR_RTNOEXIST;
1918 }
1919
1920 /* Lookup same type route. */
1921 for (rib = rn->info; rib; rib = rib->next)
1922 {
Paul Jakma6d691122006-07-27 21:49:00 +00001923 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1924 continue;
1925
paul718e3742002-12-13 20:15:29 +00001926 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1927 fib = rib;
1928
hassoebf1ead2005-09-21 14:58:20 +00001929 if (rib->type != type)
1930 continue;
1931 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
1932 nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex)
paul718e3742002-12-13 20:15:29 +00001933 {
hassoebf1ead2005-09-21 14:58:20 +00001934 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00001935 {
hassoebf1ead2005-09-21 14:58:20 +00001936 rib->refcnt--;
1937 route_unlock_node (rn);
1938 route_unlock_node (rn);
1939 return 0;
paul718e3742002-12-13 20:15:29 +00001940 }
hassoebf1ead2005-09-21 14:58:20 +00001941 same = rib;
1942 break;
paul718e3742002-12-13 20:15:29 +00001943 }
hassoebf1ead2005-09-21 14:58:20 +00001944 /* Make sure that the route found has the same gateway. */
1945 else if (gate == NULL ||
1946 ((nexthop = rib->nexthop) &&
1947 (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
1948 IPV4_ADDR_SAME (&nexthop->rgate.ipv4, gate))))
paul5ec90d22003-06-19 01:41:37 +00001949 {
hassoebf1ead2005-09-21 14:58:20 +00001950 same = rib;
1951 break;
paul718e3742002-12-13 20:15:29 +00001952 }
1953 }
1954
1955 /* If same type of route can't be found and this message is from
1956 kernel. */
1957 if (! same)
1958 {
1959 if (fib && type == ZEBRA_ROUTE_KERNEL)
1960 {
1961 /* Unset flags. */
1962 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1963 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1964
1965 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1966 }
1967 else
1968 {
1969 if (IS_ZEBRA_DEBUG_KERNEL)
1970 {
1971 if (gate)
ajsb6178002004-12-07 21:12:56 +00001972 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001973 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1974 p->prefixlen,
1975 inet_ntop (AF_INET, gate, buf2, BUFSIZ),
1976 ifindex,
1977 type);
1978 else
ajsb6178002004-12-07 21:12:56 +00001979 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00001980 inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
1981 p->prefixlen,
1982 ifindex,
1983 type);
1984 }
1985 route_unlock_node (rn);
1986 return ZEBRA_ERR_RTNOEXIST;
1987 }
1988 }
paul4d38fdb2005-04-28 17:35:14 +00001989
paul718e3742002-12-13 20:15:29 +00001990 if (same)
1991 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00001992
paul718e3742002-12-13 20:15:29 +00001993 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001994 return 0;
1995}
1996
1997/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00001998static void
paul718e3742002-12-13 20:15:29 +00001999static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
2000{
2001 struct rib *rib;
2002 struct route_node *rn;
2003 struct route_table *table;
2004
2005 /* Lookup table. */
2006 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2007 if (! table)
2008 return;
2009
2010 /* Lookup existing route */
2011 rn = route_node_get (table, p);
2012 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002013 {
2014 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2015 continue;
2016
2017 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2018 break;
2019 }
paul718e3742002-12-13 20:15:29 +00002020
2021 if (rib)
2022 {
2023 /* Same distance static route is there. Update it with new
2024 nexthop. */
paul718e3742002-12-13 20:15:29 +00002025 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002026 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002027 {
2028 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002029 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002030 break;
2031 case STATIC_IPV4_IFNAME:
2032 nexthop_ifname_add (rib, si->gate.ifname);
2033 break;
2034 case STATIC_IPV4_BLACKHOLE:
2035 nexthop_blackhole_add (rib);
2036 break;
paul4d38fdb2005-04-28 17:35:14 +00002037 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002038 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002039 }
2040 else
2041 {
2042 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002043 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2044
paul718e3742002-12-13 20:15:29 +00002045 rib->type = ZEBRA_ROUTE_STATIC;
2046 rib->distance = si->distance;
2047 rib->metric = 0;
2048 rib->nexthop_num = 0;
2049
2050 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002051 {
2052 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002053 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002054 break;
2055 case STATIC_IPV4_IFNAME:
2056 nexthop_ifname_add (rib, si->gate.ifname);
2057 break;
2058 case STATIC_IPV4_BLACKHOLE:
2059 nexthop_blackhole_add (rib);
2060 break;
2061 }
paul718e3742002-12-13 20:15:29 +00002062
hasso81dfcaa2003-05-25 19:21:25 +00002063 /* Save the flags of this static routes (reject, blackhole) */
2064 rib->flags = si->flags;
2065
paul718e3742002-12-13 20:15:29 +00002066 /* Link this rib to the tree. */
2067 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002068 }
2069}
2070
paula1ac18c2005-06-28 17:17:12 +00002071static int
paul718e3742002-12-13 20:15:29 +00002072static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2073{
2074 if (nexthop->type == NEXTHOP_TYPE_IPV4
2075 && si->type == STATIC_IPV4_GATEWAY
2076 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2077 return 1;
2078 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2079 && si->type == STATIC_IPV4_IFNAME
2080 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2081 return 1;
paul595db7f2003-05-25 21:35:06 +00002082 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2083 && si->type == STATIC_IPV4_BLACKHOLE)
2084 return 1;
paule8e19462006-01-19 20:16:55 +00002085 return 0;
paul718e3742002-12-13 20:15:29 +00002086}
2087
2088/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002089static void
paul718e3742002-12-13 20:15:29 +00002090static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
2091{
2092 struct route_node *rn;
2093 struct rib *rib;
2094 struct nexthop *nexthop;
2095 struct route_table *table;
2096
2097 /* Lookup table. */
2098 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2099 if (! table)
2100 return;
paul4d38fdb2005-04-28 17:35:14 +00002101
paul718e3742002-12-13 20:15:29 +00002102 /* Lookup existing route with type and distance. */
2103 rn = route_node_lookup (table, p);
2104 if (! rn)
2105 return;
2106
2107 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002108 {
2109 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2110 continue;
2111
2112 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2113 break;
2114 }
paul718e3742002-12-13 20:15:29 +00002115
2116 if (! rib)
2117 {
2118 route_unlock_node (rn);
2119 return;
2120 }
2121
2122 /* Lookup nexthop. */
2123 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2124 if (static_ipv4_nexthop_same (nexthop, si))
2125 break;
2126
2127 /* Can't find nexthop. */
2128 if (! nexthop)
2129 {
2130 route_unlock_node (rn);
2131 return;
2132 }
2133
2134 /* Check nexthop. */
2135 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002136 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002137 else
2138 {
paul6baeb982003-10-28 03:47:15 +00002139 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2140 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002141 nexthop_delete (rib, nexthop);
2142 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002143 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002144 }
paul718e3742002-12-13 20:15:29 +00002145 /* Unlock node. */
2146 route_unlock_node (rn);
2147}
2148
2149/* Add static route into static route configuration. */
2150int
hasso39db97e2004-10-12 20:50:58 +00002151static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00002152 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002153{
2154 u_char type = 0;
2155 struct route_node *rn;
2156 struct static_ipv4 *si;
2157 struct static_ipv4 *pp;
2158 struct static_ipv4 *cp;
2159 struct static_ipv4 *update = NULL;
2160 struct route_table *stable;
2161
2162 /* Lookup table. */
2163 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2164 if (! stable)
2165 return -1;
2166
2167 /* Lookup static route prefix. */
2168 rn = route_node_get (stable, p);
2169
2170 /* Make flags. */
2171 if (gate)
2172 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002173 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002174 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002175 else
2176 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002177
2178 /* Do nothing if there is a same static route. */
2179 for (si = rn->info; si; si = si->next)
2180 {
2181 if (type == si->type
2182 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2183 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2184 {
2185 if (distance == si->distance)
2186 {
2187 route_unlock_node (rn);
2188 return 0;
2189 }
2190 else
2191 update = si;
2192 }
2193 }
2194
Paul Jakma3c0755d2006-12-08 00:53:14 +00002195 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002196 if (update)
2197 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
2198
2199 /* Make new static route structure. */
2200 si = XMALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
2201 memset (si, 0, sizeof (struct static_ipv4));
2202
2203 si->type = type;
2204 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002205 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002206
2207 if (gate)
2208 si->gate.ipv4 = *gate;
2209 if (ifname)
2210 si->gate.ifname = XSTRDUP (0, ifname);
2211
2212 /* Add new static route information to the tree with sort by
2213 distance value and gateway address. */
2214 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2215 {
2216 if (si->distance < cp->distance)
2217 break;
2218 if (si->distance > cp->distance)
2219 continue;
2220 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2221 {
2222 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2223 break;
2224 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2225 continue;
2226 }
2227 }
2228
2229 /* Make linked list. */
2230 if (pp)
2231 pp->next = si;
2232 else
2233 rn->info = si;
2234 if (cp)
2235 cp->prev = si;
2236 si->prev = pp;
2237 si->next = cp;
2238
2239 /* Install into rib. */
2240 static_install_ipv4 (p, si);
2241
2242 return 1;
2243}
2244
2245/* Delete static route from static route configuration. */
2246int
hasso39db97e2004-10-12 20:50:58 +00002247static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00002248 u_char distance, u_int32_t vrf_id)
2249{
2250 u_char type = 0;
2251 struct route_node *rn;
2252 struct static_ipv4 *si;
2253 struct route_table *stable;
2254
2255 /* Lookup table. */
2256 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2257 if (! stable)
2258 return -1;
2259
2260 /* Lookup static route prefix. */
2261 rn = route_node_lookup (stable, p);
2262 if (! rn)
2263 return 0;
2264
2265 /* Make flags. */
2266 if (gate)
2267 type = STATIC_IPV4_GATEWAY;
2268 else if (ifname)
2269 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002270 else
2271 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002272
2273 /* Find same static route is the tree */
2274 for (si = rn->info; si; si = si->next)
2275 if (type == si->type
2276 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2277 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2278 break;
2279
2280 /* Can't find static route. */
2281 if (! si)
2282 {
2283 route_unlock_node (rn);
2284 return 0;
2285 }
2286
2287 /* Install into rib. */
2288 static_uninstall_ipv4 (p, si);
2289
2290 /* Unlink static route from linked list. */
2291 if (si->prev)
2292 si->prev->next = si->next;
2293 else
2294 rn->info = si->next;
2295 if (si->next)
2296 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002297 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002298
2299 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002300 if (ifname)
2301 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002302 XFREE (MTYPE_STATIC_IPV4, si);
2303
paul143a3852003-09-29 20:06:13 +00002304 route_unlock_node (rn);
2305
paul718e3742002-12-13 20:15:29 +00002306 return 1;
2307}
2308
2309
2310#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00002311static int
paul718e3742002-12-13 20:15:29 +00002312rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2313 struct in6_addr *gate, unsigned int ifindex, int table)
2314{
hasso726f9b22003-05-25 21:04:54 +00002315 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2316#if defined (MUSICA) || defined (LINUX)
2317 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2318 if (p->prefixlen == 96)
2319 return 0;
2320#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00002321 return 1;
hasso726f9b22003-05-25 21:04:54 +00002322 }
paul718e3742002-12-13 20:15:29 +00002323 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
2324 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
2325 {
2326 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
2327 return 1;
2328 }
2329 return 0;
2330}
2331
2332int
2333rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00002334 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
2335 u_int32_t metric, u_char distance)
paul718e3742002-12-13 20:15:29 +00002336{
2337 struct rib *rib;
2338 struct rib *same = NULL;
2339 struct route_table *table;
2340 struct route_node *rn;
2341 struct nexthop *nexthop;
2342
paul718e3742002-12-13 20:15:29 +00002343 /* Lookup table. */
2344 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2345 if (! table)
2346 return 0;
2347
2348 /* Make sure mask is applied. */
2349 apply_mask_ipv6 (p);
2350
2351 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002352 if (!distance)
2353 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002354
2355 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2356 distance = 200;
2357
2358 /* Filter bogus route. */
2359 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
2360 return 0;
2361
2362 /* Lookup route node.*/
2363 rn = route_node_get (table, (struct prefix *) p);
2364
2365 /* If same type of route are installed, treat it as a implicit
2366 withdraw. */
2367 for (rib = rn->info; rib; rib = rib->next)
2368 {
Paul Jakma6d691122006-07-27 21:49:00 +00002369 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2370 continue;
2371
hassoebf1ead2005-09-21 14:58:20 +00002372 if (rib->type != type)
2373 continue;
2374 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002375 {
2376 same = rib;
paul718e3742002-12-13 20:15:29 +00002377 break;
2378 }
hassoebf1ead2005-09-21 14:58:20 +00002379 else if ((nexthop = rib->nexthop) &&
2380 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2381 nexthop->ifindex == ifindex)
2382 {
2383 rib->refcnt++;
2384 return 0;
2385 }
paul718e3742002-12-13 20:15:29 +00002386 }
2387
2388 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002389 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2390
paul718e3742002-12-13 20:15:29 +00002391 rib->type = type;
2392 rib->distance = distance;
2393 rib->flags = flags;
2394 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00002395 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00002396 rib->nexthop_num = 0;
2397 rib->uptime = time (NULL);
2398
2399 /* Nexthop settings. */
2400 if (gate)
2401 {
2402 if (ifindex)
2403 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2404 else
2405 nexthop_ipv6_add (rib, gate);
2406 }
2407 else
2408 nexthop_ifindex_add (rib, ifindex);
2409
2410 /* If this route is kernel route, set FIB flag to the route. */
2411 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2412 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2413 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2414
2415 /* Link new rib to node.*/
2416 rib_addnode (rn, rib);
2417
paul718e3742002-12-13 20:15:29 +00002418 /* Free implicit route.*/
2419 if (same)
paul4d38fdb2005-04-28 17:35:14 +00002420 rib_delnode (rn, same);
2421
2422 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002423 return 0;
2424}
2425
hassoebf1ead2005-09-21 14:58:20 +00002426/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002427int
2428rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
2429 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
2430{
2431 struct route_table *table;
2432 struct route_node *rn;
2433 struct rib *rib;
2434 struct rib *fib = NULL;
2435 struct rib *same = NULL;
2436 struct nexthop *nexthop;
2437 char buf1[BUFSIZ];
2438 char buf2[BUFSIZ];
2439
2440 /* Apply mask. */
2441 apply_mask_ipv6 (p);
2442
2443 /* Lookup table. */
2444 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2445 if (! table)
2446 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002447
paul718e3742002-12-13 20:15:29 +00002448 /* Lookup route node. */
2449 rn = route_node_lookup (table, (struct prefix *) p);
2450 if (! rn)
2451 {
2452 if (IS_ZEBRA_DEBUG_KERNEL)
2453 {
2454 if (gate)
ajsb6178002004-12-07 21:12:56 +00002455 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00002456 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
2457 p->prefixlen,
2458 inet_ntop (AF_INET6, gate, buf2, BUFSIZ),
2459 ifindex);
2460 else
ajsb6178002004-12-07 21:12:56 +00002461 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00002462 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
2463 p->prefixlen,
2464 ifindex);
2465 }
2466 return ZEBRA_ERR_RTNOEXIST;
2467 }
2468
2469 /* Lookup same type route. */
2470 for (rib = rn->info; rib; rib = rib->next)
2471 {
Paul Jakma6d691122006-07-27 21:49:00 +00002472 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2473 continue;
2474
paul718e3742002-12-13 20:15:29 +00002475 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2476 fib = rib;
2477
hassoebf1ead2005-09-21 14:58:20 +00002478 if (rib->type != type)
2479 continue;
2480 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
2481 nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex)
paul718e3742002-12-13 20:15:29 +00002482 {
hassoebf1ead2005-09-21 14:58:20 +00002483 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002484 {
hassoebf1ead2005-09-21 14:58:20 +00002485 rib->refcnt--;
2486 route_unlock_node (rn);
2487 route_unlock_node (rn);
2488 return 0;
paul718e3742002-12-13 20:15:29 +00002489 }
hassoebf1ead2005-09-21 14:58:20 +00002490 same = rib;
2491 break;
paul718e3742002-12-13 20:15:29 +00002492 }
hassoebf1ead2005-09-21 14:58:20 +00002493 /* Make sure that the route found has the same gateway. */
2494 else if (gate == NULL ||
2495 ((nexthop = rib->nexthop) &&
2496 (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate) ||
2497 IPV6_ADDR_SAME (&nexthop->rgate.ipv6, gate))))
paul718e3742002-12-13 20:15:29 +00002498 {
hassoebf1ead2005-09-21 14:58:20 +00002499 same = rib;
2500 break;
paul718e3742002-12-13 20:15:29 +00002501 }
2502 }
2503
2504 /* If same type of route can't be found and this message is from
2505 kernel. */
2506 if (! same)
2507 {
2508 if (fib && type == ZEBRA_ROUTE_KERNEL)
2509 {
2510 /* Unset flags. */
2511 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2512 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2513
2514 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2515 }
2516 else
2517 {
2518 if (IS_ZEBRA_DEBUG_KERNEL)
2519 {
2520 if (gate)
ajsb6178002004-12-07 21:12:56 +00002521 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00002522 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
2523 p->prefixlen,
2524 inet_ntop (AF_INET6, gate, buf2, BUFSIZ),
2525 ifindex,
2526 type);
2527 else
ajsb6178002004-12-07 21:12:56 +00002528 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
paul718e3742002-12-13 20:15:29 +00002529 inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
2530 p->prefixlen,
2531 ifindex,
2532 type);
2533 }
2534 route_unlock_node (rn);
2535 return ZEBRA_ERR_RTNOEXIST;
2536 }
2537 }
2538
2539 if (same)
2540 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002541
paul718e3742002-12-13 20:15:29 +00002542 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002543 return 0;
2544}
2545
2546/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002547static void
paul718e3742002-12-13 20:15:29 +00002548static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2549{
2550 struct rib *rib;
2551 struct route_table *table;
2552 struct route_node *rn;
2553
2554 /* Lookup table. */
2555 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2556 if (! table)
2557 return;
2558
2559 /* Lookup existing route */
2560 rn = route_node_get (table, p);
2561 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002562 {
2563 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2564 continue;
2565
2566 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2567 break;
2568 }
paul718e3742002-12-13 20:15:29 +00002569
2570 if (rib)
2571 {
2572 /* Same distance static route is there. Update it with new
2573 nexthop. */
paul718e3742002-12-13 20:15:29 +00002574 route_unlock_node (rn);
2575
2576 switch (si->type)
2577 {
2578 case STATIC_IPV6_GATEWAY:
2579 nexthop_ipv6_add (rib, &si->ipv6);
2580 break;
2581 case STATIC_IPV6_IFNAME:
2582 nexthop_ifname_add (rib, si->ifname);
2583 break;
2584 case STATIC_IPV6_GATEWAY_IFNAME:
2585 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2586 break;
2587 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002588 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002589 }
2590 else
2591 {
2592 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002593 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2594
paul718e3742002-12-13 20:15:29 +00002595 rib->type = ZEBRA_ROUTE_STATIC;
2596 rib->distance = si->distance;
2597 rib->metric = 0;
2598 rib->nexthop_num = 0;
2599
2600 switch (si->type)
2601 {
2602 case STATIC_IPV6_GATEWAY:
2603 nexthop_ipv6_add (rib, &si->ipv6);
2604 break;
2605 case STATIC_IPV6_IFNAME:
2606 nexthop_ifname_add (rib, si->ifname);
2607 break;
2608 case STATIC_IPV6_GATEWAY_IFNAME:
2609 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2610 break;
2611 }
2612
hasso81dfcaa2003-05-25 19:21:25 +00002613 /* Save the flags of this static routes (reject, blackhole) */
2614 rib->flags = si->flags;
2615
paul718e3742002-12-13 20:15:29 +00002616 /* Link this rib to the tree. */
2617 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002618 }
2619}
2620
paula1ac18c2005-06-28 17:17:12 +00002621static int
paul718e3742002-12-13 20:15:29 +00002622static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2623{
2624 if (nexthop->type == NEXTHOP_TYPE_IPV6
2625 && si->type == STATIC_IPV6_GATEWAY
2626 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2627 return 1;
2628 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2629 && si->type == STATIC_IPV6_IFNAME
2630 && strcmp (nexthop->ifname, si->ifname) == 0)
2631 return 1;
2632 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2633 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2634 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2635 && strcmp (nexthop->ifname, si->ifname) == 0)
2636 return 1;
paule8e19462006-01-19 20:16:55 +00002637 return 0;
paul718e3742002-12-13 20:15:29 +00002638}
2639
paula1ac18c2005-06-28 17:17:12 +00002640static void
paul718e3742002-12-13 20:15:29 +00002641static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2642{
2643 struct route_table *table;
2644 struct route_node *rn;
2645 struct rib *rib;
2646 struct nexthop *nexthop;
2647
2648 /* Lookup table. */
2649 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2650 if (! table)
2651 return;
2652
2653 /* Lookup existing route with type and distance. */
2654 rn = route_node_lookup (table, (struct prefix *) p);
2655 if (! rn)
2656 return;
2657
2658 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002659 {
2660 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2661 continue;
2662
2663 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2664 break;
2665 }
2666
paul718e3742002-12-13 20:15:29 +00002667 if (! rib)
2668 {
2669 route_unlock_node (rn);
2670 return;
2671 }
2672
2673 /* Lookup nexthop. */
2674 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2675 if (static_ipv6_nexthop_same (nexthop, si))
2676 break;
2677
2678 /* Can't find nexthop. */
2679 if (! nexthop)
2680 {
2681 route_unlock_node (rn);
2682 return;
2683 }
2684
2685 /* Check nexthop. */
2686 if (rib->nexthop_num == 1)
2687 {
2688 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002689 }
2690 else
2691 {
paul6baeb982003-10-28 03:47:15 +00002692 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2693 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002694 nexthop_delete (rib, nexthop);
2695 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002696 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002697 }
paul718e3742002-12-13 20:15:29 +00002698 /* Unlock node. */
2699 route_unlock_node (rn);
2700}
2701
2702/* Add static route into static route configuration. */
2703int
2704static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002705 const char *ifname, u_char flags, u_char distance,
2706 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002707{
2708 struct route_node *rn;
2709 struct static_ipv6 *si;
2710 struct static_ipv6 *pp;
2711 struct static_ipv6 *cp;
2712 struct route_table *stable;
2713
2714 /* Lookup table. */
2715 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2716 if (! stable)
2717 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00002718
2719 if (!gate &&
2720 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
2721 return -1;
2722
2723 if (!ifname &&
2724 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
2725 return -1;
paul718e3742002-12-13 20:15:29 +00002726
2727 /* Lookup static route prefix. */
2728 rn = route_node_get (stable, p);
2729
2730 /* Do nothing if there is a same static route. */
2731 for (si = rn->info; si; si = si->next)
2732 {
2733 if (distance == si->distance
2734 && type == si->type
2735 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2736 && (! ifname || strcmp (ifname, si->ifname) == 0))
2737 {
2738 route_unlock_node (rn);
2739 return 0;
2740 }
2741 }
2742
2743 /* Make new static route structure. */
2744 si = XMALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
2745 memset (si, 0, sizeof (struct static_ipv6));
2746
2747 si->type = type;
2748 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002749 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002750
2751 switch (type)
2752 {
2753 case STATIC_IPV6_GATEWAY:
2754 si->ipv6 = *gate;
2755 break;
2756 case STATIC_IPV6_IFNAME:
2757 si->ifname = XSTRDUP (0, ifname);
2758 break;
2759 case STATIC_IPV6_GATEWAY_IFNAME:
2760 si->ipv6 = *gate;
2761 si->ifname = XSTRDUP (0, ifname);
2762 break;
2763 }
2764
2765 /* Add new static route information to the tree with sort by
2766 distance value and gateway address. */
2767 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2768 {
2769 if (si->distance < cp->distance)
2770 break;
2771 if (si->distance > cp->distance)
2772 continue;
2773 }
2774
2775 /* Make linked list. */
2776 if (pp)
2777 pp->next = si;
2778 else
2779 rn->info = si;
2780 if (cp)
2781 cp->prev = si;
2782 si->prev = pp;
2783 si->next = cp;
2784
2785 /* Install into rib. */
2786 static_install_ipv6 (p, si);
2787
2788 return 1;
2789}
2790
2791/* Delete static route from static route configuration. */
2792int
2793static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002794 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002795{
2796 struct route_node *rn;
2797 struct static_ipv6 *si;
2798 struct route_table *stable;
2799
2800 /* Lookup table. */
2801 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2802 if (! stable)
2803 return -1;
2804
2805 /* Lookup static route prefix. */
2806 rn = route_node_lookup (stable, p);
2807 if (! rn)
2808 return 0;
2809
2810 /* Find same static route is the tree */
2811 for (si = rn->info; si; si = si->next)
2812 if (distance == si->distance
2813 && type == si->type
2814 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2815 && (! ifname || strcmp (ifname, si->ifname) == 0))
2816 break;
2817
2818 /* Can't find static route. */
2819 if (! si)
2820 {
2821 route_unlock_node (rn);
2822 return 0;
2823 }
2824
2825 /* Install into rib. */
2826 static_uninstall_ipv6 (p, si);
2827
2828 /* Unlink static route from linked list. */
2829 if (si->prev)
2830 si->prev->next = si->next;
2831 else
2832 rn->info = si->next;
2833 if (si->next)
2834 si->next->prev = si->prev;
2835
2836 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002837 if (ifname)
2838 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00002839 XFREE (MTYPE_STATIC_IPV6, si);
2840
2841 return 1;
2842}
2843#endif /* HAVE_IPV6 */
2844
2845/* RIB update function. */
2846void
paula1ac18c2005-06-28 17:17:12 +00002847rib_update (void)
paul718e3742002-12-13 20:15:29 +00002848{
2849 struct route_node *rn;
2850 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00002851
paul718e3742002-12-13 20:15:29 +00002852 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2853 if (table)
2854 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002855 if (rn->info)
Paul Jakma6d691122006-07-27 21:49:00 +00002856 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002857
2858 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2859 if (table)
2860 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002861 if (rn->info)
Paul Jakma6d691122006-07-27 21:49:00 +00002862 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002863}
2864
2865/* Interface goes up. */
paula1ac18c2005-06-28 17:17:12 +00002866static void
paul718e3742002-12-13 20:15:29 +00002867rib_if_up (struct interface *ifp)
2868{
2869 rib_update ();
2870}
2871
2872/* Interface goes down. */
paula1ac18c2005-06-28 17:17:12 +00002873static void
paul718e3742002-12-13 20:15:29 +00002874rib_if_down (struct interface *ifp)
2875{
2876 rib_update ();
2877}
2878
2879/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00002880static void
paul718e3742002-12-13 20:15:29 +00002881rib_weed_table (struct route_table *table)
2882{
2883 struct route_node *rn;
2884 struct rib *rib;
2885 struct rib *next;
2886
2887 if (table)
2888 for (rn = route_top (table); rn; rn = route_next (rn))
2889 for (rib = rn->info; rib; rib = next)
2890 {
2891 next = rib->next;
2892
Paul Jakma6d691122006-07-27 21:49:00 +00002893 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2894 continue;
2895
paulb21b19c2003-06-15 01:28:29 +00002896 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00002897 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00002898 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002899 }
2900}
2901
2902/* Delete all routes from non main table. */
2903void
paula1ac18c2005-06-28 17:17:12 +00002904rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00002905{
2906 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2907 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2908}
2909
2910/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00002911static void
paul718e3742002-12-13 20:15:29 +00002912rib_sweep_table (struct route_table *table)
2913{
2914 struct route_node *rn;
2915 struct rib *rib;
2916 struct rib *next;
2917 int ret = 0;
2918
2919 if (table)
2920 for (rn = route_top (table); rn; rn = route_next (rn))
2921 for (rib = rn->info; rib; rib = next)
2922 {
2923 next = rib->next;
2924
Paul Jakma6d691122006-07-27 21:49:00 +00002925 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2926 continue;
2927
paul718e3742002-12-13 20:15:29 +00002928 if (rib->type == ZEBRA_ROUTE_KERNEL &&
2929 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
2930 {
2931 ret = rib_uninstall_kernel (rn, rib);
2932 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00002933 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002934 }
2935 }
2936}
2937
2938/* Sweep all RIB tables. */
2939void
paula1ac18c2005-06-28 17:17:12 +00002940rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00002941{
2942 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2943 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2944}
2945
2946/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00002947static void
paul718e3742002-12-13 20:15:29 +00002948rib_close_table (struct route_table *table)
2949{
2950 struct route_node *rn;
2951 struct rib *rib;
2952
2953 if (table)
2954 for (rn = route_top (table); rn; rn = route_next (rn))
2955 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002956 {
2957 if (! RIB_SYSTEM_ROUTE (rib)
2958 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2959 rib_uninstall_kernel (rn, rib);
2960 }
paul718e3742002-12-13 20:15:29 +00002961}
2962
2963/* Close all RIB tables. */
2964void
paula1ac18c2005-06-28 17:17:12 +00002965rib_close (void)
paul718e3742002-12-13 20:15:29 +00002966{
2967 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2968 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2969}
2970
2971/* Routing information base initialize. */
2972void
paula1ac18c2005-06-28 17:17:12 +00002973rib_init (void)
paul718e3742002-12-13 20:15:29 +00002974{
paul4d38fdb2005-04-28 17:35:14 +00002975 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00002976 /* VRF initialization. */
2977 vrf_init ();
2978}