blob: 8da6c84a1e1dc52c8b5fc52de97cec876d80ee68 [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
Josh Bailey26e2ae32012-03-22 01:09:21 -0700228struct 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{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001274 char buf[INET_ADDRSTRLEN];
1275 assert (zebra && rn);
paul4d38fdb2005-04-28 17:35:14 +00001276
Paul Jakma93bdada2007-08-06 19:25:11 +00001277 if (IS_ZEBRA_DEBUG_RIB_Q)
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001278 inet_ntop (AF_INET, &rn->p.u.prefix, buf, INET_ADDRSTRLEN);
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001279
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001280 /* Pointless to queue a route_node with no RIB entries to add or remove */
1281 if (!rn->info)
1282 {
1283 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1284 __func__, rn, rn->lock);
1285 zlog_backtrace(LOG_DEBUG);
1286 return;
1287 }
1288
1289 if (IS_ZEBRA_DEBUG_RIB_Q)
1290 zlog_info ("%s: %s/%d: work queue added", __func__, buf, rn->p.prefixlen);
1291
1292 assert (zebra);
1293
1294 if (zebra->ribq == NULL)
1295 {
1296 zlog_err ("%s: work_queue does not exist!", __func__);
1297 return;
Paul Jakma6d691122006-07-27 21:49:00 +00001298 }
paul4d38fdb2005-04-28 17:35:14 +00001299
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001300 /*
1301 * The RIB queue should normally be either empty or holding the only
1302 * work_queue_item element. In the latter case this element would
1303 * hold a pointer to the meta queue structure, which must be used to
1304 * actually queue the route nodes to process. So create the MQ
1305 * holder, if necessary, then push the work into it in any case.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001306 * This semantics was introduced after 0.99.9 release.
1307 */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001308 if (!zebra->ribq->items->count)
1309 work_queue_add (zebra->ribq, zebra->mq);
1310
1311 rib_meta_queue_add (zebra->mq, rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001312
1313 if (IS_ZEBRA_DEBUG_RIB_Q)
1314 zlog_debug ("%s: %s/%d: rn %p queued", __func__, buf, rn->p.prefixlen, rn);
1315
1316 return;
paul4d38fdb2005-04-28 17:35:14 +00001317}
1318
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001319/* Create new meta queue.
1320 A destructor function doesn't seem to be necessary here.
1321 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001322static struct meta_queue *
1323meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001324{
1325 struct meta_queue *new;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001326 unsigned i;
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001327
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001328 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1329 assert(new);
1330
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001331 for (i = 0; i < MQ_SIZE; i++)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001332 {
1333 new->subq[i] = list_new ();
1334 assert(new->subq[i]);
1335 }
1336
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001337 return new;
1338}
1339
paul4d38fdb2005-04-28 17:35:14 +00001340/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001341static void
paul4d38fdb2005-04-28 17:35:14 +00001342rib_queue_init (struct zebra_t *zebra)
1343{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001344 assert (zebra);
1345
paul4d38fdb2005-04-28 17:35:14 +00001346 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001347 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001348 {
Paul Jakma6d691122006-07-27 21:49:00 +00001349 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001350 return;
1351 }
1352
1353 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001354 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001355 zebra->ribq->spec.errorfunc = NULL;
paul4d38fdb2005-04-28 17:35:14 +00001356 /* XXX: TODO: These should be runtime configurable via vty */
1357 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001358 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001359
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001360 if (!(zebra->mq = meta_queue_new ()))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001361 {
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001362 zlog_err ("%s: could not initialise meta queue!", __func__);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001363 return;
1364 }
1365 return;
paul718e3742002-12-13 20:15:29 +00001366}
1367
Paul Jakma6d691122006-07-27 21:49:00 +00001368/* RIB updates are processed via a queue of pointers to route_nodes.
1369 *
1370 * The queue length is bounded by the maximal size of the routing table,
1371 * as a route_node will not be requeued, if already queued.
1372 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001373 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1374 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1375 * and then submit route_node to queue for best-path selection later.
1376 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001377 *
1378 * Deleted RIBs are reaped during best-path selection.
1379 *
1380 * rib_addnode
1381 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001382 * |-------->| | best RIB, if required
1383 * | |
1384 * static_install->|->rib_addqueue...... -> rib_process
1385 * | |
1386 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001387 * |-> set RIB_ENTRY_REMOVE |
1388 * rib_delnode (RIB freed)
1389 *
1390 *
1391 * Queueing state for a route_node is kept in the head RIB entry, this
1392 * state must be preserved as and when the head RIB entry of a
1393 * route_node is changed by rib_unlink / rib_link. A small complication,
1394 * but saves having to allocate a dedicated object for this.
1395 *
1396 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1397 *
1398 * - route_nodes: refcounted by:
1399 * - RIBs attached to route_node:
1400 * - managed by: rib_link/unlink
1401 * - route_node processing queue
1402 * - managed by: rib_addqueue, rib_process.
1403 *
1404 */
1405
paul718e3742002-12-13 20:15:29 +00001406/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001407static void
Paul Jakma6d691122006-07-27 21:49:00 +00001408rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001409{
1410 struct rib *head;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001411 char buf[INET6_ADDRSTRLEN];
paul4d38fdb2005-04-28 17:35:14 +00001412
1413 assert (rib && rn);
1414
Paul Jakma6d691122006-07-27 21:49:00 +00001415 route_lock_node (rn); /* rn route table reference */
1416
1417 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001418 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001419 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001420 zlog_debug ("%s: %s/%d: rn %p, rib %p", __func__,
1421 buf, rn->p.prefixlen, rn, rib);
1422 }
Paul Jakma6d691122006-07-27 21:49:00 +00001423
paul718e3742002-12-13 20:15:29 +00001424 head = rn->info;
1425 if (head)
Paul Jakma6d691122006-07-27 21:49:00 +00001426 {
1427 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001428 zlog_debug ("%s: %s/%d: new head, rn_status copied over", __func__,
1429 buf, rn->p.prefixlen);
Paul Jakma6d691122006-07-27 21:49:00 +00001430 head->prev = rib;
1431 /* Transfer the rn status flags to the new head RIB */
1432 rib->rn_status = head->rn_status;
1433 }
paul718e3742002-12-13 20:15:29 +00001434 rib->next = head;
1435 rn->info = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001436 rib_queue_add (&zebrad, rn);
1437}
1438
1439static void
1440rib_addnode (struct route_node *rn, struct rib *rib)
1441{
1442 /* RIB node has been un-removed before route-node is processed.
1443 * route_node must hence already be on the queue for processing..
1444 */
1445 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1446 {
1447 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001448 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001449 char buf[INET6_ADDRSTRLEN];
1450 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001451 zlog_debug ("%s: %s/%d: rn %p, un-removed rib %p",
1452 __func__, buf, rn->p.prefixlen, rn, rib);
1453 }
Paul Jakma6d691122006-07-27 21:49:00 +00001454 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1455 return;
1456 }
1457 rib_link (rn, rib);
1458}
1459
1460static void
1461rib_unlink (struct route_node *rn, struct rib *rib)
1462{
1463 struct nexthop *nexthop, *next;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001464 char buf[INET6_ADDRSTRLEN];
Paul Jakma6d691122006-07-27 21:49:00 +00001465
1466 assert (rn && rib);
1467
1468 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001469 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001470 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001471 zlog_debug ("%s: %s/%d: rn %p, rib %p",
1472 __func__, buf, rn->p.prefixlen, rn, rib);
1473 }
Paul Jakma6d691122006-07-27 21:49:00 +00001474
1475 if (rib->next)
1476 rib->next->prev = rib->prev;
1477
1478 if (rib->prev)
1479 rib->prev->next = rib->next;
1480 else
1481 {
1482 rn->info = rib->next;
1483
1484 if (rn->info)
1485 {
1486 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001487 zlog_debug ("%s: %s/%d: rn %p, rib %p, new head copy",
1488 __func__, buf, rn->p.prefixlen, rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001489 rib->next->rn_status = rib->rn_status;
1490 }
1491 }
1492
1493 /* free RIB and nexthops */
1494 for (nexthop = rib->nexthop; nexthop; nexthop = next)
1495 {
1496 next = nexthop->next;
1497 nexthop_free (nexthop);
1498 }
1499 XFREE (MTYPE_RIB, rib);
1500
1501 route_unlock_node (rn); /* rn route table reference */
paul718e3742002-12-13 20:15:29 +00001502}
1503
paula1ac18c2005-06-28 17:17:12 +00001504static void
paul718e3742002-12-13 20:15:29 +00001505rib_delnode (struct route_node *rn, struct rib *rib)
1506{
Paul Jakma6d691122006-07-27 21:49:00 +00001507 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001508 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001509 char buf[INET6_ADDRSTRLEN];
1510 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001511 zlog_debug ("%s: %s/%d: rn %p, rib %p, removing", __func__,
1512 buf, rn->p.prefixlen, rn, rib);
1513 }
Paul Jakma6d691122006-07-27 21:49:00 +00001514 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1515 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001516}
1517
1518int
1519rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001520 struct in_addr *gate, struct in_addr *src,
1521 unsigned int ifindex, u_int32_t vrf_id,
paul718e3742002-12-13 20:15:29 +00001522 u_int32_t metric, u_char distance)
1523{
1524 struct rib *rib;
1525 struct rib *same = NULL;
1526 struct route_table *table;
1527 struct route_node *rn;
1528 struct nexthop *nexthop;
1529
1530 /* Lookup table. */
1531 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1532 if (! table)
1533 return 0;
1534
1535 /* Make it sure prefixlen is applied to the prefix. */
1536 apply_mask_ipv4 (p);
1537
1538 /* Set default distance by route type. */
1539 if (distance == 0)
1540 {
1541 distance = route_info[type].distance;
1542
1543 /* iBGP distance is 200. */
1544 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1545 distance = 200;
1546 }
1547
1548 /* Lookup route node.*/
1549 rn = route_node_get (table, (struct prefix *) p);
1550
1551 /* If same type of route are installed, treat it as a implicit
1552 withdraw. */
1553 for (rib = rn->info; rib; rib = rib->next)
1554 {
Paul Jakma6d691122006-07-27 21:49:00 +00001555 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1556 continue;
1557
hassoebf1ead2005-09-21 14:58:20 +00001558 if (rib->type != type)
1559 continue;
1560 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001561 {
1562 same = rib;
1563 break;
1564 }
hassoebf1ead2005-09-21 14:58:20 +00001565 /* Duplicate connected route comes in. */
1566 else if ((nexthop = rib->nexthop) &&
1567 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001568 nexthop->ifindex == ifindex &&
1569 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001570 {
1571 rib->refcnt++;
1572 return 0 ;
1573 }
paul718e3742002-12-13 20:15:29 +00001574 }
1575
1576 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001577 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001578 rib->type = type;
1579 rib->distance = distance;
1580 rib->flags = flags;
1581 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001582 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001583 rib->nexthop_num = 0;
1584 rib->uptime = time (NULL);
1585
1586 /* Nexthop settings. */
1587 if (gate)
1588 {
1589 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001590 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001591 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001592 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001593 }
1594 else
1595 nexthop_ifindex_add (rib, ifindex);
1596
1597 /* If this route is kernel route, set FIB flag to the route. */
1598 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1599 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1600 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1601
1602 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001603 if (IS_ZEBRA_DEBUG_RIB)
1604 zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
paul718e3742002-12-13 20:15:29 +00001605 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001606
paul718e3742002-12-13 20:15:29 +00001607 /* Free implicit route.*/
1608 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001609 {
1610 if (IS_ZEBRA_DEBUG_RIB)
1611 zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001612 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001613 }
paul4d38fdb2005-04-28 17:35:14 +00001614
1615 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001616 return 0;
1617}
1618
Denis Ovsienkodc958242007-08-13 16:03:06 +00001619/* This function dumps the contents of a given RIB entry into
1620 * standard debug log. Calling function name and IP prefix in
1621 * question are passed as 1st and 2nd arguments.
1622 */
1623
1624void rib_dump (const char * func, const struct prefix_ipv4 * p, const struct rib * rib)
1625{
1626 char straddr1[INET_ADDRSTRLEN], straddr2[INET_ADDRSTRLEN];
1627 struct nexthop *nexthop;
1628
1629 inet_ntop (AF_INET, &p->prefix, straddr1, INET_ADDRSTRLEN);
1630 zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr1, p->prefixlen);
1631 zlog_debug
1632 (
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001633 "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
Denis Ovsienkodc958242007-08-13 16:03:06 +00001634 func,
1635 rib->refcnt,
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001636 (unsigned long) rib->uptime,
Denis Ovsienkodc958242007-08-13 16:03:06 +00001637 rib->type,
1638 rib->table
1639 );
1640 zlog_debug
1641 (
1642 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1643 func,
1644 rib->metric,
1645 rib->distance,
1646 rib->flags,
1647 rib->status
1648 );
1649 zlog_debug
1650 (
1651 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1652 func,
1653 rib->nexthop_num,
1654 rib->nexthop_active_num,
1655 rib->nexthop_fib_num
1656 );
1657 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1658 {
1659 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, straddr1, INET_ADDRSTRLEN);
1660 inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, straddr2, INET_ADDRSTRLEN);
1661 zlog_debug
1662 (
1663 "%s: NH %s (%s) with flags %s%s%s",
1664 func,
1665 straddr1,
1666 straddr2,
1667 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1668 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1669 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1670 );
1671 }
1672 zlog_debug ("%s: dump complete", func);
1673}
1674
1675/* This is an exported helper to rtm_read() to dump the strange
1676 * RIB entry found by rib_lookup_ipv4_route()
1677 */
1678
1679void rib_lookup_and_dump (struct prefix_ipv4 * p)
1680{
1681 struct route_table *table;
1682 struct route_node *rn;
1683 struct rib *rib;
1684 char prefix_buf[INET_ADDRSTRLEN];
1685
1686 /* Lookup table. */
1687 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1688 if (! table)
1689 {
1690 zlog_err ("%s: vrf_table() returned NULL", __func__);
1691 return;
1692 }
1693
1694 inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
1695 /* Scan the RIB table for exactly matching RIB entry. */
1696 rn = route_node_lookup (table, (struct prefix *) p);
1697
1698 /* No route for this prefix. */
1699 if (! rn)
1700 {
1701 zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
1702 return;
1703 }
1704
1705 /* Unlock node. */
1706 route_unlock_node (rn);
1707
1708 /* let's go */
1709 for (rib = rn->info; rib; rib = rib->next)
1710 {
1711 zlog_debug
1712 (
1713 "%s: rn %p, rib %p: %s, %s",
1714 __func__,
1715 rn,
1716 rib,
1717 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
1718 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
1719 );
1720 rib_dump (__func__, p, rib);
1721 }
1722}
1723
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001724/* Check if requested address assignment will fail due to another
1725 * route being installed by zebra in FIB already. Take necessary
1726 * actions, if needed: remove such a route from FIB and deSELECT
1727 * corresponding RIB entry. Then put affected RN into RIBQ head.
1728 */
1729void rib_lookup_and_pushup (struct prefix_ipv4 * p)
1730{
1731 struct route_table *table;
1732 struct route_node *rn;
1733 struct rib *rib;
1734 unsigned changed = 0;
1735
1736 if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
1737 {
1738 zlog_err ("%s: vrf_table() returned NULL", __func__);
1739 return;
1740 }
1741
1742 /* No matches would be the simplest case. */
1743 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
1744 return;
1745
1746 /* Unlock node. */
1747 route_unlock_node (rn);
1748
1749 /* Check all RIB entries. In case any changes have to be done, requeue
1750 * the RN into RIBQ head. If the routing message about the new connected
1751 * route (generated by the IP address we are going to assign very soon)
1752 * comes before the RIBQ is processed, the new RIB entry will join
1753 * RIBQ record already on head. This is necessary for proper revalidation
1754 * of the rest of the RIB.
1755 */
1756 for (rib = rn->info; rib; rib = rib->next)
1757 {
1758 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
1759 ! RIB_SYSTEM_ROUTE (rib))
1760 {
1761 changed = 1;
1762 if (IS_ZEBRA_DEBUG_RIB)
1763 {
1764 char buf[INET_ADDRSTRLEN];
1765 inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
1766 zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
1767 rib_dump (__func__, (struct prefix_ipv4 *)&rn->p, rib);
1768 }
1769 rib_uninstall (rn, rib);
1770 }
1771 }
1772 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001773 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001774}
1775
paul718e3742002-12-13 20:15:29 +00001776int
1777rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib)
1778{
1779 struct route_table *table;
1780 struct route_node *rn;
1781 struct rib *same;
1782 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00001783
paul718e3742002-12-13 20:15:29 +00001784 /* Lookup table. */
1785 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1786 if (! table)
1787 return 0;
paul718e3742002-12-13 20:15:29 +00001788 /* Make it sure prefixlen is applied to the prefix. */
1789 apply_mask_ipv4 (p);
1790
1791 /* Set default distance by route type. */
1792 if (rib->distance == 0)
1793 {
1794 rib->distance = route_info[rib->type].distance;
1795
1796 /* iBGP distance is 200. */
1797 if (rib->type == ZEBRA_ROUTE_BGP
1798 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1799 rib->distance = 200;
1800 }
1801
1802 /* Lookup route node.*/
1803 rn = route_node_get (table, (struct prefix *) p);
1804
1805 /* If same type of route are installed, treat it as a implicit
1806 withdraw. */
1807 for (same = rn->info; same; same = same->next)
1808 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00001809 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00001810 continue;
1811
paul718e3742002-12-13 20:15:29 +00001812 if (same->type == rib->type && same->table == rib->table
1813 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001814 break;
paul718e3742002-12-13 20:15:29 +00001815 }
paul4d38fdb2005-04-28 17:35:14 +00001816
paul718e3742002-12-13 20:15:29 +00001817 /* If this route is kernel route, set FIB flag to the route. */
1818 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
1819 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1820 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1821
1822 /* Link new rib to node.*/
1823 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001824 if (IS_ZEBRA_DEBUG_RIB)
1825 {
1826 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
1827 __func__, rn, rib);
1828 rib_dump (__func__, p, rib);
1829 }
paul718e3742002-12-13 20:15:29 +00001830
paul718e3742002-12-13 20:15:29 +00001831 /* Free implicit route.*/
1832 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001833 {
1834 if (IS_ZEBRA_DEBUG_RIB)
1835 {
1836 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
1837 __func__, rn, same);
1838 rib_dump (__func__, p, same);
1839 }
paul4d38fdb2005-04-28 17:35:14 +00001840 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001841 }
paul4d38fdb2005-04-28 17:35:14 +00001842
1843 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001844 return 0;
1845}
1846
hassoebf1ead2005-09-21 14:58:20 +00001847/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00001848int
1849rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
1850 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1851{
1852 struct route_table *table;
1853 struct route_node *rn;
1854 struct rib *rib;
1855 struct rib *fib = NULL;
1856 struct rib *same = NULL;
1857 struct nexthop *nexthop;
Stephen Hemminger81cce012009-04-28 14:28:00 -07001858 char buf1[INET_ADDRSTRLEN];
1859 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00001860
1861 /* Lookup table. */
1862 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1863 if (! table)
1864 return 0;
1865
1866 /* Apply mask. */
1867 apply_mask_ipv4 (p);
1868
paul5ec90d22003-06-19 01:41:37 +00001869 if (IS_ZEBRA_DEBUG_KERNEL && gate)
ajsb6178002004-12-07 21:12:56 +00001870 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001871 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul5ec90d22003-06-19 01:41:37 +00001872 p->prefixlen,
1873 inet_ntoa (*gate),
1874 ifindex);
1875
paul718e3742002-12-13 20:15:29 +00001876 /* Lookup route node. */
1877 rn = route_node_lookup (table, (struct prefix *) p);
1878 if (! rn)
1879 {
1880 if (IS_ZEBRA_DEBUG_KERNEL)
1881 {
1882 if (gate)
ajsb6178002004-12-07 21:12:56 +00001883 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001884 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001885 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07001886 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001887 ifindex);
1888 else
ajsb6178002004-12-07 21:12:56 +00001889 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001890 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001891 p->prefixlen,
1892 ifindex);
1893 }
1894 return ZEBRA_ERR_RTNOEXIST;
1895 }
1896
1897 /* Lookup same type route. */
1898 for (rib = rn->info; rib; rib = rib->next)
1899 {
Paul Jakma6d691122006-07-27 21:49:00 +00001900 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1901 continue;
1902
paul718e3742002-12-13 20:15:29 +00001903 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1904 fib = rib;
1905
hassoebf1ead2005-09-21 14:58:20 +00001906 if (rib->type != type)
1907 continue;
1908 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
1909 nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex)
paul718e3742002-12-13 20:15:29 +00001910 {
hassoebf1ead2005-09-21 14:58:20 +00001911 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00001912 {
hassoebf1ead2005-09-21 14:58:20 +00001913 rib->refcnt--;
1914 route_unlock_node (rn);
1915 route_unlock_node (rn);
1916 return 0;
paul718e3742002-12-13 20:15:29 +00001917 }
hassoebf1ead2005-09-21 14:58:20 +00001918 same = rib;
1919 break;
paul718e3742002-12-13 20:15:29 +00001920 }
hassoebf1ead2005-09-21 14:58:20 +00001921 /* Make sure that the route found has the same gateway. */
1922 else if (gate == NULL ||
1923 ((nexthop = rib->nexthop) &&
1924 (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
1925 IPV4_ADDR_SAME (&nexthop->rgate.ipv4, gate))))
paul5ec90d22003-06-19 01:41:37 +00001926 {
hassoebf1ead2005-09-21 14:58:20 +00001927 same = rib;
1928 break;
paul718e3742002-12-13 20:15:29 +00001929 }
1930 }
1931
1932 /* If same type of route can't be found and this message is from
1933 kernel. */
1934 if (! same)
1935 {
1936 if (fib && type == ZEBRA_ROUTE_KERNEL)
1937 {
1938 /* Unset flags. */
1939 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1940 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1941
1942 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1943 }
1944 else
1945 {
1946 if (IS_ZEBRA_DEBUG_KERNEL)
1947 {
1948 if (gate)
ajsb6178002004-12-07 21:12:56 +00001949 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001950 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001951 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07001952 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001953 ifindex,
1954 type);
1955 else
ajsb6178002004-12-07 21:12:56 +00001956 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001957 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001958 p->prefixlen,
1959 ifindex,
1960 type);
1961 }
1962 route_unlock_node (rn);
1963 return ZEBRA_ERR_RTNOEXIST;
1964 }
1965 }
paul4d38fdb2005-04-28 17:35:14 +00001966
paul718e3742002-12-13 20:15:29 +00001967 if (same)
1968 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00001969
paul718e3742002-12-13 20:15:29 +00001970 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001971 return 0;
1972}
1973
1974/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00001975static void
paul718e3742002-12-13 20:15:29 +00001976static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
1977{
1978 struct rib *rib;
1979 struct route_node *rn;
1980 struct route_table *table;
1981
1982 /* Lookup table. */
1983 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1984 if (! table)
1985 return;
1986
1987 /* Lookup existing route */
1988 rn = route_node_get (table, p);
1989 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00001990 {
1991 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1992 continue;
1993
1994 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1995 break;
1996 }
paul718e3742002-12-13 20:15:29 +00001997
1998 if (rib)
1999 {
2000 /* Same distance static route is there. Update it with new
2001 nexthop. */
paul718e3742002-12-13 20:15:29 +00002002 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002003 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002004 {
2005 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002006 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002007 break;
2008 case STATIC_IPV4_IFNAME:
2009 nexthop_ifname_add (rib, si->gate.ifname);
2010 break;
2011 case STATIC_IPV4_BLACKHOLE:
2012 nexthop_blackhole_add (rib);
2013 break;
paul4d38fdb2005-04-28 17:35:14 +00002014 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002015 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002016 }
2017 else
2018 {
2019 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002020 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2021
paul718e3742002-12-13 20:15:29 +00002022 rib->type = ZEBRA_ROUTE_STATIC;
2023 rib->distance = si->distance;
2024 rib->metric = 0;
2025 rib->nexthop_num = 0;
2026
2027 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002028 {
2029 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002030 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002031 break;
2032 case STATIC_IPV4_IFNAME:
2033 nexthop_ifname_add (rib, si->gate.ifname);
2034 break;
2035 case STATIC_IPV4_BLACKHOLE:
2036 nexthop_blackhole_add (rib);
2037 break;
2038 }
paul718e3742002-12-13 20:15:29 +00002039
hasso81dfcaa2003-05-25 19:21:25 +00002040 /* Save the flags of this static routes (reject, blackhole) */
2041 rib->flags = si->flags;
2042
paul718e3742002-12-13 20:15:29 +00002043 /* Link this rib to the tree. */
2044 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002045 }
2046}
2047
paula1ac18c2005-06-28 17:17:12 +00002048static int
paul718e3742002-12-13 20:15:29 +00002049static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2050{
2051 if (nexthop->type == NEXTHOP_TYPE_IPV4
2052 && si->type == STATIC_IPV4_GATEWAY
2053 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2054 return 1;
2055 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2056 && si->type == STATIC_IPV4_IFNAME
2057 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2058 return 1;
paul595db7f2003-05-25 21:35:06 +00002059 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2060 && si->type == STATIC_IPV4_BLACKHOLE)
2061 return 1;
paule8e19462006-01-19 20:16:55 +00002062 return 0;
paul718e3742002-12-13 20:15:29 +00002063}
2064
2065/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002066static void
paul718e3742002-12-13 20:15:29 +00002067static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
2068{
2069 struct route_node *rn;
2070 struct rib *rib;
2071 struct nexthop *nexthop;
2072 struct route_table *table;
2073
2074 /* Lookup table. */
2075 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2076 if (! table)
2077 return;
paul4d38fdb2005-04-28 17:35:14 +00002078
paul718e3742002-12-13 20:15:29 +00002079 /* Lookup existing route with type and distance. */
2080 rn = route_node_lookup (table, p);
2081 if (! rn)
2082 return;
2083
2084 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002085 {
2086 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2087 continue;
2088
2089 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2090 break;
2091 }
paul718e3742002-12-13 20:15:29 +00002092
2093 if (! rib)
2094 {
2095 route_unlock_node (rn);
2096 return;
2097 }
2098
2099 /* Lookup nexthop. */
2100 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2101 if (static_ipv4_nexthop_same (nexthop, si))
2102 break;
2103
2104 /* Can't find nexthop. */
2105 if (! nexthop)
2106 {
2107 route_unlock_node (rn);
2108 return;
2109 }
2110
2111 /* Check nexthop. */
2112 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002113 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002114 else
2115 {
paul6baeb982003-10-28 03:47:15 +00002116 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2117 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002118 nexthop_delete (rib, nexthop);
2119 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002120 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002121 }
paul718e3742002-12-13 20:15:29 +00002122 /* Unlock node. */
2123 route_unlock_node (rn);
2124}
2125
2126/* Add static route into static route configuration. */
2127int
hasso39db97e2004-10-12 20:50:58 +00002128static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00002129 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002130{
2131 u_char type = 0;
2132 struct route_node *rn;
2133 struct static_ipv4 *si;
2134 struct static_ipv4 *pp;
2135 struct static_ipv4 *cp;
2136 struct static_ipv4 *update = NULL;
2137 struct route_table *stable;
2138
2139 /* Lookup table. */
2140 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2141 if (! stable)
2142 return -1;
2143
2144 /* Lookup static route prefix. */
2145 rn = route_node_get (stable, p);
2146
2147 /* Make flags. */
2148 if (gate)
2149 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002150 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002151 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002152 else
2153 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002154
2155 /* Do nothing if there is a same static route. */
2156 for (si = rn->info; si; si = si->next)
2157 {
2158 if (type == si->type
2159 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2160 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2161 {
2162 if (distance == si->distance)
2163 {
2164 route_unlock_node (rn);
2165 return 0;
2166 }
2167 else
2168 update = si;
2169 }
2170 }
2171
Paul Jakma3c0755d2006-12-08 00:53:14 +00002172 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002173 if (update)
2174 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
2175
2176 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002177 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
paul718e3742002-12-13 20:15:29 +00002178
2179 si->type = type;
2180 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002181 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002182
2183 if (gate)
2184 si->gate.ipv4 = *gate;
2185 if (ifname)
2186 si->gate.ifname = XSTRDUP (0, ifname);
2187
2188 /* Add new static route information to the tree with sort by
2189 distance value and gateway address. */
2190 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2191 {
2192 if (si->distance < cp->distance)
2193 break;
2194 if (si->distance > cp->distance)
2195 continue;
2196 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2197 {
2198 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2199 break;
2200 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2201 continue;
2202 }
2203 }
2204
2205 /* Make linked list. */
2206 if (pp)
2207 pp->next = si;
2208 else
2209 rn->info = si;
2210 if (cp)
2211 cp->prev = si;
2212 si->prev = pp;
2213 si->next = cp;
2214
2215 /* Install into rib. */
2216 static_install_ipv4 (p, si);
2217
2218 return 1;
2219}
2220
2221/* Delete static route from static route configuration. */
2222int
hasso39db97e2004-10-12 20:50:58 +00002223static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00002224 u_char distance, u_int32_t vrf_id)
2225{
2226 u_char type = 0;
2227 struct route_node *rn;
2228 struct static_ipv4 *si;
2229 struct route_table *stable;
2230
2231 /* Lookup table. */
2232 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2233 if (! stable)
2234 return -1;
2235
2236 /* Lookup static route prefix. */
2237 rn = route_node_lookup (stable, p);
2238 if (! rn)
2239 return 0;
2240
2241 /* Make flags. */
2242 if (gate)
2243 type = STATIC_IPV4_GATEWAY;
2244 else if (ifname)
2245 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002246 else
2247 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002248
2249 /* Find same static route is the tree */
2250 for (si = rn->info; si; si = si->next)
2251 if (type == si->type
2252 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2253 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2254 break;
2255
2256 /* Can't find static route. */
2257 if (! si)
2258 {
2259 route_unlock_node (rn);
2260 return 0;
2261 }
2262
2263 /* Install into rib. */
2264 static_uninstall_ipv4 (p, si);
2265
2266 /* Unlink static route from linked list. */
2267 if (si->prev)
2268 si->prev->next = si->next;
2269 else
2270 rn->info = si->next;
2271 if (si->next)
2272 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002273 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002274
2275 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002276 if (ifname)
2277 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002278 XFREE (MTYPE_STATIC_IPV4, si);
2279
paul143a3852003-09-29 20:06:13 +00002280 route_unlock_node (rn);
2281
paul718e3742002-12-13 20:15:29 +00002282 return 1;
2283}
2284
2285
2286#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00002287static int
paul718e3742002-12-13 20:15:29 +00002288rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2289 struct in6_addr *gate, unsigned int ifindex, int table)
2290{
hasso726f9b22003-05-25 21:04:54 +00002291 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2292#if defined (MUSICA) || defined (LINUX)
2293 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2294 if (p->prefixlen == 96)
2295 return 0;
2296#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00002297 return 1;
hasso726f9b22003-05-25 21:04:54 +00002298 }
paul718e3742002-12-13 20:15:29 +00002299 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
2300 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
2301 {
2302 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
2303 return 1;
2304 }
2305 return 0;
2306}
2307
2308int
2309rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00002310 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
2311 u_int32_t metric, u_char distance)
paul718e3742002-12-13 20:15:29 +00002312{
2313 struct rib *rib;
2314 struct rib *same = NULL;
2315 struct route_table *table;
2316 struct route_node *rn;
2317 struct nexthop *nexthop;
2318
paul718e3742002-12-13 20:15:29 +00002319 /* Lookup table. */
2320 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2321 if (! table)
2322 return 0;
2323
2324 /* Make sure mask is applied. */
2325 apply_mask_ipv6 (p);
2326
2327 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002328 if (!distance)
2329 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002330
2331 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2332 distance = 200;
2333
2334 /* Filter bogus route. */
2335 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
2336 return 0;
2337
2338 /* Lookup route node.*/
2339 rn = route_node_get (table, (struct prefix *) p);
2340
2341 /* If same type of route are installed, treat it as a implicit
2342 withdraw. */
2343 for (rib = rn->info; rib; rib = rib->next)
2344 {
Paul Jakma6d691122006-07-27 21:49:00 +00002345 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2346 continue;
2347
hassoebf1ead2005-09-21 14:58:20 +00002348 if (rib->type != type)
2349 continue;
2350 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002351 {
2352 same = rib;
paul718e3742002-12-13 20:15:29 +00002353 break;
2354 }
hassoebf1ead2005-09-21 14:58:20 +00002355 else if ((nexthop = rib->nexthop) &&
2356 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2357 nexthop->ifindex == ifindex)
2358 {
2359 rib->refcnt++;
2360 return 0;
2361 }
paul718e3742002-12-13 20:15:29 +00002362 }
2363
2364 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002365 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2366
paul718e3742002-12-13 20:15:29 +00002367 rib->type = type;
2368 rib->distance = distance;
2369 rib->flags = flags;
2370 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00002371 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00002372 rib->nexthop_num = 0;
2373 rib->uptime = time (NULL);
2374
2375 /* Nexthop settings. */
2376 if (gate)
2377 {
2378 if (ifindex)
2379 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2380 else
2381 nexthop_ipv6_add (rib, gate);
2382 }
2383 else
2384 nexthop_ifindex_add (rib, ifindex);
2385
2386 /* If this route is kernel route, set FIB flag to the route. */
2387 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2388 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2389 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2390
2391 /* Link new rib to node.*/
2392 rib_addnode (rn, rib);
2393
paul718e3742002-12-13 20:15:29 +00002394 /* Free implicit route.*/
2395 if (same)
paul4d38fdb2005-04-28 17:35:14 +00002396 rib_delnode (rn, same);
2397
2398 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002399 return 0;
2400}
2401
hassoebf1ead2005-09-21 14:58:20 +00002402/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002403int
2404rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
2405 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
2406{
2407 struct route_table *table;
2408 struct route_node *rn;
2409 struct rib *rib;
2410 struct rib *fib = NULL;
2411 struct rib *same = NULL;
2412 struct nexthop *nexthop;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002413 char buf1[INET6_ADDRSTRLEN];
2414 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002415
2416 /* Apply mask. */
2417 apply_mask_ipv6 (p);
2418
2419 /* Lookup table. */
2420 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2421 if (! table)
2422 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002423
paul718e3742002-12-13 20:15:29 +00002424 /* Lookup route node. */
2425 rn = route_node_lookup (table, (struct prefix *) p);
2426 if (! rn)
2427 {
2428 if (IS_ZEBRA_DEBUG_KERNEL)
2429 {
2430 if (gate)
ajsb6178002004-12-07 21:12:56 +00002431 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002432 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002433 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002434 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002435 ifindex);
2436 else
ajsb6178002004-12-07 21:12:56 +00002437 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002438 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002439 p->prefixlen,
2440 ifindex);
2441 }
2442 return ZEBRA_ERR_RTNOEXIST;
2443 }
2444
2445 /* Lookup same type route. */
2446 for (rib = rn->info; rib; rib = rib->next)
2447 {
Paul Jakma6d691122006-07-27 21:49:00 +00002448 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2449 continue;
2450
paul718e3742002-12-13 20:15:29 +00002451 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2452 fib = rib;
2453
hassoebf1ead2005-09-21 14:58:20 +00002454 if (rib->type != type)
2455 continue;
2456 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
2457 nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex)
paul718e3742002-12-13 20:15:29 +00002458 {
hassoebf1ead2005-09-21 14:58:20 +00002459 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002460 {
hassoebf1ead2005-09-21 14:58:20 +00002461 rib->refcnt--;
2462 route_unlock_node (rn);
2463 route_unlock_node (rn);
2464 return 0;
paul718e3742002-12-13 20:15:29 +00002465 }
hassoebf1ead2005-09-21 14:58:20 +00002466 same = rib;
2467 break;
paul718e3742002-12-13 20:15:29 +00002468 }
hassoebf1ead2005-09-21 14:58:20 +00002469 /* Make sure that the route found has the same gateway. */
2470 else if (gate == NULL ||
2471 ((nexthop = rib->nexthop) &&
2472 (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate) ||
2473 IPV6_ADDR_SAME (&nexthop->rgate.ipv6, gate))))
paul718e3742002-12-13 20:15:29 +00002474 {
hassoebf1ead2005-09-21 14:58:20 +00002475 same = rib;
2476 break;
paul718e3742002-12-13 20:15:29 +00002477 }
2478 }
2479
2480 /* If same type of route can't be found and this message is from
2481 kernel. */
2482 if (! same)
2483 {
2484 if (fib && type == ZEBRA_ROUTE_KERNEL)
2485 {
2486 /* Unset flags. */
2487 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2488 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2489
2490 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2491 }
2492 else
2493 {
2494 if (IS_ZEBRA_DEBUG_KERNEL)
2495 {
2496 if (gate)
ajsb6178002004-12-07 21:12:56 +00002497 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002498 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002499 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002500 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002501 ifindex,
2502 type);
2503 else
ajsb6178002004-12-07 21:12:56 +00002504 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002505 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002506 p->prefixlen,
2507 ifindex,
2508 type);
2509 }
2510 route_unlock_node (rn);
2511 return ZEBRA_ERR_RTNOEXIST;
2512 }
2513 }
2514
2515 if (same)
2516 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002517
paul718e3742002-12-13 20:15:29 +00002518 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002519 return 0;
2520}
2521
2522/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002523static void
paul718e3742002-12-13 20:15:29 +00002524static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2525{
2526 struct rib *rib;
2527 struct route_table *table;
2528 struct route_node *rn;
2529
2530 /* Lookup table. */
2531 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2532 if (! table)
2533 return;
2534
2535 /* Lookup existing route */
2536 rn = route_node_get (table, p);
2537 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002538 {
2539 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2540 continue;
2541
2542 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2543 break;
2544 }
paul718e3742002-12-13 20:15:29 +00002545
2546 if (rib)
2547 {
2548 /* Same distance static route is there. Update it with new
2549 nexthop. */
paul718e3742002-12-13 20:15:29 +00002550 route_unlock_node (rn);
2551
2552 switch (si->type)
2553 {
2554 case STATIC_IPV6_GATEWAY:
2555 nexthop_ipv6_add (rib, &si->ipv6);
2556 break;
2557 case STATIC_IPV6_IFNAME:
2558 nexthop_ifname_add (rib, si->ifname);
2559 break;
2560 case STATIC_IPV6_GATEWAY_IFNAME:
2561 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2562 break;
2563 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002564 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002565 }
2566 else
2567 {
2568 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002569 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2570
paul718e3742002-12-13 20:15:29 +00002571 rib->type = ZEBRA_ROUTE_STATIC;
2572 rib->distance = si->distance;
2573 rib->metric = 0;
2574 rib->nexthop_num = 0;
2575
2576 switch (si->type)
2577 {
2578 case STATIC_IPV6_GATEWAY:
2579 nexthop_ipv6_add (rib, &si->ipv6);
2580 break;
2581 case STATIC_IPV6_IFNAME:
2582 nexthop_ifname_add (rib, si->ifname);
2583 break;
2584 case STATIC_IPV6_GATEWAY_IFNAME:
2585 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2586 break;
2587 }
2588
hasso81dfcaa2003-05-25 19:21:25 +00002589 /* Save the flags of this static routes (reject, blackhole) */
2590 rib->flags = si->flags;
2591
paul718e3742002-12-13 20:15:29 +00002592 /* Link this rib to the tree. */
2593 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002594 }
2595}
2596
paula1ac18c2005-06-28 17:17:12 +00002597static int
paul718e3742002-12-13 20:15:29 +00002598static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2599{
2600 if (nexthop->type == NEXTHOP_TYPE_IPV6
2601 && si->type == STATIC_IPV6_GATEWAY
2602 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2603 return 1;
2604 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2605 && si->type == STATIC_IPV6_IFNAME
2606 && strcmp (nexthop->ifname, si->ifname) == 0)
2607 return 1;
2608 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2609 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2610 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2611 && strcmp (nexthop->ifname, si->ifname) == 0)
2612 return 1;
paule8e19462006-01-19 20:16:55 +00002613 return 0;
paul718e3742002-12-13 20:15:29 +00002614}
2615
paula1ac18c2005-06-28 17:17:12 +00002616static void
paul718e3742002-12-13 20:15:29 +00002617static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2618{
2619 struct route_table *table;
2620 struct route_node *rn;
2621 struct rib *rib;
2622 struct nexthop *nexthop;
2623
2624 /* Lookup table. */
2625 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2626 if (! table)
2627 return;
2628
2629 /* Lookup existing route with type and distance. */
2630 rn = route_node_lookup (table, (struct prefix *) p);
2631 if (! rn)
2632 return;
2633
2634 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002635 {
2636 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2637 continue;
2638
2639 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2640 break;
2641 }
2642
paul718e3742002-12-13 20:15:29 +00002643 if (! rib)
2644 {
2645 route_unlock_node (rn);
2646 return;
2647 }
2648
2649 /* Lookup nexthop. */
2650 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2651 if (static_ipv6_nexthop_same (nexthop, si))
2652 break;
2653
2654 /* Can't find nexthop. */
2655 if (! nexthop)
2656 {
2657 route_unlock_node (rn);
2658 return;
2659 }
2660
2661 /* Check nexthop. */
2662 if (rib->nexthop_num == 1)
2663 {
2664 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002665 }
2666 else
2667 {
paul6baeb982003-10-28 03:47:15 +00002668 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2669 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002670 nexthop_delete (rib, nexthop);
2671 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002672 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002673 }
paul718e3742002-12-13 20:15:29 +00002674 /* Unlock node. */
2675 route_unlock_node (rn);
2676}
2677
2678/* Add static route into static route configuration. */
2679int
2680static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002681 const char *ifname, u_char flags, u_char distance,
2682 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002683{
2684 struct route_node *rn;
2685 struct static_ipv6 *si;
2686 struct static_ipv6 *pp;
2687 struct static_ipv6 *cp;
2688 struct route_table *stable;
2689
2690 /* Lookup table. */
2691 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2692 if (! stable)
2693 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00002694
2695 if (!gate &&
2696 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
2697 return -1;
2698
2699 if (!ifname &&
2700 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
2701 return -1;
paul718e3742002-12-13 20:15:29 +00002702
2703 /* Lookup static route prefix. */
2704 rn = route_node_get (stable, p);
2705
2706 /* Do nothing if there is a same static route. */
2707 for (si = rn->info; si; si = si->next)
2708 {
2709 if (distance == si->distance
2710 && type == si->type
2711 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2712 && (! ifname || strcmp (ifname, si->ifname) == 0))
2713 {
2714 route_unlock_node (rn);
2715 return 0;
2716 }
2717 }
2718
2719 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002720 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
paul718e3742002-12-13 20:15:29 +00002721
2722 si->type = type;
2723 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002724 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002725
2726 switch (type)
2727 {
2728 case STATIC_IPV6_GATEWAY:
2729 si->ipv6 = *gate;
2730 break;
2731 case STATIC_IPV6_IFNAME:
2732 si->ifname = XSTRDUP (0, ifname);
2733 break;
2734 case STATIC_IPV6_GATEWAY_IFNAME:
2735 si->ipv6 = *gate;
2736 si->ifname = XSTRDUP (0, ifname);
2737 break;
2738 }
2739
2740 /* Add new static route information to the tree with sort by
2741 distance value and gateway address. */
2742 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2743 {
2744 if (si->distance < cp->distance)
2745 break;
2746 if (si->distance > cp->distance)
2747 continue;
2748 }
2749
2750 /* Make linked list. */
2751 if (pp)
2752 pp->next = si;
2753 else
2754 rn->info = si;
2755 if (cp)
2756 cp->prev = si;
2757 si->prev = pp;
2758 si->next = cp;
2759
2760 /* Install into rib. */
2761 static_install_ipv6 (p, si);
2762
2763 return 1;
2764}
2765
2766/* Delete static route from static route configuration. */
2767int
2768static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002769 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002770{
2771 struct route_node *rn;
2772 struct static_ipv6 *si;
2773 struct route_table *stable;
2774
2775 /* Lookup table. */
2776 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2777 if (! stable)
2778 return -1;
2779
2780 /* Lookup static route prefix. */
2781 rn = route_node_lookup (stable, p);
2782 if (! rn)
2783 return 0;
2784
2785 /* Find same static route is the tree */
2786 for (si = rn->info; si; si = si->next)
2787 if (distance == si->distance
2788 && type == si->type
2789 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2790 && (! ifname || strcmp (ifname, si->ifname) == 0))
2791 break;
2792
2793 /* Can't find static route. */
2794 if (! si)
2795 {
2796 route_unlock_node (rn);
2797 return 0;
2798 }
2799
2800 /* Install into rib. */
2801 static_uninstall_ipv6 (p, si);
2802
2803 /* Unlink static route from linked list. */
2804 if (si->prev)
2805 si->prev->next = si->next;
2806 else
2807 rn->info = si->next;
2808 if (si->next)
2809 si->next->prev = si->prev;
2810
2811 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002812 if (ifname)
2813 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00002814 XFREE (MTYPE_STATIC_IPV6, si);
2815
2816 return 1;
2817}
2818#endif /* HAVE_IPV6 */
2819
2820/* RIB update function. */
2821void
paula1ac18c2005-06-28 17:17:12 +00002822rib_update (void)
paul718e3742002-12-13 20:15:29 +00002823{
2824 struct route_node *rn;
2825 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00002826
paul718e3742002-12-13 20:15:29 +00002827 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2828 if (table)
2829 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002830 if (rn->info)
Paul Jakma6d691122006-07-27 21:49:00 +00002831 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002832
2833 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2834 if (table)
2835 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002836 if (rn->info)
Paul Jakma6d691122006-07-27 21:49:00 +00002837 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002838}
2839
paul718e3742002-12-13 20:15:29 +00002840
2841/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00002842static void
paul718e3742002-12-13 20:15:29 +00002843rib_weed_table (struct route_table *table)
2844{
2845 struct route_node *rn;
2846 struct rib *rib;
2847 struct rib *next;
2848
2849 if (table)
2850 for (rn = route_top (table); rn; rn = route_next (rn))
2851 for (rib = rn->info; rib; rib = next)
2852 {
2853 next = rib->next;
2854
Paul Jakma6d691122006-07-27 21:49:00 +00002855 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2856 continue;
2857
paulb21b19c2003-06-15 01:28:29 +00002858 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00002859 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00002860 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002861 }
2862}
2863
2864/* Delete all routes from non main table. */
2865void
paula1ac18c2005-06-28 17:17:12 +00002866rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00002867{
2868 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2869 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2870}
2871
2872/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00002873static void
paul718e3742002-12-13 20:15:29 +00002874rib_sweep_table (struct route_table *table)
2875{
2876 struct route_node *rn;
2877 struct rib *rib;
2878 struct rib *next;
2879 int ret = 0;
2880
2881 if (table)
2882 for (rn = route_top (table); rn; rn = route_next (rn))
2883 for (rib = rn->info; rib; rib = next)
2884 {
2885 next = rib->next;
2886
Paul Jakma6d691122006-07-27 21:49:00 +00002887 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2888 continue;
2889
paul718e3742002-12-13 20:15:29 +00002890 if (rib->type == ZEBRA_ROUTE_KERNEL &&
2891 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
2892 {
2893 ret = rib_uninstall_kernel (rn, rib);
2894 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00002895 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002896 }
2897 }
2898}
2899
2900/* Sweep all RIB tables. */
2901void
paula1ac18c2005-06-28 17:17:12 +00002902rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00002903{
2904 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2905 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2906}
2907
Josh Baileyaf56d402012-03-21 18:47:51 -07002908/* Delete routes learned from a given client. */
2909/* TODO(wsun) May need to split the sweep process into multiple batches,
2910 * so that the process won't take too long if the table is large. */
2911static void
2912rib_sweep_client_table (struct route_table *table, int rib_type)
2913{
2914 struct route_node *rn;
2915 struct rib *rib;
2916 struct rib *next;
2917 int ret = 0;
2918
2919 if (table)
2920 for (rn = route_top (table); rn; rn = route_next (rn))
2921 for (rib = rn->info; rib; rib = next)
2922 {
2923 next = rib->next;
2924
2925 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2926 continue;
2927
2928 if (rib->type == rib_type)
2929 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2930 {
2931 /* TODO(wsun) Is this mandatory? What about graceful restart/
2932 * non-stop forwarding */
2933 ret = rib_uninstall_kernel (rn, rib);
2934 if (! ret)
2935 rib_delnode (rn, rib);
2936 else
2937 zlog_err ("%s: could not delete routes from kernel!",
2938 __func__);
2939 }
2940 else
2941 {
2942 /* Always delete the node. */
2943 rib_delnode (rn, rib);
2944 }
2945 }
2946}
2947
2948/* Sweep all routes learned from a given client from RIB tables. */
2949void
2950rib_sweep_client_route (struct zserv *client)
2951{
2952 assert(client);
2953 int route_type = client->route_type;
2954 if (route_type != ZEBRA_ROUTE_MAX)
2955 {
2956 zlog_debug ("%s: Removing existing routes from client type %d",
2957 __func__, route_type);
2958 rib_sweep_client_table (vrf_table (AFI_IP, SAFI_UNICAST, 0), route_type);
2959 rib_sweep_client_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0), route_type);
2960 }
2961}
2962
paul718e3742002-12-13 20:15:29 +00002963/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00002964static void
paul718e3742002-12-13 20:15:29 +00002965rib_close_table (struct route_table *table)
2966{
2967 struct route_node *rn;
2968 struct rib *rib;
2969
2970 if (table)
2971 for (rn = route_top (table); rn; rn = route_next (rn))
2972 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002973 {
2974 if (! RIB_SYSTEM_ROUTE (rib)
2975 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2976 rib_uninstall_kernel (rn, rib);
2977 }
paul718e3742002-12-13 20:15:29 +00002978}
2979
2980/* Close all RIB tables. */
2981void
paula1ac18c2005-06-28 17:17:12 +00002982rib_close (void)
paul718e3742002-12-13 20:15:29 +00002983{
2984 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2985 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2986}
2987
2988/* Routing information base initialize. */
2989void
paula1ac18c2005-06-28 17:17:12 +00002990rib_init (void)
paul718e3742002-12-13 20:15:29 +00002991{
paul4d38fdb2005-04-28 17:35:14 +00002992 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00002993 /* VRF initialization. */
2994 vrf_init ();
2995}