blob: 12f3fa5a5b912c32a8a658c27d714e7c545da8b7 [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
paul718e3742002-12-13 20:15:29 +000096/* Lookup VRF by identifier. */
97struct vrf *
98vrf_lookup (u_int32_t id)
99{
100 return vector_lookup (vrf_vector, id);
101}
102
paul718e3742002-12-13 20:15:29 +0000103/* Initialize VRF. */
paula1ac18c2005-06-28 17:17:12 +0000104static void
105vrf_init (void)
paul718e3742002-12-13 20:15:29 +0000106{
107 struct vrf *default_table;
108
109 /* Allocate VRF vector. */
110 vrf_vector = vector_init (1);
111
112 /* Allocate default main table. */
113 default_table = vrf_alloc ("Default-IP-Routing-Table");
114
115 /* Default table index must be 0. */
116 vector_set_index (vrf_vector, 0, default_table);
117}
118
119/* Lookup route table. */
120struct route_table *
121vrf_table (afi_t afi, safi_t safi, u_int32_t id)
122{
123 struct vrf *vrf;
124
125 vrf = vrf_lookup (id);
126 if (! vrf)
127 return NULL;
128
129 return vrf->table[afi][safi];
130}
131
132/* Lookup static route table. */
133struct route_table *
134vrf_static_table (afi_t afi, safi_t safi, u_int32_t id)
135{
136 struct vrf *vrf;
137
138 vrf = vrf_lookup (id);
139 if (! vrf)
140 return NULL;
141
142 return vrf->stable[afi][safi];
143}
144
145/* Add nexthop to the end of the list. */
paula1ac18c2005-06-28 17:17:12 +0000146static void
paul718e3742002-12-13 20:15:29 +0000147nexthop_add (struct rib *rib, struct nexthop *nexthop)
148{
149 struct nexthop *last;
150
151 for (last = rib->nexthop; last && last->next; last = last->next)
152 ;
153 if (last)
154 last->next = nexthop;
155 else
156 rib->nexthop = nexthop;
157 nexthop->prev = last;
158
159 rib->nexthop_num++;
160}
161
162/* Delete specified nexthop from the list. */
paula1ac18c2005-06-28 17:17:12 +0000163static void
paul718e3742002-12-13 20:15:29 +0000164nexthop_delete (struct rib *rib, struct nexthop *nexthop)
165{
166 if (nexthop->next)
167 nexthop->next->prev = nexthop->prev;
168 if (nexthop->prev)
169 nexthop->prev->next = nexthop->next;
170 else
171 rib->nexthop = nexthop->next;
172 rib->nexthop_num--;
173}
174
175/* Free nexthop. */
paula1ac18c2005-06-28 17:17:12 +0000176static void
paul718e3742002-12-13 20:15:29 +0000177nexthop_free (struct nexthop *nexthop)
178{
paula4b70762003-05-16 17:19:48 +0000179 if (nexthop->ifname)
180 XFREE (0, nexthop->ifname);
paul718e3742002-12-13 20:15:29 +0000181 XFREE (MTYPE_NEXTHOP, nexthop);
182}
183
184struct nexthop *
185nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
186{
187 struct nexthop *nexthop;
188
Stephen Hemminger393deb92008-08-18 14:13:29 -0700189 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000190 nexthop->type = NEXTHOP_TYPE_IFINDEX;
191 nexthop->ifindex = ifindex;
192
193 nexthop_add (rib, nexthop);
194
195 return nexthop;
196}
197
198struct nexthop *
199nexthop_ifname_add (struct rib *rib, char *ifname)
200{
201 struct nexthop *nexthop;
202
Stephen Hemminger393deb92008-08-18 14:13:29 -0700203 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000204 nexthop->type = NEXTHOP_TYPE_IFNAME;
paula4b70762003-05-16 17:19:48 +0000205 nexthop->ifname = XSTRDUP (0, ifname);
paul718e3742002-12-13 20:15:29 +0000206
207 nexthop_add (rib, nexthop);
208
209 return nexthop;
210}
211
212struct nexthop *
Paul Jakma7514fb72007-05-02 16:05:35 +0000213nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src)
paul718e3742002-12-13 20:15:29 +0000214{
215 struct nexthop *nexthop;
216
Stephen Hemminger393deb92008-08-18 14:13:29 -0700217 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000218 nexthop->type = NEXTHOP_TYPE_IPV4;
219 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000220 if (src)
221 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000222
223 nexthop_add (rib, nexthop);
224
225 return nexthop;
226}
227
paula1ac18c2005-06-28 17:17:12 +0000228static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000229nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
Paul Jakma7514fb72007-05-02 16:05:35 +0000230 struct in_addr *src, unsigned int ifindex)
paul718e3742002-12-13 20:15:29 +0000231{
232 struct nexthop *nexthop;
233
Stephen Hemminger393deb92008-08-18 14:13:29 -0700234 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000235 nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
236 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000237 if (src)
238 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000239 nexthop->ifindex = ifindex;
240
241 nexthop_add (rib, nexthop);
242
243 return nexthop;
244}
245
246#ifdef HAVE_IPV6
247struct nexthop *
248nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
249{
250 struct nexthop *nexthop;
251
Stephen Hemminger393deb92008-08-18 14:13:29 -0700252 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000253 nexthop->type = NEXTHOP_TYPE_IPV6;
254 nexthop->gate.ipv6 = *ipv6;
255
256 nexthop_add (rib, nexthop);
257
258 return nexthop;
259}
260
paula1ac18c2005-06-28 17:17:12 +0000261static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000262nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
263 char *ifname)
264{
265 struct nexthop *nexthop;
266
Stephen Hemminger393deb92008-08-18 14:13:29 -0700267 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000268 nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
269 nexthop->gate.ipv6 = *ipv6;
270 nexthop->ifname = XSTRDUP (0, ifname);
271
272 nexthop_add (rib, nexthop);
273
274 return nexthop;
275}
276
paula1ac18c2005-06-28 17:17:12 +0000277static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000278nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
279 unsigned int ifindex)
280{
281 struct nexthop *nexthop;
282
Stephen Hemminger393deb92008-08-18 14:13:29 -0700283 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000284 nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
285 nexthop->gate.ipv6 = *ipv6;
286 nexthop->ifindex = ifindex;
287
288 nexthop_add (rib, nexthop);
289
290 return nexthop;
291}
292#endif /* HAVE_IPV6 */
293
paul595db7f2003-05-25 21:35:06 +0000294struct nexthop *
295nexthop_blackhole_add (struct rib *rib)
296{
297 struct nexthop *nexthop;
298
Stephen Hemminger393deb92008-08-18 14:13:29 -0700299 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul595db7f2003-05-25 21:35:06 +0000300 nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
301 SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
302
303 nexthop_add (rib, nexthop);
304
305 return nexthop;
306}
307
paul718e3742002-12-13 20:15:29 +0000308/* If force flag is not set, do not modify falgs at all for uninstall
309 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000310static int
paul718e3742002-12-13 20:15:29 +0000311nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
312 struct route_node *top)
313{
314 struct prefix_ipv4 p;
315 struct route_table *table;
316 struct route_node *rn;
317 struct rib *match;
318 struct nexthop *newhop;
319
320 if (nexthop->type == NEXTHOP_TYPE_IPV4)
321 nexthop->ifindex = 0;
322
323 if (set)
324 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
325
326 /* Make lookup prefix. */
327 memset (&p, 0, sizeof (struct prefix_ipv4));
328 p.family = AF_INET;
329 p.prefixlen = IPV4_MAX_PREFIXLEN;
330 p.prefix = nexthop->gate.ipv4;
331
332 /* Lookup table. */
333 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
334 if (! table)
335 return 0;
336
337 rn = route_node_match (table, (struct prefix *) &p);
338 while (rn)
339 {
340 route_unlock_node (rn);
341
David Warda50c1072009-12-03 15:34:39 +0300342 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000343 if (rn == top)
344 return 0;
345
346 /* Pick up selected route. */
347 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100348 {
349 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
350 continue;
351 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
352 break;
353 }
paul718e3742002-12-13 20:15:29 +0000354
355 /* If there is no selected route or matched route is EGP, go up
356 tree. */
357 if (! match
358 || match->type == ZEBRA_ROUTE_BGP)
359 {
360 do {
361 rn = rn->parent;
362 } while (rn && rn->info == NULL);
363 if (rn)
364 route_lock_node (rn);
365 }
366 else
367 {
368 if (match->type == ZEBRA_ROUTE_CONNECT)
369 {
370 /* Directly point connected route. */
371 newhop = match->nexthop;
372 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
373 nexthop->ifindex = newhop->ifindex;
374
375 return 1;
376 }
377 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
378 {
379 for (newhop = match->nexthop; newhop; newhop = newhop->next)
380 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
381 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
382 {
383 if (set)
384 {
385 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
386 nexthop->rtype = newhop->type;
387 if (newhop->type == NEXTHOP_TYPE_IPV4 ||
388 newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
389 nexthop->rgate.ipv4 = newhop->gate.ipv4;
390 if (newhop->type == NEXTHOP_TYPE_IFINDEX
391 || newhop->type == NEXTHOP_TYPE_IFNAME
392 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
393 nexthop->rifindex = newhop->ifindex;
394 }
395 return 1;
396 }
397 return 0;
398 }
399 else
400 {
401 return 0;
402 }
403 }
404 }
405 return 0;
406}
407
408#ifdef HAVE_IPV6
409/* If force flag is not set, do not modify falgs at all for uninstall
410 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000411static int
paul718e3742002-12-13 20:15:29 +0000412nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
413 struct route_node *top)
414{
415 struct prefix_ipv6 p;
416 struct route_table *table;
417 struct route_node *rn;
418 struct rib *match;
419 struct nexthop *newhop;
420
421 if (nexthop->type == NEXTHOP_TYPE_IPV6)
422 nexthop->ifindex = 0;
423
424 if (set)
425 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
426
427 /* Make lookup prefix. */
428 memset (&p, 0, sizeof (struct prefix_ipv6));
429 p.family = AF_INET6;
430 p.prefixlen = IPV6_MAX_PREFIXLEN;
431 p.prefix = nexthop->gate.ipv6;
432
433 /* Lookup table. */
434 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
435 if (! table)
436 return 0;
437
438 rn = route_node_match (table, (struct prefix *) &p);
439 while (rn)
440 {
441 route_unlock_node (rn);
442
David Warda50c1072009-12-03 15:34:39 +0300443 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000444 if (rn == top)
445 return 0;
446
447 /* Pick up selected route. */
448 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100449 {
450 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
451 continue;
452 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
453 break;
454 }
paul718e3742002-12-13 20:15:29 +0000455
456 /* If there is no selected route or matched route is EGP, go up
457 tree. */
458 if (! match
459 || match->type == ZEBRA_ROUTE_BGP)
460 {
461 do {
462 rn = rn->parent;
463 } while (rn && rn->info == NULL);
464 if (rn)
465 route_lock_node (rn);
466 }
467 else
468 {
469 if (match->type == ZEBRA_ROUTE_CONNECT)
470 {
471 /* Directly point connected route. */
472 newhop = match->nexthop;
473
474 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
475 nexthop->ifindex = newhop->ifindex;
476
477 return 1;
478 }
479 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
480 {
481 for (newhop = match->nexthop; newhop; newhop = newhop->next)
482 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
483 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
484 {
485 if (set)
486 {
487 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
488 nexthop->rtype = newhop->type;
489 if (newhop->type == NEXTHOP_TYPE_IPV6
490 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
491 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
492 nexthop->rgate.ipv6 = newhop->gate.ipv6;
493 if (newhop->type == NEXTHOP_TYPE_IFINDEX
494 || newhop->type == NEXTHOP_TYPE_IFNAME
495 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
496 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
497 nexthop->rifindex = newhop->ifindex;
498 }
499 return 1;
500 }
501 return 0;
502 }
503 else
504 {
505 return 0;
506 }
507 }
508 }
509 return 0;
510}
511#endif /* HAVE_IPV6 */
512
513struct rib *
514rib_match_ipv4 (struct in_addr addr)
515{
516 struct prefix_ipv4 p;
517 struct route_table *table;
518 struct route_node *rn;
519 struct rib *match;
520 struct nexthop *newhop;
521
522 /* Lookup table. */
523 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
524 if (! table)
525 return 0;
526
527 memset (&p, 0, sizeof (struct prefix_ipv4));
528 p.family = AF_INET;
529 p.prefixlen = IPV4_MAX_PREFIXLEN;
530 p.prefix = addr;
531
532 rn = route_node_match (table, (struct prefix *) &p);
533
534 while (rn)
535 {
536 route_unlock_node (rn);
537
538 /* Pick up selected route. */
539 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100540 {
541 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
542 continue;
543 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
544 break;
545 }
paul718e3742002-12-13 20:15:29 +0000546
547 /* If there is no selected route or matched route is EGP, go up
548 tree. */
549 if (! match
550 || match->type == ZEBRA_ROUTE_BGP)
551 {
552 do {
553 rn = rn->parent;
554 } while (rn && rn->info == NULL);
555 if (rn)
556 route_lock_node (rn);
557 }
558 else
559 {
560 if (match->type == ZEBRA_ROUTE_CONNECT)
561 /* Directly point connected route. */
562 return match;
563 else
564 {
565 for (newhop = match->nexthop; newhop; newhop = newhop->next)
566 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
567 return match;
568 return NULL;
569 }
570 }
571 }
572 return NULL;
573}
574
575struct rib *
576rib_lookup_ipv4 (struct prefix_ipv4 *p)
577{
578 struct route_table *table;
579 struct route_node *rn;
580 struct rib *match;
581 struct nexthop *nexthop;
582
583 /* Lookup table. */
584 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
585 if (! table)
586 return 0;
587
588 rn = route_node_lookup (table, (struct prefix *) p);
589
590 /* No route for this prefix. */
591 if (! rn)
592 return NULL;
593
594 /* Unlock node. */
595 route_unlock_node (rn);
596
paul718e3742002-12-13 20:15:29 +0000597 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100598 {
599 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
600 continue;
601 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
602 break;
603 }
paul718e3742002-12-13 20:15:29 +0000604
605 if (! match || match->type == ZEBRA_ROUTE_BGP)
606 return NULL;
607
608 if (match->type == ZEBRA_ROUTE_CONNECT)
609 return match;
610
611 for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
612 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
613 return match;
614
615 return NULL;
616}
617
Denis Ovsienkodc958242007-08-13 16:03:06 +0000618/*
619 * This clone function, unlike its original rib_lookup_ipv4(), checks
620 * if specified IPv4 route record (prefix/mask -> gate) exists in
621 * the whole RIB and has ZEBRA_FLAG_SELECTED set.
622 *
623 * Return values:
624 * -1: error
625 * 0: exact match found
626 * 1: a match was found with a different gate
627 * 2: connected route found
628 * 3: no matches found
629 */
630int
631rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
632{
633 struct route_table *table;
634 struct route_node *rn;
635 struct rib *match;
636 struct nexthop *nexthop;
637
638 /* Lookup table. */
639 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
640 if (! table)
641 return ZEBRA_RIB_LOOKUP_ERROR;
642
643 /* Scan the RIB table for exactly matching RIB entry. */
644 rn = route_node_lookup (table, (struct prefix *) p);
645
646 /* No route for this prefix. */
647 if (! rn)
648 return ZEBRA_RIB_NOTFOUND;
649
650 /* Unlock node. */
651 route_unlock_node (rn);
652
653 /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
654 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100655 {
656 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
657 continue;
658 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
659 break;
660 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000661
662 /* None such found :( */
663 if (!match)
664 return ZEBRA_RIB_NOTFOUND;
665
666 if (match->type == ZEBRA_ROUTE_CONNECT)
667 return ZEBRA_RIB_FOUND_CONNECTED;
668
669 /* Ok, we have a cood candidate, let's check it's nexthop list... */
670 for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
671 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
672 {
673 /* We are happy with either direct or recursive hexthop */
674 if (nexthop->gate.ipv4.s_addr == qgate->sin.sin_addr.s_addr ||
675 nexthop->rgate.ipv4.s_addr == qgate->sin.sin_addr.s_addr)
676 return ZEBRA_RIB_FOUND_EXACT;
677 else
678 {
679 if (IS_ZEBRA_DEBUG_RIB)
680 {
681 char gate_buf[INET_ADDRSTRLEN], rgate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
682 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
683 inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, rgate_buf, INET_ADDRSTRLEN);
684 inet_ntop (AF_INET, &qgate->sin.sin_addr.s_addr, qgate_buf, INET_ADDRSTRLEN);
685 zlog_debug ("%s: qgate == %s, gate == %s, rgate == %s", __func__, qgate_buf, gate_buf, rgate_buf);
686 }
687 return ZEBRA_RIB_FOUND_NOGATE;
688 }
689 }
690
691 return ZEBRA_RIB_NOTFOUND;
692}
693
paul718e3742002-12-13 20:15:29 +0000694#ifdef HAVE_IPV6
695struct rib *
696rib_match_ipv6 (struct in6_addr *addr)
697{
698 struct prefix_ipv6 p;
699 struct route_table *table;
700 struct route_node *rn;
701 struct rib *match;
702 struct nexthop *newhop;
703
704 /* Lookup table. */
705 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
706 if (! table)
707 return 0;
708
709 memset (&p, 0, sizeof (struct prefix_ipv6));
710 p.family = AF_INET6;
711 p.prefixlen = IPV6_MAX_PREFIXLEN;
712 IPV6_ADDR_COPY (&p.prefix, addr);
713
714 rn = route_node_match (table, (struct prefix *) &p);
715
716 while (rn)
717 {
718 route_unlock_node (rn);
719
720 /* Pick up selected route. */
721 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100722 {
723 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
724 continue;
725 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
726 break;
727 }
paul718e3742002-12-13 20:15:29 +0000728
729 /* If there is no selected route or matched route is EGP, go up
730 tree. */
731 if (! match
732 || match->type == ZEBRA_ROUTE_BGP)
733 {
734 do {
735 rn = rn->parent;
736 } while (rn && rn->info == NULL);
737 if (rn)
738 route_lock_node (rn);
739 }
740 else
741 {
742 if (match->type == ZEBRA_ROUTE_CONNECT)
743 /* Directly point connected route. */
744 return match;
745 else
746 {
747 for (newhop = match->nexthop; newhop; newhop = newhop->next)
748 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
749 return match;
750 return NULL;
751 }
752 }
753 }
754 return NULL;
755}
756#endif /* HAVE_IPV6 */
757
Paul Jakma7514fb72007-05-02 16:05:35 +0000758#define RIB_SYSTEM_ROUTE(R) \
759 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
760
Denis Ovsienkodc958242007-08-13 16:03:06 +0000761/* This function verifies reachability of one given nexthop, which can be
762 * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
763 * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
764 * nexthop->ifindex will be updated appropriately as well.
765 * An existing route map can turn (otherwise active) nexthop into inactive, but
766 * not vice versa.
767 *
768 * The return value is the final value of 'ACTIVE' flag.
769 */
770
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300771static unsigned
paul718e3742002-12-13 20:15:29 +0000772nexthop_active_check (struct route_node *rn, struct rib *rib,
773 struct nexthop *nexthop, int set)
774{
775 struct interface *ifp;
Paul Jakma7514fb72007-05-02 16:05:35 +0000776 route_map_result_t ret = RMAP_MATCH;
777 extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
778 struct route_map *rmap;
779 int family;
paul718e3742002-12-13 20:15:29 +0000780
Paul Jakma7514fb72007-05-02 16:05:35 +0000781 family = 0;
paul718e3742002-12-13 20:15:29 +0000782 switch (nexthop->type)
783 {
784 case NEXTHOP_TYPE_IFINDEX:
785 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000786 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000787 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
788 else
789 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
790 break;
paul718e3742002-12-13 20:15:29 +0000791 case NEXTHOP_TYPE_IPV6_IFNAME:
Paul Jakma7514fb72007-05-02 16:05:35 +0000792 family = AFI_IP6;
793 case NEXTHOP_TYPE_IFNAME:
paul718e3742002-12-13 20:15:29 +0000794 ifp = if_lookup_by_name (nexthop->ifname);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000795 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000796 {
797 if (set)
798 nexthop->ifindex = ifp->ifindex;
799 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
800 }
801 else
802 {
803 if (set)
804 nexthop->ifindex = 0;
805 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
806 }
807 break;
808 case NEXTHOP_TYPE_IPV4:
809 case NEXTHOP_TYPE_IPV4_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000810 family = AFI_IP;
paul718e3742002-12-13 20:15:29 +0000811 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
812 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
813 else
814 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
815 break;
816#ifdef HAVE_IPV6
817 case NEXTHOP_TYPE_IPV6:
Paul Jakma7514fb72007-05-02 16:05:35 +0000818 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000819 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
820 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
821 else
822 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
823 break;
824 case NEXTHOP_TYPE_IPV6_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000825 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000826 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
827 {
828 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000829 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000830 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
831 else
832 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
833 }
834 else
835 {
836 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
837 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
838 else
839 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
840 }
841 break;
842#endif /* HAVE_IPV6 */
paul595db7f2003-05-25 21:35:06 +0000843 case NEXTHOP_TYPE_BLACKHOLE:
844 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
845 break;
paul718e3742002-12-13 20:15:29 +0000846 default:
847 break;
848 }
Paul Jakma7514fb72007-05-02 16:05:35 +0000849 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
850 return 0;
851
852 if (RIB_SYSTEM_ROUTE(rib) ||
853 (family == AFI_IP && rn->p.family != AF_INET) ||
854 (family == AFI_IP6 && rn->p.family != AF_INET6))
855 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
856
857 rmap = 0;
858 if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
859 proto_rm[family][rib->type])
860 rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
861 if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
862 rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
863 if (rmap) {
864 ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, nexthop);
865 }
866
867 if (ret == RMAP_DENYMATCH)
868 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
paul718e3742002-12-13 20:15:29 +0000869 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
870}
871
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000872/* Iterate over all nexthops of the given RIB entry and refresh their
873 * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
874 * nexthop is found to toggle the ACTIVE flag, the whole rib structure
875 * is flagged with ZEBRA_FLAG_CHANGED. The 4th 'set' argument is
876 * transparently passed to nexthop_active_check().
877 *
878 * Return value is the new number of active nexthops.
879 */
880
paula1ac18c2005-06-28 17:17:12 +0000881static int
paul718e3742002-12-13 20:15:29 +0000882nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
883{
884 struct nexthop *nexthop;
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300885 unsigned int prev_active, prev_index, new_active;
paul718e3742002-12-13 20:15:29 +0000886
887 rib->nexthop_active_num = 0;
888 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
889
890 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000891 {
892 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
Joakim Tjernlundc3a56062009-06-24 19:15:36 +0200893 prev_index = nexthop->ifindex;
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000894 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
895 rib->nexthop_active_num++;
Joakim Tjernlundc3a56062009-06-24 19:15:36 +0200896 if (prev_active != new_active ||
897 prev_index != nexthop->ifindex)
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000898 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
899 }
paul718e3742002-12-13 20:15:29 +0000900 return rib->nexthop_active_num;
901}
paul6baeb982003-10-28 03:47:15 +0000902
paul718e3742002-12-13 20:15:29 +0000903
paul718e3742002-12-13 20:15:29 +0000904
paula1ac18c2005-06-28 17:17:12 +0000905static void
paul718e3742002-12-13 20:15:29 +0000906rib_install_kernel (struct route_node *rn, struct rib *rib)
907{
908 int ret = 0;
909 struct nexthop *nexthop;
910
911 switch (PREFIX_FAMILY (&rn->p))
912 {
913 case AF_INET:
914 ret = kernel_add_ipv4 (&rn->p, rib);
915 break;
916#ifdef HAVE_IPV6
917 case AF_INET6:
918 ret = kernel_add_ipv6 (&rn->p, rib);
919 break;
920#endif /* HAVE_IPV6 */
921 }
922
Denis Ovsienkodc958242007-08-13 16:03:06 +0000923 /* This condition is never met, if we are using rt_socket.c */
paul718e3742002-12-13 20:15:29 +0000924 if (ret < 0)
925 {
926 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
927 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
928 }
929}
930
931/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +0000932static int
paul718e3742002-12-13 20:15:29 +0000933rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
934{
935 int ret = 0;
936 struct nexthop *nexthop;
937
938 switch (PREFIX_FAMILY (&rn->p))
939 {
940 case AF_INET:
941 ret = kernel_delete_ipv4 (&rn->p, rib);
942 break;
943#ifdef HAVE_IPV6
944 case AF_INET6:
945 ret = kernel_delete_ipv6 (&rn->p, rib);
946 break;
947#endif /* HAVE_IPV6 */
948 }
949
950 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
951 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
952
953 return ret;
954}
955
956/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +0000957static void
paul718e3742002-12-13 20:15:29 +0000958rib_uninstall (struct route_node *rn, struct rib *rib)
959{
960 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
961 {
962 redistribute_delete (&rn->p, rib);
963 if (! RIB_SYSTEM_ROUTE (rib))
964 rib_uninstall_kernel (rn, rib);
965 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
966 }
967}
968
Paul Jakma6d691122006-07-27 21:49:00 +0000969static void rib_unlink (struct route_node *, struct rib *);
970
paul718e3742002-12-13 20:15:29 +0000971/* Core function for processing routing information base. */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +0000972static void
973rib_process (struct route_node *rn)
paul718e3742002-12-13 20:15:29 +0000974{
975 struct rib *rib;
976 struct rib *next;
977 struct rib *fib = NULL;
978 struct rib *select = NULL;
Paul Jakma6d691122006-07-27 21:49:00 +0000979 struct rib *del = NULL;
pauld753e9e2003-01-22 19:45:50 +0000980 int installed = 0;
981 struct nexthop *nexthop = NULL;
Denis Ovsienkof304cb42007-10-03 12:27:16 +0000982 char buf[INET6_ADDRSTRLEN];
paul4d38fdb2005-04-28 17:35:14 +0000983
984 assert (rn);
985
Paul Jakma93bdada2007-08-06 19:25:11 +0000986 if (IS_ZEBRA_DEBUG_RIB || IS_ZEBRA_DEBUG_RIB_Q)
Denis Ovsienkof304cb42007-10-03 12:27:16 +0000987 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +0000988
paul718e3742002-12-13 20:15:29 +0000989 for (rib = rn->info; rib; rib = next)
990 {
Denis Ovsienkodc958242007-08-13 16:03:06 +0000991 /* The next pointer is saved, because current pointer
992 * may be passed to rib_unlink() in the middle of iteration.
993 */
paul718e3742002-12-13 20:15:29 +0000994 next = rib->next;
pauld753e9e2003-01-22 19:45:50 +0000995
paul718e3742002-12-13 20:15:29 +0000996 /* Currently installed rib. */
997 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Paul Jakma6d691122006-07-27 21:49:00 +0000998 {
999 assert (fib == NULL);
1000 fib = rib;
1001 }
1002
1003 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1004 * which we need to do do further work with below.
1005 */
1006 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1007 {
1008 if (rib != fib)
1009 {
1010 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001011 zlog_debug ("%s: %s/%d: rn %p, removing rib %p", __func__,
1012 buf, rn->p.prefixlen, rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001013 rib_unlink (rn, rib);
1014 }
1015 else
1016 del = rib;
1017
1018 continue;
1019 }
paul4d38fdb2005-04-28 17:35:14 +00001020
paul718e3742002-12-13 20:15:29 +00001021 /* Skip unreachable nexthop. */
1022 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +00001023 continue;
paul718e3742002-12-13 20:15:29 +00001024
1025 /* Infinit distance. */
1026 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +00001027 continue;
paul718e3742002-12-13 20:15:29 +00001028
paulaf887b52006-01-18 14:52:52 +00001029 /* Newly selected rib, the common case. */
1030 if (!select)
1031 {
1032 select = rib;
1033 continue;
1034 }
1035
1036 /* filter route selection in following order:
paulaf887b52006-01-18 14:52:52 +00001037 * - connected beats other types
paula8d9c1f2006-01-25 06:31:04 +00001038 * - lower distance beats higher
paulaf887b52006-01-18 14:52:52 +00001039 * - lower metric beats higher for equal distance
1040 * - last, hence oldest, route wins tie break.
1041 */
paula1038a12006-01-30 14:08:51 +00001042
1043 /* Connected routes. Pick the last connected
1044 * route of the set of lowest metric connected routes.
1045 */
paula8d9c1f2006-01-25 06:31:04 +00001046 if (rib->type == ZEBRA_ROUTE_CONNECT)
1047 {
paula1038a12006-01-30 14:08:51 +00001048 if (select->type != ZEBRA_ROUTE_CONNECT
paula8d9c1f2006-01-25 06:31:04 +00001049 || rib->metric <= select->metric)
paula1038a12006-01-30 14:08:51 +00001050 select = rib;
1051 continue;
paula8d9c1f2006-01-25 06:31:04 +00001052 }
1053 else if (select->type == ZEBRA_ROUTE_CONNECT)
1054 continue;
1055
1056 /* higher distance loses */
1057 if (rib->distance > select->distance)
1058 continue;
1059
1060 /* lower wins */
1061 if (rib->distance < select->distance)
1062 {
paulaf887b52006-01-18 14:52:52 +00001063 select = rib;
paula8d9c1f2006-01-25 06:31:04 +00001064 continue;
1065 }
1066
1067 /* metric tie-breaks equal distance */
1068 if (rib->metric <= select->metric)
1069 select = rib;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001070 } /* for (rib = rn->info; rib; rib = next) */
1071
1072 /* After the cycle is finished, the following pointers will be set:
1073 * select --- the winner RIB entry, if any was found, otherwise NULL
1074 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1075 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1076 * rib --- NULL
1077 */
1078
1079 /* Same RIB entry is selected. Update FIB and finish. */
paul718e3742002-12-13 20:15:29 +00001080 if (select && select == fib)
1081 {
Paul Jakma6d691122006-07-27 21:49:00 +00001082 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001083 zlog_debug ("%s: %s/%d: Updating existing route, select %p, fib %p",
1084 __func__, buf, rn->p.prefixlen, select, fib);
paul718e3742002-12-13 20:15:29 +00001085 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +00001086 {
1087 redistribute_delete (&rn->p, select);
1088 if (! RIB_SYSTEM_ROUTE (select))
1089 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001090
paul4d38fdb2005-04-28 17:35:14 +00001091 /* Set real nexthop. */
1092 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +00001093
paul4d38fdb2005-04-28 17:35:14 +00001094 if (! RIB_SYSTEM_ROUTE (select))
1095 rib_install_kernel (rn, select);
1096 redistribute_add (&rn->p, select);
1097 }
pauld753e9e2003-01-22 19:45:50 +00001098 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001099 {
1100 /* Housekeeping code to deal with
1101 race conditions in kernel with linux
1102 netlink reporting interface up before IPv4 or IPv6 protocol
1103 is ready to add routes.
1104 This makes sure the routes are IN the kernel.
1105 */
pauld753e9e2003-01-22 19:45:50 +00001106
paul4d38fdb2005-04-28 17:35:14 +00001107 for (nexthop = select->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001108 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
paul4d38fdb2005-04-28 17:35:14 +00001109 {
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001110 installed = 1;
1111 break;
paul4d38fdb2005-04-28 17:35:14 +00001112 }
1113 if (! installed)
1114 rib_install_kernel (rn, select);
1115 }
Paul Jakma6d691122006-07-27 21:49:00 +00001116 goto end;
paul718e3742002-12-13 20:15:29 +00001117 }
1118
Denis Ovsienkodc958242007-08-13 16:03:06 +00001119 /* At this point we either haven't found the best RIB entry or it is
1120 * different from what we currently intend to flag with SELECTED. In both
1121 * cases, if a RIB block is present in FIB, it should be withdrawn.
1122 */
paul718e3742002-12-13 20:15:29 +00001123 if (fib)
1124 {
Paul Jakma6d691122006-07-27 21:49:00 +00001125 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001126 zlog_debug ("%s: %s/%d: Removing existing route, fib %p", __func__,
1127 buf, rn->p.prefixlen, fib);
paul718e3742002-12-13 20:15:29 +00001128 redistribute_delete (&rn->p, fib);
1129 if (! RIB_SYSTEM_ROUTE (fib))
1130 rib_uninstall_kernel (rn, fib);
1131 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1132
1133 /* Set real nexthop. */
1134 nexthop_active_update (rn, fib, 1);
1135 }
1136
Denis Ovsienkodc958242007-08-13 16:03:06 +00001137 /* Regardless of some RIB entry being SELECTED or not before, now we can
1138 * tell, that if a new winner exists, FIB is still not updated with this
1139 * data, but ready to be.
1140 */
paul718e3742002-12-13 20:15:29 +00001141 if (select)
1142 {
Paul Jakma6d691122006-07-27 21:49:00 +00001143 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001144 zlog_debug ("%s: %s/%d: Adding route, select %p", __func__, buf,
1145 rn->p.prefixlen, select);
paul718e3742002-12-13 20:15:29 +00001146 /* Set real nexthop. */
1147 nexthop_active_update (rn, select, 1);
1148
1149 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001150 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001151 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1152 redistribute_add (&rn->p, select);
1153 }
paul4d38fdb2005-04-28 17:35:14 +00001154
Paul Jakma6d691122006-07-27 21:49:00 +00001155 /* FIB route was removed, should be deleted */
1156 if (del)
1157 {
1158 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001159 zlog_debug ("%s: %s/%d: Deleting fib %p, rn %p", __func__, buf,
1160 rn->p.prefixlen, del, rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001161 rib_unlink (rn, del);
1162 }
paul4d38fdb2005-04-28 17:35:14 +00001163
Paul Jakma6d691122006-07-27 21:49:00 +00001164end:
1165 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma93bdada2007-08-06 19:25:11 +00001166 zlog_debug ("%s: %s/%d: rn %p dequeued", __func__, buf, rn->p.prefixlen, rn);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001167}
1168
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001169/* Take a list of route_node structs and return 1, if there was a record
1170 * picked from it and processed by rib_process(). Don't process more,
1171 * than one RN record; operate only in the specified sub-queue.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001172 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001173static unsigned int
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001174process_subq (struct list * subq, u_char qindex)
1175{
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001176 struct listnode *lnode = listhead (subq);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001177 struct route_node *rnode;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001178
1179 if (!lnode)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001180 return 0;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001181
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001182 rnode = listgetdata (lnode);
1183 rib_process (rnode);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001184
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001185 if (rnode->info) /* The first RIB record is holding the flags bitmask. */
1186 UNSET_FLAG (((struct rib *)rnode->info)->rn_status, RIB_ROUTE_QUEUED(qindex));
Chris Caputo67b94672009-07-18 04:02:26 +00001187#if 0
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001188 else
1189 {
1190 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1191 __func__, rnode, rnode->lock);
1192 zlog_backtrace(LOG_DEBUG);
1193 }
Chris Caputo67b94672009-07-18 04:02:26 +00001194#endif
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001195 route_unlock_node (rnode);
1196 list_delete_node (subq, lnode);
1197 return 1;
1198}
1199
1200/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1201 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1202 * is pointed to the meta queue structure.
1203 */
1204static wq_item_status
1205meta_queue_process (struct work_queue *dummy, void *data)
1206{
1207 struct meta_queue * mq = data;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001208 unsigned i;
1209
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001210 for (i = 0; i < MQ_SIZE; i++)
1211 if (process_subq (mq->subq[i], i))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001212 {
1213 mq->size--;
1214 break;
1215 }
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001216 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1217}
1218
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001219/* Map from rib types to queue type (priority) in meta queue */
1220static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
1221 [ZEBRA_ROUTE_SYSTEM] = 4,
1222 [ZEBRA_ROUTE_KERNEL] = 0,
1223 [ZEBRA_ROUTE_CONNECT] = 0,
1224 [ZEBRA_ROUTE_STATIC] = 1,
1225 [ZEBRA_ROUTE_RIP] = 2,
1226 [ZEBRA_ROUTE_RIPNG] = 2,
1227 [ZEBRA_ROUTE_OSPF] = 2,
1228 [ZEBRA_ROUTE_OSPF6] = 2,
1229 [ZEBRA_ROUTE_ISIS] = 2,
1230 [ZEBRA_ROUTE_BGP] = 3,
1231 [ZEBRA_ROUTE_HSLS] = 4,
1232};
1233
1234/* Look into the RN and queue it into one or more priority queues,
1235 * increasing the size for each data push done.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001236 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001237static void
1238rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001239{
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001240 struct rib *rib;
1241 char buf[INET6_ADDRSTRLEN];
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001242
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001243 if (IS_ZEBRA_DEBUG_RIB_Q)
1244 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001245
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001246 for (rib = rn->info; rib; rib = rib->next)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001247 {
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001248 u_char qindex = meta_queue_map[rib->type];
1249
1250 /* Invariant: at this point we always have rn->info set. */
1251 if (CHECK_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED(qindex)))
1252 {
1253 if (IS_ZEBRA_DEBUG_RIB_Q)
1254 zlog_debug ("%s: %s/%d: rn %p is already queued in sub-queue %u",
1255 __func__, buf, rn->p.prefixlen, rn, qindex);
1256 continue;
1257 }
1258
1259 SET_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED(qindex));
1260 listnode_add (mq->subq[qindex], rn);
1261 route_lock_node (rn);
1262 mq->size++;
1263
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001264 if (IS_ZEBRA_DEBUG_RIB_Q)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001265 zlog_debug ("%s: %s/%d: queued rn %p into sub-queue %u",
1266 __func__, buf, rn->p.prefixlen, rn, qindex);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001267 }
paul4d38fdb2005-04-28 17:35:14 +00001268}
1269
Paul Jakma6d691122006-07-27 21:49:00 +00001270/* Add route_node to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001271static void
Paul Jakma6d691122006-07-27 21:49:00 +00001272rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
paul4d38fdb2005-04-28 17:35:14 +00001273{
paul4d38fdb2005-04-28 17:35:14 +00001274
Paul Jakma93bdada2007-08-06 19:25:11 +00001275 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma6d691122006-07-27 21:49:00 +00001276 {
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001277 char buf[INET6_ADDRSTRLEN];
1278
1279 zlog_info ("%s: %s/%d: work queue added", __func__,
1280 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN),
1281 rn->p.prefixlen);
Paul Jakma6d691122006-07-27 21:49:00 +00001282 }
paul4d38fdb2005-04-28 17:35:14 +00001283
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001284 /*
1285 * The RIB queue should normally be either empty or holding the only
1286 * work_queue_item element. In the latter case this element would
1287 * hold a pointer to the meta queue structure, which must be used to
1288 * actually queue the route nodes to process. So create the MQ
1289 * holder, if necessary, then push the work into it in any case.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001290 * This semantics was introduced after 0.99.9 release.
1291 */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001292 if (!zebra->ribq->items->count)
1293 work_queue_add (zebra->ribq, zebra->mq);
1294
1295 rib_meta_queue_add (zebra->mq, rn);
paul4d38fdb2005-04-28 17:35:14 +00001296}
1297
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001298/* Create new meta queue.
1299 A destructor function doesn't seem to be necessary here.
1300 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001301static struct meta_queue *
1302meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001303{
1304 struct meta_queue *new;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001305 unsigned i;
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001306
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001307 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1308 assert(new);
1309
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001310 for (i = 0; i < MQ_SIZE; i++)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001311 {
1312 new->subq[i] = list_new ();
1313 assert(new->subq[i]);
1314 }
1315
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001316 return new;
1317}
1318
paul4d38fdb2005-04-28 17:35:14 +00001319/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001320static void
paul4d38fdb2005-04-28 17:35:14 +00001321rib_queue_init (struct zebra_t *zebra)
1322{
paul4d38fdb2005-04-28 17:35:14 +00001323 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001324 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001325 {
Paul Jakma6d691122006-07-27 21:49:00 +00001326 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001327 return;
1328 }
1329
1330 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001331 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001332 zebra->ribq->spec.errorfunc = NULL;
paul4d38fdb2005-04-28 17:35:14 +00001333 /* XXX: TODO: These should be runtime configurable via vty */
1334 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001335 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001336
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001337 if (!(zebra->mq = meta_queue_new ()))
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001338 zlog_err ("%s: could not initialise meta queue!", __func__);
paul718e3742002-12-13 20:15:29 +00001339}
1340
Paul Jakma6d691122006-07-27 21:49:00 +00001341/* RIB updates are processed via a queue of pointers to route_nodes.
1342 *
1343 * The queue length is bounded by the maximal size of the routing table,
1344 * as a route_node will not be requeued, if already queued.
1345 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001346 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1347 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1348 * and then submit route_node to queue for best-path selection later.
1349 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001350 *
1351 * Deleted RIBs are reaped during best-path selection.
1352 *
1353 * rib_addnode
1354 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001355 * |-------->| | best RIB, if required
1356 * | |
1357 * static_install->|->rib_addqueue...... -> rib_process
1358 * | |
1359 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001360 * |-> set RIB_ENTRY_REMOVE |
1361 * rib_delnode (RIB freed)
1362 *
1363 *
1364 * Queueing state for a route_node is kept in the head RIB entry, this
1365 * state must be preserved as and when the head RIB entry of a
1366 * route_node is changed by rib_unlink / rib_link. A small complication,
1367 * but saves having to allocate a dedicated object for this.
1368 *
1369 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1370 *
1371 * - route_nodes: refcounted by:
1372 * - RIBs attached to route_node:
1373 * - managed by: rib_link/unlink
1374 * - route_node processing queue
1375 * - managed by: rib_addqueue, rib_process.
1376 *
1377 */
1378
paul718e3742002-12-13 20:15:29 +00001379/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001380static void
Paul Jakma6d691122006-07-27 21:49:00 +00001381rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001382{
1383 struct rib *head;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001384 char buf[INET6_ADDRSTRLEN];
paul4d38fdb2005-04-28 17:35:14 +00001385
1386 assert (rib && rn);
1387
Paul Jakma6d691122006-07-27 21:49:00 +00001388 route_lock_node (rn); /* rn route table reference */
1389
1390 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001391 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001392 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001393 zlog_debug ("%s: %s/%d: rn %p, rib %p", __func__,
1394 buf, rn->p.prefixlen, rn, rib);
1395 }
Paul Jakma6d691122006-07-27 21:49:00 +00001396
paul718e3742002-12-13 20:15:29 +00001397 head = rn->info;
1398 if (head)
Paul Jakma6d691122006-07-27 21:49:00 +00001399 {
1400 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001401 zlog_debug ("%s: %s/%d: new head, rn_status copied over", __func__,
1402 buf, rn->p.prefixlen);
Paul Jakma6d691122006-07-27 21:49:00 +00001403 head->prev = rib;
1404 /* Transfer the rn status flags to the new head RIB */
1405 rib->rn_status = head->rn_status;
1406 }
paul718e3742002-12-13 20:15:29 +00001407 rib->next = head;
1408 rn->info = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001409 rib_queue_add (&zebrad, rn);
1410}
1411
1412static void
1413rib_addnode (struct route_node *rn, struct rib *rib)
1414{
1415 /* RIB node has been un-removed before route-node is processed.
1416 * route_node must hence already be on the queue for processing..
1417 */
1418 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1419 {
1420 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001421 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001422 char buf[INET6_ADDRSTRLEN];
1423 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001424 zlog_debug ("%s: %s/%d: rn %p, un-removed rib %p",
1425 __func__, buf, rn->p.prefixlen, rn, rib);
1426 }
Paul Jakma6d691122006-07-27 21:49:00 +00001427 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1428 return;
1429 }
1430 rib_link (rn, rib);
1431}
1432
1433static void
1434rib_unlink (struct route_node *rn, struct rib *rib)
1435{
1436 struct nexthop *nexthop, *next;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001437 char buf[INET6_ADDRSTRLEN];
Paul Jakma6d691122006-07-27 21:49:00 +00001438
1439 assert (rn && rib);
1440
1441 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001442 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001443 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001444 zlog_debug ("%s: %s/%d: rn %p, rib %p",
1445 __func__, buf, rn->p.prefixlen, rn, rib);
1446 }
Paul Jakma6d691122006-07-27 21:49:00 +00001447
1448 if (rib->next)
1449 rib->next->prev = rib->prev;
1450
1451 if (rib->prev)
1452 rib->prev->next = rib->next;
1453 else
1454 {
1455 rn->info = rib->next;
1456
1457 if (rn->info)
1458 {
1459 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001460 zlog_debug ("%s: %s/%d: rn %p, rib %p, new head copy",
1461 __func__, buf, rn->p.prefixlen, rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001462 rib->next->rn_status = rib->rn_status;
1463 }
1464 }
1465
1466 /* free RIB and nexthops */
1467 for (nexthop = rib->nexthop; nexthop; nexthop = next)
1468 {
1469 next = nexthop->next;
1470 nexthop_free (nexthop);
1471 }
1472 XFREE (MTYPE_RIB, rib);
1473
1474 route_unlock_node (rn); /* rn route table reference */
paul718e3742002-12-13 20:15:29 +00001475}
1476
paula1ac18c2005-06-28 17:17:12 +00001477static void
paul718e3742002-12-13 20:15:29 +00001478rib_delnode (struct route_node *rn, struct rib *rib)
1479{
Paul Jakma6d691122006-07-27 21:49:00 +00001480 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001481 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001482 char buf[INET6_ADDRSTRLEN];
1483 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001484 zlog_debug ("%s: %s/%d: rn %p, rib %p, removing", __func__,
1485 buf, rn->p.prefixlen, rn, rib);
1486 }
Paul Jakma6d691122006-07-27 21:49:00 +00001487 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1488 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001489}
1490
1491int
1492rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001493 struct in_addr *gate, struct in_addr *src,
1494 unsigned int ifindex, u_int32_t vrf_id,
paul718e3742002-12-13 20:15:29 +00001495 u_int32_t metric, u_char distance)
1496{
1497 struct rib *rib;
1498 struct rib *same = NULL;
1499 struct route_table *table;
1500 struct route_node *rn;
1501 struct nexthop *nexthop;
1502
1503 /* Lookup table. */
1504 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1505 if (! table)
1506 return 0;
1507
1508 /* Make it sure prefixlen is applied to the prefix. */
1509 apply_mask_ipv4 (p);
1510
1511 /* Set default distance by route type. */
1512 if (distance == 0)
1513 {
1514 distance = route_info[type].distance;
1515
1516 /* iBGP distance is 200. */
1517 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1518 distance = 200;
1519 }
1520
1521 /* Lookup route node.*/
1522 rn = route_node_get (table, (struct prefix *) p);
1523
1524 /* If same type of route are installed, treat it as a implicit
1525 withdraw. */
1526 for (rib = rn->info; rib; rib = rib->next)
1527 {
Paul Jakma6d691122006-07-27 21:49:00 +00001528 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1529 continue;
1530
hassoebf1ead2005-09-21 14:58:20 +00001531 if (rib->type != type)
1532 continue;
1533 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001534 {
1535 same = rib;
1536 break;
1537 }
hassoebf1ead2005-09-21 14:58:20 +00001538 /* Duplicate connected route comes in. */
1539 else if ((nexthop = rib->nexthop) &&
1540 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001541 nexthop->ifindex == ifindex &&
1542 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001543 {
1544 rib->refcnt++;
1545 return 0 ;
1546 }
paul718e3742002-12-13 20:15:29 +00001547 }
1548
1549 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001550 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001551 rib->type = type;
1552 rib->distance = distance;
1553 rib->flags = flags;
1554 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001555 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001556 rib->nexthop_num = 0;
1557 rib->uptime = time (NULL);
1558
1559 /* Nexthop settings. */
1560 if (gate)
1561 {
1562 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001563 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001564 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001565 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001566 }
1567 else
1568 nexthop_ifindex_add (rib, ifindex);
1569
1570 /* If this route is kernel route, set FIB flag to the route. */
1571 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1572 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1573 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1574
1575 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001576 if (IS_ZEBRA_DEBUG_RIB)
1577 zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
paul718e3742002-12-13 20:15:29 +00001578 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001579
paul718e3742002-12-13 20:15:29 +00001580 /* Free implicit route.*/
1581 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001582 {
1583 if (IS_ZEBRA_DEBUG_RIB)
1584 zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001585 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001586 }
paul4d38fdb2005-04-28 17:35:14 +00001587
1588 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001589 return 0;
1590}
1591
Denis Ovsienkodc958242007-08-13 16:03:06 +00001592/* This function dumps the contents of a given RIB entry into
1593 * standard debug log. Calling function name and IP prefix in
1594 * question are passed as 1st and 2nd arguments.
1595 */
1596
1597void rib_dump (const char * func, const struct prefix_ipv4 * p, const struct rib * rib)
1598{
1599 char straddr1[INET_ADDRSTRLEN], straddr2[INET_ADDRSTRLEN];
1600 struct nexthop *nexthop;
1601
1602 inet_ntop (AF_INET, &p->prefix, straddr1, INET_ADDRSTRLEN);
1603 zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr1, p->prefixlen);
1604 zlog_debug
1605 (
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001606 "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
Denis Ovsienkodc958242007-08-13 16:03:06 +00001607 func,
1608 rib->refcnt,
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001609 (unsigned long) rib->uptime,
Denis Ovsienkodc958242007-08-13 16:03:06 +00001610 rib->type,
1611 rib->table
1612 );
1613 zlog_debug
1614 (
1615 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1616 func,
1617 rib->metric,
1618 rib->distance,
1619 rib->flags,
1620 rib->status
1621 );
1622 zlog_debug
1623 (
1624 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1625 func,
1626 rib->nexthop_num,
1627 rib->nexthop_active_num,
1628 rib->nexthop_fib_num
1629 );
1630 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1631 {
1632 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, straddr1, INET_ADDRSTRLEN);
1633 inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, straddr2, INET_ADDRSTRLEN);
1634 zlog_debug
1635 (
1636 "%s: NH %s (%s) with flags %s%s%s",
1637 func,
1638 straddr1,
1639 straddr2,
1640 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1641 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1642 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1643 );
1644 }
1645 zlog_debug ("%s: dump complete", func);
1646}
1647
1648/* This is an exported helper to rtm_read() to dump the strange
1649 * RIB entry found by rib_lookup_ipv4_route()
1650 */
1651
1652void rib_lookup_and_dump (struct prefix_ipv4 * p)
1653{
1654 struct route_table *table;
1655 struct route_node *rn;
1656 struct rib *rib;
1657 char prefix_buf[INET_ADDRSTRLEN];
1658
1659 /* Lookup table. */
1660 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1661 if (! table)
1662 {
1663 zlog_err ("%s: vrf_table() returned NULL", __func__);
1664 return;
1665 }
1666
1667 inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
1668 /* Scan the RIB table for exactly matching RIB entry. */
1669 rn = route_node_lookup (table, (struct prefix *) p);
1670
1671 /* No route for this prefix. */
1672 if (! rn)
1673 {
1674 zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
1675 return;
1676 }
1677
1678 /* Unlock node. */
1679 route_unlock_node (rn);
1680
1681 /* let's go */
1682 for (rib = rn->info; rib; rib = rib->next)
1683 {
1684 zlog_debug
1685 (
1686 "%s: rn %p, rib %p: %s, %s",
1687 __func__,
1688 rn,
1689 rib,
1690 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
1691 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
1692 );
1693 rib_dump (__func__, p, rib);
1694 }
1695}
1696
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001697/* Check if requested address assignment will fail due to another
1698 * route being installed by zebra in FIB already. Take necessary
1699 * actions, if needed: remove such a route from FIB and deSELECT
1700 * corresponding RIB entry. Then put affected RN into RIBQ head.
1701 */
1702void rib_lookup_and_pushup (struct prefix_ipv4 * p)
1703{
1704 struct route_table *table;
1705 struct route_node *rn;
1706 struct rib *rib;
1707 unsigned changed = 0;
1708
1709 if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
1710 {
1711 zlog_err ("%s: vrf_table() returned NULL", __func__);
1712 return;
1713 }
1714
1715 /* No matches would be the simplest case. */
1716 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
1717 return;
1718
1719 /* Unlock node. */
1720 route_unlock_node (rn);
1721
1722 /* Check all RIB entries. In case any changes have to be done, requeue
1723 * the RN into RIBQ head. If the routing message about the new connected
1724 * route (generated by the IP address we are going to assign very soon)
1725 * comes before the RIBQ is processed, the new RIB entry will join
1726 * RIBQ record already on head. This is necessary for proper revalidation
1727 * of the rest of the RIB.
1728 */
1729 for (rib = rn->info; rib; rib = rib->next)
1730 {
1731 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
1732 ! RIB_SYSTEM_ROUTE (rib))
1733 {
1734 changed = 1;
1735 if (IS_ZEBRA_DEBUG_RIB)
1736 {
1737 char buf[INET_ADDRSTRLEN];
1738 inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
1739 zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
1740 rib_dump (__func__, (struct prefix_ipv4 *)&rn->p, rib);
1741 }
1742 rib_uninstall (rn, rib);
1743 }
1744 }
1745 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001746 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001747}
1748
paul718e3742002-12-13 20:15:29 +00001749int
1750rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib)
1751{
1752 struct route_table *table;
1753 struct route_node *rn;
1754 struct rib *same;
1755 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00001756
paul718e3742002-12-13 20:15:29 +00001757 /* Lookup table. */
1758 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1759 if (! table)
1760 return 0;
paul718e3742002-12-13 20:15:29 +00001761 /* Make it sure prefixlen is applied to the prefix. */
1762 apply_mask_ipv4 (p);
1763
1764 /* Set default distance by route type. */
1765 if (rib->distance == 0)
1766 {
1767 rib->distance = route_info[rib->type].distance;
1768
1769 /* iBGP distance is 200. */
1770 if (rib->type == ZEBRA_ROUTE_BGP
1771 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1772 rib->distance = 200;
1773 }
1774
1775 /* Lookup route node.*/
1776 rn = route_node_get (table, (struct prefix *) p);
1777
1778 /* If same type of route are installed, treat it as a implicit
1779 withdraw. */
1780 for (same = rn->info; same; same = same->next)
1781 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00001782 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00001783 continue;
1784
paul718e3742002-12-13 20:15:29 +00001785 if (same->type == rib->type && same->table == rib->table
1786 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001787 break;
paul718e3742002-12-13 20:15:29 +00001788 }
paul4d38fdb2005-04-28 17:35:14 +00001789
paul718e3742002-12-13 20:15:29 +00001790 /* If this route is kernel route, set FIB flag to the route. */
1791 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
1792 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1793 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1794
1795 /* Link new rib to node.*/
1796 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001797 if (IS_ZEBRA_DEBUG_RIB)
1798 {
1799 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
1800 __func__, rn, rib);
1801 rib_dump (__func__, p, rib);
1802 }
paul718e3742002-12-13 20:15:29 +00001803
paul718e3742002-12-13 20:15:29 +00001804 /* Free implicit route.*/
1805 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001806 {
1807 if (IS_ZEBRA_DEBUG_RIB)
1808 {
1809 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
1810 __func__, rn, same);
1811 rib_dump (__func__, p, same);
1812 }
paul4d38fdb2005-04-28 17:35:14 +00001813 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001814 }
paul4d38fdb2005-04-28 17:35:14 +00001815
1816 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001817 return 0;
1818}
1819
hassoebf1ead2005-09-21 14:58:20 +00001820/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00001821int
1822rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
1823 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1824{
1825 struct route_table *table;
1826 struct route_node *rn;
1827 struct rib *rib;
1828 struct rib *fib = NULL;
1829 struct rib *same = NULL;
1830 struct nexthop *nexthop;
Stephen Hemminger81cce012009-04-28 14:28:00 -07001831 char buf1[INET_ADDRSTRLEN];
1832 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00001833
1834 /* Lookup table. */
1835 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1836 if (! table)
1837 return 0;
1838
1839 /* Apply mask. */
1840 apply_mask_ipv4 (p);
1841
paul5ec90d22003-06-19 01:41:37 +00001842 if (IS_ZEBRA_DEBUG_KERNEL && gate)
ajsb6178002004-12-07 21:12:56 +00001843 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001844 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul5ec90d22003-06-19 01:41:37 +00001845 p->prefixlen,
1846 inet_ntoa (*gate),
1847 ifindex);
1848
paul718e3742002-12-13 20:15:29 +00001849 /* Lookup route node. */
1850 rn = route_node_lookup (table, (struct prefix *) p);
1851 if (! rn)
1852 {
1853 if (IS_ZEBRA_DEBUG_KERNEL)
1854 {
1855 if (gate)
ajsb6178002004-12-07 21:12:56 +00001856 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001857 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001858 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07001859 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001860 ifindex);
1861 else
ajsb6178002004-12-07 21:12:56 +00001862 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001863 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001864 p->prefixlen,
1865 ifindex);
1866 }
1867 return ZEBRA_ERR_RTNOEXIST;
1868 }
1869
1870 /* Lookup same type route. */
1871 for (rib = rn->info; rib; rib = rib->next)
1872 {
Paul Jakma6d691122006-07-27 21:49:00 +00001873 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1874 continue;
1875
paul718e3742002-12-13 20:15:29 +00001876 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1877 fib = rib;
1878
hassoebf1ead2005-09-21 14:58:20 +00001879 if (rib->type != type)
1880 continue;
1881 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
1882 nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex)
paul718e3742002-12-13 20:15:29 +00001883 {
hassoebf1ead2005-09-21 14:58:20 +00001884 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00001885 {
hassoebf1ead2005-09-21 14:58:20 +00001886 rib->refcnt--;
1887 route_unlock_node (rn);
1888 route_unlock_node (rn);
1889 return 0;
paul718e3742002-12-13 20:15:29 +00001890 }
hassoebf1ead2005-09-21 14:58:20 +00001891 same = rib;
1892 break;
paul718e3742002-12-13 20:15:29 +00001893 }
hassoebf1ead2005-09-21 14:58:20 +00001894 /* Make sure that the route found has the same gateway. */
1895 else if (gate == NULL ||
1896 ((nexthop = rib->nexthop) &&
1897 (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
1898 IPV4_ADDR_SAME (&nexthop->rgate.ipv4, gate))))
paul5ec90d22003-06-19 01:41:37 +00001899 {
hassoebf1ead2005-09-21 14:58:20 +00001900 same = rib;
1901 break;
paul718e3742002-12-13 20:15:29 +00001902 }
1903 }
1904
1905 /* If same type of route can't be found and this message is from
1906 kernel. */
1907 if (! same)
1908 {
1909 if (fib && type == ZEBRA_ROUTE_KERNEL)
1910 {
1911 /* Unset flags. */
1912 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1913 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1914
1915 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1916 }
1917 else
1918 {
1919 if (IS_ZEBRA_DEBUG_KERNEL)
1920 {
1921 if (gate)
ajsb6178002004-12-07 21:12:56 +00001922 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001923 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001924 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07001925 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001926 ifindex,
1927 type);
1928 else
ajsb6178002004-12-07 21:12:56 +00001929 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001930 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001931 p->prefixlen,
1932 ifindex,
1933 type);
1934 }
1935 route_unlock_node (rn);
1936 return ZEBRA_ERR_RTNOEXIST;
1937 }
1938 }
paul4d38fdb2005-04-28 17:35:14 +00001939
paul718e3742002-12-13 20:15:29 +00001940 if (same)
1941 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00001942
paul718e3742002-12-13 20:15:29 +00001943 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001944 return 0;
1945}
1946
1947/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00001948static void
paul718e3742002-12-13 20:15:29 +00001949static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
1950{
1951 struct rib *rib;
1952 struct route_node *rn;
1953 struct route_table *table;
1954
1955 /* Lookup table. */
1956 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1957 if (! table)
1958 return;
1959
1960 /* Lookup existing route */
1961 rn = route_node_get (table, p);
1962 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00001963 {
1964 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1965 continue;
1966
1967 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1968 break;
1969 }
paul718e3742002-12-13 20:15:29 +00001970
1971 if (rib)
1972 {
1973 /* Same distance static route is there. Update it with new
1974 nexthop. */
paul718e3742002-12-13 20:15:29 +00001975 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001976 switch (si->type)
paul7021c422003-07-15 12:52:22 +00001977 {
1978 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00001979 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00001980 break;
1981 case STATIC_IPV4_IFNAME:
1982 nexthop_ifname_add (rib, si->gate.ifname);
1983 break;
1984 case STATIC_IPV4_BLACKHOLE:
1985 nexthop_blackhole_add (rib);
1986 break;
paul4d38fdb2005-04-28 17:35:14 +00001987 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00001988 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001989 }
1990 else
1991 {
1992 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00001993 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
1994
paul718e3742002-12-13 20:15:29 +00001995 rib->type = ZEBRA_ROUTE_STATIC;
1996 rib->distance = si->distance;
1997 rib->metric = 0;
1998 rib->nexthop_num = 0;
1999
2000 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002001 {
2002 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002003 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002004 break;
2005 case STATIC_IPV4_IFNAME:
2006 nexthop_ifname_add (rib, si->gate.ifname);
2007 break;
2008 case STATIC_IPV4_BLACKHOLE:
2009 nexthop_blackhole_add (rib);
2010 break;
2011 }
paul718e3742002-12-13 20:15:29 +00002012
hasso81dfcaa2003-05-25 19:21:25 +00002013 /* Save the flags of this static routes (reject, blackhole) */
2014 rib->flags = si->flags;
2015
paul718e3742002-12-13 20:15:29 +00002016 /* Link this rib to the tree. */
2017 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002018 }
2019}
2020
paula1ac18c2005-06-28 17:17:12 +00002021static int
paul718e3742002-12-13 20:15:29 +00002022static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2023{
2024 if (nexthop->type == NEXTHOP_TYPE_IPV4
2025 && si->type == STATIC_IPV4_GATEWAY
2026 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2027 return 1;
2028 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2029 && si->type == STATIC_IPV4_IFNAME
2030 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2031 return 1;
paul595db7f2003-05-25 21:35:06 +00002032 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2033 && si->type == STATIC_IPV4_BLACKHOLE)
2034 return 1;
paule8e19462006-01-19 20:16:55 +00002035 return 0;
paul718e3742002-12-13 20:15:29 +00002036}
2037
2038/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002039static void
paul718e3742002-12-13 20:15:29 +00002040static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
2041{
2042 struct route_node *rn;
2043 struct rib *rib;
2044 struct nexthop *nexthop;
2045 struct route_table *table;
2046
2047 /* Lookup table. */
2048 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2049 if (! table)
2050 return;
paul4d38fdb2005-04-28 17:35:14 +00002051
paul718e3742002-12-13 20:15:29 +00002052 /* Lookup existing route with type and distance. */
2053 rn = route_node_lookup (table, p);
2054 if (! rn)
2055 return;
2056
2057 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002058 {
2059 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2060 continue;
2061
2062 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2063 break;
2064 }
paul718e3742002-12-13 20:15:29 +00002065
2066 if (! rib)
2067 {
2068 route_unlock_node (rn);
2069 return;
2070 }
2071
2072 /* Lookup nexthop. */
2073 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2074 if (static_ipv4_nexthop_same (nexthop, si))
2075 break;
2076
2077 /* Can't find nexthop. */
2078 if (! nexthop)
2079 {
2080 route_unlock_node (rn);
2081 return;
2082 }
2083
2084 /* Check nexthop. */
2085 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002086 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002087 else
2088 {
paul6baeb982003-10-28 03:47:15 +00002089 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2090 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002091 nexthop_delete (rib, nexthop);
2092 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002093 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002094 }
paul718e3742002-12-13 20:15:29 +00002095 /* Unlock node. */
2096 route_unlock_node (rn);
2097}
2098
2099/* Add static route into static route configuration. */
2100int
hasso39db97e2004-10-12 20:50:58 +00002101static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00002102 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002103{
2104 u_char type = 0;
2105 struct route_node *rn;
2106 struct static_ipv4 *si;
2107 struct static_ipv4 *pp;
2108 struct static_ipv4 *cp;
2109 struct static_ipv4 *update = NULL;
2110 struct route_table *stable;
2111
2112 /* Lookup table. */
2113 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2114 if (! stable)
2115 return -1;
2116
2117 /* Lookup static route prefix. */
2118 rn = route_node_get (stable, p);
2119
2120 /* Make flags. */
2121 if (gate)
2122 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002123 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002124 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002125 else
2126 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002127
2128 /* Do nothing if there is a same static route. */
2129 for (si = rn->info; si; si = si->next)
2130 {
2131 if (type == si->type
2132 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2133 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2134 {
2135 if (distance == si->distance)
2136 {
2137 route_unlock_node (rn);
2138 return 0;
2139 }
2140 else
2141 update = si;
2142 }
2143 }
2144
Paul Jakma3c0755d2006-12-08 00:53:14 +00002145 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002146 if (update)
2147 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
2148
2149 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002150 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
paul718e3742002-12-13 20:15:29 +00002151
2152 si->type = type;
2153 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002154 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002155
2156 if (gate)
2157 si->gate.ipv4 = *gate;
2158 if (ifname)
2159 si->gate.ifname = XSTRDUP (0, ifname);
2160
2161 /* Add new static route information to the tree with sort by
2162 distance value and gateway address. */
2163 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2164 {
2165 if (si->distance < cp->distance)
2166 break;
2167 if (si->distance > cp->distance)
2168 continue;
2169 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2170 {
2171 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2172 break;
2173 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2174 continue;
2175 }
2176 }
2177
2178 /* Make linked list. */
2179 if (pp)
2180 pp->next = si;
2181 else
2182 rn->info = si;
2183 if (cp)
2184 cp->prev = si;
2185 si->prev = pp;
2186 si->next = cp;
2187
2188 /* Install into rib. */
2189 static_install_ipv4 (p, si);
2190
2191 return 1;
2192}
2193
2194/* Delete static route from static route configuration. */
2195int
hasso39db97e2004-10-12 20:50:58 +00002196static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00002197 u_char distance, u_int32_t vrf_id)
2198{
2199 u_char type = 0;
2200 struct route_node *rn;
2201 struct static_ipv4 *si;
2202 struct route_table *stable;
2203
2204 /* Lookup table. */
2205 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2206 if (! stable)
2207 return -1;
2208
2209 /* Lookup static route prefix. */
2210 rn = route_node_lookup (stable, p);
2211 if (! rn)
2212 return 0;
2213
2214 /* Make flags. */
2215 if (gate)
2216 type = STATIC_IPV4_GATEWAY;
2217 else if (ifname)
2218 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002219 else
2220 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002221
2222 /* Find same static route is the tree */
2223 for (si = rn->info; si; si = si->next)
2224 if (type == si->type
2225 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2226 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2227 break;
2228
2229 /* Can't find static route. */
2230 if (! si)
2231 {
2232 route_unlock_node (rn);
2233 return 0;
2234 }
2235
2236 /* Install into rib. */
2237 static_uninstall_ipv4 (p, si);
2238
2239 /* Unlink static route from linked list. */
2240 if (si->prev)
2241 si->prev->next = si->next;
2242 else
2243 rn->info = si->next;
2244 if (si->next)
2245 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002246 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002247
2248 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002249 if (ifname)
2250 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002251 XFREE (MTYPE_STATIC_IPV4, si);
2252
paul143a3852003-09-29 20:06:13 +00002253 route_unlock_node (rn);
2254
paul718e3742002-12-13 20:15:29 +00002255 return 1;
2256}
2257
2258
2259#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00002260static int
paul718e3742002-12-13 20:15:29 +00002261rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2262 struct in6_addr *gate, unsigned int ifindex, int table)
2263{
hasso726f9b22003-05-25 21:04:54 +00002264 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2265#if defined (MUSICA) || defined (LINUX)
2266 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2267 if (p->prefixlen == 96)
2268 return 0;
2269#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00002270 return 1;
hasso726f9b22003-05-25 21:04:54 +00002271 }
paul718e3742002-12-13 20:15:29 +00002272 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
2273 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
2274 {
2275 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
2276 return 1;
2277 }
2278 return 0;
2279}
2280
2281int
2282rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00002283 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
2284 u_int32_t metric, u_char distance)
paul718e3742002-12-13 20:15:29 +00002285{
2286 struct rib *rib;
2287 struct rib *same = NULL;
2288 struct route_table *table;
2289 struct route_node *rn;
2290 struct nexthop *nexthop;
2291
paul718e3742002-12-13 20:15:29 +00002292 /* Lookup table. */
2293 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2294 if (! table)
2295 return 0;
2296
2297 /* Make sure mask is applied. */
2298 apply_mask_ipv6 (p);
2299
2300 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002301 if (!distance)
2302 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002303
2304 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2305 distance = 200;
2306
2307 /* Filter bogus route. */
2308 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
2309 return 0;
2310
2311 /* Lookup route node.*/
2312 rn = route_node_get (table, (struct prefix *) p);
2313
2314 /* If same type of route are installed, treat it as a implicit
2315 withdraw. */
2316 for (rib = rn->info; rib; rib = rib->next)
2317 {
Paul Jakma6d691122006-07-27 21:49:00 +00002318 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2319 continue;
2320
hassoebf1ead2005-09-21 14:58:20 +00002321 if (rib->type != type)
2322 continue;
2323 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002324 {
2325 same = rib;
paul718e3742002-12-13 20:15:29 +00002326 break;
2327 }
hassoebf1ead2005-09-21 14:58:20 +00002328 else if ((nexthop = rib->nexthop) &&
2329 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2330 nexthop->ifindex == ifindex)
2331 {
2332 rib->refcnt++;
2333 return 0;
2334 }
paul718e3742002-12-13 20:15:29 +00002335 }
2336
2337 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002338 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2339
paul718e3742002-12-13 20:15:29 +00002340 rib->type = type;
2341 rib->distance = distance;
2342 rib->flags = flags;
2343 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00002344 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00002345 rib->nexthop_num = 0;
2346 rib->uptime = time (NULL);
2347
2348 /* Nexthop settings. */
2349 if (gate)
2350 {
2351 if (ifindex)
2352 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2353 else
2354 nexthop_ipv6_add (rib, gate);
2355 }
2356 else
2357 nexthop_ifindex_add (rib, ifindex);
2358
2359 /* If this route is kernel route, set FIB flag to the route. */
2360 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2361 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2362 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2363
2364 /* Link new rib to node.*/
2365 rib_addnode (rn, rib);
2366
paul718e3742002-12-13 20:15:29 +00002367 /* Free implicit route.*/
2368 if (same)
paul4d38fdb2005-04-28 17:35:14 +00002369 rib_delnode (rn, same);
2370
2371 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002372 return 0;
2373}
2374
hassoebf1ead2005-09-21 14:58:20 +00002375/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002376int
2377rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
2378 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
2379{
2380 struct route_table *table;
2381 struct route_node *rn;
2382 struct rib *rib;
2383 struct rib *fib = NULL;
2384 struct rib *same = NULL;
2385 struct nexthop *nexthop;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002386 char buf1[INET6_ADDRSTRLEN];
2387 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002388
2389 /* Apply mask. */
2390 apply_mask_ipv6 (p);
2391
2392 /* Lookup table. */
2393 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2394 if (! table)
2395 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002396
paul718e3742002-12-13 20:15:29 +00002397 /* Lookup route node. */
2398 rn = route_node_lookup (table, (struct prefix *) p);
2399 if (! rn)
2400 {
2401 if (IS_ZEBRA_DEBUG_KERNEL)
2402 {
2403 if (gate)
ajsb6178002004-12-07 21:12:56 +00002404 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002405 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002406 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002407 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002408 ifindex);
2409 else
ajsb6178002004-12-07 21:12:56 +00002410 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002411 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002412 p->prefixlen,
2413 ifindex);
2414 }
2415 return ZEBRA_ERR_RTNOEXIST;
2416 }
2417
2418 /* Lookup same type route. */
2419 for (rib = rn->info; rib; rib = rib->next)
2420 {
Paul Jakma6d691122006-07-27 21:49:00 +00002421 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2422 continue;
2423
paul718e3742002-12-13 20:15:29 +00002424 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2425 fib = rib;
2426
hassoebf1ead2005-09-21 14:58:20 +00002427 if (rib->type != type)
2428 continue;
2429 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
2430 nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex)
paul718e3742002-12-13 20:15:29 +00002431 {
hassoebf1ead2005-09-21 14:58:20 +00002432 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002433 {
hassoebf1ead2005-09-21 14:58:20 +00002434 rib->refcnt--;
2435 route_unlock_node (rn);
2436 route_unlock_node (rn);
2437 return 0;
paul718e3742002-12-13 20:15:29 +00002438 }
hassoebf1ead2005-09-21 14:58:20 +00002439 same = rib;
2440 break;
paul718e3742002-12-13 20:15:29 +00002441 }
hassoebf1ead2005-09-21 14:58:20 +00002442 /* Make sure that the route found has the same gateway. */
2443 else if (gate == NULL ||
2444 ((nexthop = rib->nexthop) &&
2445 (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate) ||
2446 IPV6_ADDR_SAME (&nexthop->rgate.ipv6, gate))))
paul718e3742002-12-13 20:15:29 +00002447 {
hassoebf1ead2005-09-21 14:58:20 +00002448 same = rib;
2449 break;
paul718e3742002-12-13 20:15:29 +00002450 }
2451 }
2452
2453 /* If same type of route can't be found and this message is from
2454 kernel. */
2455 if (! same)
2456 {
2457 if (fib && type == ZEBRA_ROUTE_KERNEL)
2458 {
2459 /* Unset flags. */
2460 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2461 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2462
2463 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2464 }
2465 else
2466 {
2467 if (IS_ZEBRA_DEBUG_KERNEL)
2468 {
2469 if (gate)
ajsb6178002004-12-07 21:12:56 +00002470 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002471 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002472 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002473 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002474 ifindex,
2475 type);
2476 else
ajsb6178002004-12-07 21:12:56 +00002477 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002478 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002479 p->prefixlen,
2480 ifindex,
2481 type);
2482 }
2483 route_unlock_node (rn);
2484 return ZEBRA_ERR_RTNOEXIST;
2485 }
2486 }
2487
2488 if (same)
2489 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002490
paul718e3742002-12-13 20:15:29 +00002491 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002492 return 0;
2493}
2494
2495/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002496static void
paul718e3742002-12-13 20:15:29 +00002497static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2498{
2499 struct rib *rib;
2500 struct route_table *table;
2501 struct route_node *rn;
2502
2503 /* Lookup table. */
2504 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2505 if (! table)
2506 return;
2507
2508 /* Lookup existing route */
2509 rn = route_node_get (table, p);
2510 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002511 {
2512 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2513 continue;
2514
2515 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2516 break;
2517 }
paul718e3742002-12-13 20:15:29 +00002518
2519 if (rib)
2520 {
2521 /* Same distance static route is there. Update it with new
2522 nexthop. */
paul718e3742002-12-13 20:15:29 +00002523 route_unlock_node (rn);
2524
2525 switch (si->type)
2526 {
2527 case STATIC_IPV6_GATEWAY:
2528 nexthop_ipv6_add (rib, &si->ipv6);
2529 break;
2530 case STATIC_IPV6_IFNAME:
2531 nexthop_ifname_add (rib, si->ifname);
2532 break;
2533 case STATIC_IPV6_GATEWAY_IFNAME:
2534 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2535 break;
2536 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002537 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002538 }
2539 else
2540 {
2541 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002542 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2543
paul718e3742002-12-13 20:15:29 +00002544 rib->type = ZEBRA_ROUTE_STATIC;
2545 rib->distance = si->distance;
2546 rib->metric = 0;
2547 rib->nexthop_num = 0;
2548
2549 switch (si->type)
2550 {
2551 case STATIC_IPV6_GATEWAY:
2552 nexthop_ipv6_add (rib, &si->ipv6);
2553 break;
2554 case STATIC_IPV6_IFNAME:
2555 nexthop_ifname_add (rib, si->ifname);
2556 break;
2557 case STATIC_IPV6_GATEWAY_IFNAME:
2558 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2559 break;
2560 }
2561
hasso81dfcaa2003-05-25 19:21:25 +00002562 /* Save the flags of this static routes (reject, blackhole) */
2563 rib->flags = si->flags;
2564
paul718e3742002-12-13 20:15:29 +00002565 /* Link this rib to the tree. */
2566 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002567 }
2568}
2569
paula1ac18c2005-06-28 17:17:12 +00002570static int
paul718e3742002-12-13 20:15:29 +00002571static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2572{
2573 if (nexthop->type == NEXTHOP_TYPE_IPV6
2574 && si->type == STATIC_IPV6_GATEWAY
2575 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2576 return 1;
2577 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2578 && si->type == STATIC_IPV6_IFNAME
2579 && strcmp (nexthop->ifname, si->ifname) == 0)
2580 return 1;
2581 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2582 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2583 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2584 && strcmp (nexthop->ifname, si->ifname) == 0)
2585 return 1;
paule8e19462006-01-19 20:16:55 +00002586 return 0;
paul718e3742002-12-13 20:15:29 +00002587}
2588
paula1ac18c2005-06-28 17:17:12 +00002589static void
paul718e3742002-12-13 20:15:29 +00002590static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2591{
2592 struct route_table *table;
2593 struct route_node *rn;
2594 struct rib *rib;
2595 struct nexthop *nexthop;
2596
2597 /* Lookup table. */
2598 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2599 if (! table)
2600 return;
2601
2602 /* Lookup existing route with type and distance. */
2603 rn = route_node_lookup (table, (struct prefix *) p);
2604 if (! rn)
2605 return;
2606
2607 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002608 {
2609 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2610 continue;
2611
2612 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2613 break;
2614 }
2615
paul718e3742002-12-13 20:15:29 +00002616 if (! rib)
2617 {
2618 route_unlock_node (rn);
2619 return;
2620 }
2621
2622 /* Lookup nexthop. */
2623 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2624 if (static_ipv6_nexthop_same (nexthop, si))
2625 break;
2626
2627 /* Can't find nexthop. */
2628 if (! nexthop)
2629 {
2630 route_unlock_node (rn);
2631 return;
2632 }
2633
2634 /* Check nexthop. */
2635 if (rib->nexthop_num == 1)
2636 {
2637 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002638 }
2639 else
2640 {
paul6baeb982003-10-28 03:47:15 +00002641 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2642 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002643 nexthop_delete (rib, nexthop);
2644 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002645 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002646 }
paul718e3742002-12-13 20:15:29 +00002647 /* Unlock node. */
2648 route_unlock_node (rn);
2649}
2650
2651/* Add static route into static route configuration. */
2652int
2653static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002654 const char *ifname, u_char flags, u_char distance,
2655 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002656{
2657 struct route_node *rn;
2658 struct static_ipv6 *si;
2659 struct static_ipv6 *pp;
2660 struct static_ipv6 *cp;
2661 struct route_table *stable;
2662
2663 /* Lookup table. */
2664 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2665 if (! stable)
2666 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00002667
2668 if (!gate &&
2669 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
2670 return -1;
2671
2672 if (!ifname &&
2673 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
2674 return -1;
paul718e3742002-12-13 20:15:29 +00002675
2676 /* Lookup static route prefix. */
2677 rn = route_node_get (stable, p);
2678
2679 /* Do nothing if there is a same static route. */
2680 for (si = rn->info; si; si = si->next)
2681 {
2682 if (distance == si->distance
2683 && type == si->type
2684 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2685 && (! ifname || strcmp (ifname, si->ifname) == 0))
2686 {
2687 route_unlock_node (rn);
2688 return 0;
2689 }
2690 }
2691
2692 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002693 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
paul718e3742002-12-13 20:15:29 +00002694
2695 si->type = type;
2696 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002697 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002698
2699 switch (type)
2700 {
2701 case STATIC_IPV6_GATEWAY:
2702 si->ipv6 = *gate;
2703 break;
2704 case STATIC_IPV6_IFNAME:
2705 si->ifname = XSTRDUP (0, ifname);
2706 break;
2707 case STATIC_IPV6_GATEWAY_IFNAME:
2708 si->ipv6 = *gate;
2709 si->ifname = XSTRDUP (0, ifname);
2710 break;
2711 }
2712
2713 /* Add new static route information to the tree with sort by
2714 distance value and gateway address. */
2715 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2716 {
2717 if (si->distance < cp->distance)
2718 break;
2719 if (si->distance > cp->distance)
2720 continue;
2721 }
2722
2723 /* Make linked list. */
2724 if (pp)
2725 pp->next = si;
2726 else
2727 rn->info = si;
2728 if (cp)
2729 cp->prev = si;
2730 si->prev = pp;
2731 si->next = cp;
2732
2733 /* Install into rib. */
2734 static_install_ipv6 (p, si);
2735
2736 return 1;
2737}
2738
2739/* Delete static route from static route configuration. */
2740int
2741static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002742 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002743{
2744 struct route_node *rn;
2745 struct static_ipv6 *si;
2746 struct route_table *stable;
2747
2748 /* Lookup table. */
2749 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2750 if (! stable)
2751 return -1;
2752
2753 /* Lookup static route prefix. */
2754 rn = route_node_lookup (stable, p);
2755 if (! rn)
2756 return 0;
2757
2758 /* Find same static route is the tree */
2759 for (si = rn->info; si; si = si->next)
2760 if (distance == si->distance
2761 && type == si->type
2762 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2763 && (! ifname || strcmp (ifname, si->ifname) == 0))
2764 break;
2765
2766 /* Can't find static route. */
2767 if (! si)
2768 {
2769 route_unlock_node (rn);
2770 return 0;
2771 }
2772
2773 /* Install into rib. */
2774 static_uninstall_ipv6 (p, si);
2775
2776 /* Unlink static route from linked list. */
2777 if (si->prev)
2778 si->prev->next = si->next;
2779 else
2780 rn->info = si->next;
2781 if (si->next)
2782 si->next->prev = si->prev;
2783
2784 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002785 if (ifname)
2786 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00002787 XFREE (MTYPE_STATIC_IPV6, si);
2788
2789 return 1;
2790}
2791#endif /* HAVE_IPV6 */
2792
2793/* RIB update function. */
2794void
paula1ac18c2005-06-28 17:17:12 +00002795rib_update (void)
paul718e3742002-12-13 20:15:29 +00002796{
2797 struct route_node *rn;
2798 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00002799
paul718e3742002-12-13 20:15:29 +00002800 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2801 if (table)
2802 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002803 if (rn->info)
Paul Jakma6d691122006-07-27 21:49:00 +00002804 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002805
2806 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2807 if (table)
2808 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002809 if (rn->info)
Paul Jakma6d691122006-07-27 21:49:00 +00002810 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002811}
2812
paul718e3742002-12-13 20:15:29 +00002813
2814/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00002815static void
paul718e3742002-12-13 20:15:29 +00002816rib_weed_table (struct route_table *table)
2817{
2818 struct route_node *rn;
2819 struct rib *rib;
2820 struct rib *next;
2821
2822 if (table)
2823 for (rn = route_top (table); rn; rn = route_next (rn))
2824 for (rib = rn->info; rib; rib = next)
2825 {
2826 next = rib->next;
2827
Paul Jakma6d691122006-07-27 21:49:00 +00002828 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2829 continue;
2830
paulb21b19c2003-06-15 01:28:29 +00002831 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00002832 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00002833 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002834 }
2835}
2836
2837/* Delete all routes from non main table. */
2838void
paula1ac18c2005-06-28 17:17:12 +00002839rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00002840{
2841 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2842 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2843}
2844
2845/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00002846static void
paul718e3742002-12-13 20:15:29 +00002847rib_sweep_table (struct route_table *table)
2848{
2849 struct route_node *rn;
2850 struct rib *rib;
2851 struct rib *next;
2852 int ret = 0;
2853
2854 if (table)
2855 for (rn = route_top (table); rn; rn = route_next (rn))
2856 for (rib = rn->info; rib; rib = next)
2857 {
2858 next = rib->next;
2859
Paul Jakma6d691122006-07-27 21:49:00 +00002860 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2861 continue;
2862
paul718e3742002-12-13 20:15:29 +00002863 if (rib->type == ZEBRA_ROUTE_KERNEL &&
2864 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
2865 {
2866 ret = rib_uninstall_kernel (rn, rib);
2867 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00002868 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002869 }
2870 }
2871}
2872
2873/* Sweep all RIB tables. */
2874void
paula1ac18c2005-06-28 17:17:12 +00002875rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00002876{
2877 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2878 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2879}
2880
2881/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00002882static void
paul718e3742002-12-13 20:15:29 +00002883rib_close_table (struct route_table *table)
2884{
2885 struct route_node *rn;
2886 struct rib *rib;
2887
2888 if (table)
2889 for (rn = route_top (table); rn; rn = route_next (rn))
2890 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002891 {
2892 if (! RIB_SYSTEM_ROUTE (rib)
2893 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2894 rib_uninstall_kernel (rn, rib);
2895 }
paul718e3742002-12-13 20:15:29 +00002896}
2897
2898/* Close all RIB tables. */
2899void
paula1ac18c2005-06-28 17:17:12 +00002900rib_close (void)
paul718e3742002-12-13 20:15:29 +00002901{
2902 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2903 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2904}
2905
2906/* Routing information base initialize. */
2907void
paula1ac18c2005-06-28 17:17:12 +00002908rib_init (void)
paul718e3742002-12-13 20:15:29 +00002909{
paul4d38fdb2005-04-28 17:35:14 +00002910 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00002911 /* VRF initialization. */
2912 vrf_init ();
2913}