blob: d239501d33ef6b6c6a286053dec9f2a124d1dd22 [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. */}
David Lamparter7052f222009-08-27 00:28:28 +020070 /* no entry/default: 150 */
paul718e3742002-12-13 20:15:29 +000071};
72
73/* Vector for routing table. */
Stephen Hemmingerd145bc02008-08-17 17:41:37 +010074static vector vrf_vector;
paul718e3742002-12-13 20:15:29 +000075
76/* Allocate new VRF. */
paula1ac18c2005-06-28 17:17:12 +000077static struct vrf *
hassofce954f2004-10-07 20:29:24 +000078vrf_alloc (const char *name)
paul718e3742002-12-13 20:15:29 +000079{
80 struct vrf *vrf;
81
82 vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
83
84 /* Put name. */
85 if (name)
86 vrf->name = XSTRDUP (MTYPE_VRF_NAME, name);
87
88 /* Allocate routing table and static table. */
89 vrf->table[AFI_IP][SAFI_UNICAST] = route_table_init ();
90 vrf->table[AFI_IP6][SAFI_UNICAST] = route_table_init ();
91 vrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
92 vrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
93
94 return vrf;
95}
96
paul718e3742002-12-13 20:15:29 +000097/* Lookup VRF by identifier. */
98struct vrf *
99vrf_lookup (u_int32_t id)
100{
101 return vector_lookup (vrf_vector, id);
102}
103
paul718e3742002-12-13 20:15:29 +0000104/* Initialize VRF. */
paula1ac18c2005-06-28 17:17:12 +0000105static void
106vrf_init (void)
paul718e3742002-12-13 20:15:29 +0000107{
108 struct vrf *default_table;
109
110 /* Allocate VRF vector. */
111 vrf_vector = vector_init (1);
112
113 /* Allocate default main table. */
114 default_table = vrf_alloc ("Default-IP-Routing-Table");
115
116 /* Default table index must be 0. */
117 vector_set_index (vrf_vector, 0, default_table);
118}
119
120/* Lookup route table. */
121struct route_table *
122vrf_table (afi_t afi, safi_t safi, u_int32_t id)
123{
124 struct vrf *vrf;
125
126 vrf = vrf_lookup (id);
127 if (! vrf)
128 return NULL;
129
130 return vrf->table[afi][safi];
131}
132
133/* Lookup static route table. */
134struct route_table *
135vrf_static_table (afi_t afi, safi_t safi, u_int32_t id)
136{
137 struct vrf *vrf;
138
139 vrf = vrf_lookup (id);
140 if (! vrf)
141 return NULL;
142
143 return vrf->stable[afi][safi];
144}
145
146/* Add nexthop to the end of the list. */
paula1ac18c2005-06-28 17:17:12 +0000147static void
paul718e3742002-12-13 20:15:29 +0000148nexthop_add (struct rib *rib, struct nexthop *nexthop)
149{
150 struct nexthop *last;
151
152 for (last = rib->nexthop; last && last->next; last = last->next)
153 ;
154 if (last)
155 last->next = nexthop;
156 else
157 rib->nexthop = nexthop;
158 nexthop->prev = last;
159
160 rib->nexthop_num++;
161}
162
163/* Delete specified nexthop from the list. */
paula1ac18c2005-06-28 17:17:12 +0000164static void
paul718e3742002-12-13 20:15:29 +0000165nexthop_delete (struct rib *rib, struct nexthop *nexthop)
166{
167 if (nexthop->next)
168 nexthop->next->prev = nexthop->prev;
169 if (nexthop->prev)
170 nexthop->prev->next = nexthop->next;
171 else
172 rib->nexthop = nexthop->next;
173 rib->nexthop_num--;
174}
175
176/* Free nexthop. */
paula1ac18c2005-06-28 17:17:12 +0000177static void
paul718e3742002-12-13 20:15:29 +0000178nexthop_free (struct nexthop *nexthop)
179{
paula4b70762003-05-16 17:19:48 +0000180 if (nexthop->ifname)
181 XFREE (0, nexthop->ifname);
paul718e3742002-12-13 20:15:29 +0000182 XFREE (MTYPE_NEXTHOP, nexthop);
183}
184
185struct nexthop *
186nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
187{
188 struct nexthop *nexthop;
189
Stephen Hemminger393deb92008-08-18 14:13:29 -0700190 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000191 nexthop->type = NEXTHOP_TYPE_IFINDEX;
192 nexthop->ifindex = ifindex;
193
194 nexthop_add (rib, nexthop);
195
196 return nexthop;
197}
198
199struct nexthop *
200nexthop_ifname_add (struct rib *rib, char *ifname)
201{
202 struct nexthop *nexthop;
203
Stephen Hemminger393deb92008-08-18 14:13:29 -0700204 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000205 nexthop->type = NEXTHOP_TYPE_IFNAME;
paula4b70762003-05-16 17:19:48 +0000206 nexthop->ifname = XSTRDUP (0, ifname);
paul718e3742002-12-13 20:15:29 +0000207
208 nexthop_add (rib, nexthop);
209
210 return nexthop;
211}
212
213struct nexthop *
Paul Jakma7514fb72007-05-02 16:05:35 +0000214nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src)
paul718e3742002-12-13 20:15:29 +0000215{
216 struct nexthop *nexthop;
217
Stephen Hemminger393deb92008-08-18 14:13:29 -0700218 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000219 nexthop->type = NEXTHOP_TYPE_IPV4;
220 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000221 if (src)
222 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000223
224 nexthop_add (rib, nexthop);
225
226 return nexthop;
227}
228
paula1ac18c2005-06-28 17:17:12 +0000229static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000230nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
Paul Jakma7514fb72007-05-02 16:05:35 +0000231 struct in_addr *src, unsigned int ifindex)
paul718e3742002-12-13 20:15:29 +0000232{
233 struct nexthop *nexthop;
234
Stephen Hemminger393deb92008-08-18 14:13:29 -0700235 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000236 nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
237 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000238 if (src)
239 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000240 nexthop->ifindex = ifindex;
241
242 nexthop_add (rib, nexthop);
243
244 return nexthop;
245}
246
247#ifdef HAVE_IPV6
248struct nexthop *
249nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
250{
251 struct nexthop *nexthop;
252
Stephen Hemminger393deb92008-08-18 14:13:29 -0700253 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000254 nexthop->type = NEXTHOP_TYPE_IPV6;
255 nexthop->gate.ipv6 = *ipv6;
256
257 nexthop_add (rib, nexthop);
258
259 return nexthop;
260}
261
paula1ac18c2005-06-28 17:17:12 +0000262static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000263nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
264 char *ifname)
265{
266 struct nexthop *nexthop;
267
Stephen Hemminger393deb92008-08-18 14:13:29 -0700268 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000269 nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
270 nexthop->gate.ipv6 = *ipv6;
271 nexthop->ifname = XSTRDUP (0, ifname);
272
273 nexthop_add (rib, nexthop);
274
275 return nexthop;
276}
277
paula1ac18c2005-06-28 17:17:12 +0000278static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000279nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
280 unsigned int ifindex)
281{
282 struct nexthop *nexthop;
283
Stephen Hemminger393deb92008-08-18 14:13:29 -0700284 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000285 nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
286 nexthop->gate.ipv6 = *ipv6;
287 nexthop->ifindex = ifindex;
288
289 nexthop_add (rib, nexthop);
290
291 return nexthop;
292}
293#endif /* HAVE_IPV6 */
294
paul595db7f2003-05-25 21:35:06 +0000295struct nexthop *
296nexthop_blackhole_add (struct rib *rib)
297{
298 struct nexthop *nexthop;
299
Stephen Hemminger393deb92008-08-18 14:13:29 -0700300 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul595db7f2003-05-25 21:35:06 +0000301 nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
302 SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
303
304 nexthop_add (rib, nexthop);
305
306 return nexthop;
307}
308
paul718e3742002-12-13 20:15:29 +0000309/* If force flag is not set, do not modify falgs at all for uninstall
310 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000311static int
paul718e3742002-12-13 20:15:29 +0000312nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
313 struct route_node *top)
314{
315 struct prefix_ipv4 p;
316 struct route_table *table;
317 struct route_node *rn;
318 struct rib *match;
319 struct nexthop *newhop;
320
321 if (nexthop->type == NEXTHOP_TYPE_IPV4)
322 nexthop->ifindex = 0;
323
324 if (set)
325 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
326
327 /* Make lookup prefix. */
328 memset (&p, 0, sizeof (struct prefix_ipv4));
329 p.family = AF_INET;
330 p.prefixlen = IPV4_MAX_PREFIXLEN;
331 p.prefix = nexthop->gate.ipv4;
332
333 /* Lookup table. */
334 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
335 if (! table)
336 return 0;
337
338 rn = route_node_match (table, (struct prefix *) &p);
339 while (rn)
340 {
341 route_unlock_node (rn);
342
David Warda50c1072009-12-03 15:34:39 +0300343 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000344 if (rn == top)
345 return 0;
346
347 /* Pick up selected route. */
348 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100349 {
350 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
351 continue;
352 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
353 break;
354 }
paul718e3742002-12-13 20:15:29 +0000355
356 /* If there is no selected route or matched route is EGP, go up
357 tree. */
358 if (! match
359 || match->type == ZEBRA_ROUTE_BGP)
360 {
361 do {
362 rn = rn->parent;
363 } while (rn && rn->info == NULL);
364 if (rn)
365 route_lock_node (rn);
366 }
367 else
368 {
369 if (match->type == ZEBRA_ROUTE_CONNECT)
370 {
371 /* Directly point connected route. */
372 newhop = match->nexthop;
373 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
374 nexthop->ifindex = newhop->ifindex;
375
376 return 1;
377 }
378 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
379 {
380 for (newhop = match->nexthop; newhop; newhop = newhop->next)
381 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
382 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
383 {
384 if (set)
385 {
386 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
387 nexthop->rtype = newhop->type;
388 if (newhop->type == NEXTHOP_TYPE_IPV4 ||
389 newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
390 nexthop->rgate.ipv4 = newhop->gate.ipv4;
391 if (newhop->type == NEXTHOP_TYPE_IFINDEX
392 || newhop->type == NEXTHOP_TYPE_IFNAME
393 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
394 nexthop->rifindex = newhop->ifindex;
395 }
396 return 1;
397 }
398 return 0;
399 }
400 else
401 {
402 return 0;
403 }
404 }
405 }
406 return 0;
407}
408
409#ifdef HAVE_IPV6
410/* If force flag is not set, do not modify falgs at all for uninstall
411 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000412static int
paul718e3742002-12-13 20:15:29 +0000413nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
414 struct route_node *top)
415{
416 struct prefix_ipv6 p;
417 struct route_table *table;
418 struct route_node *rn;
419 struct rib *match;
420 struct nexthop *newhop;
421
422 if (nexthop->type == NEXTHOP_TYPE_IPV6)
423 nexthop->ifindex = 0;
424
425 if (set)
426 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
427
428 /* Make lookup prefix. */
429 memset (&p, 0, sizeof (struct prefix_ipv6));
430 p.family = AF_INET6;
431 p.prefixlen = IPV6_MAX_PREFIXLEN;
432 p.prefix = nexthop->gate.ipv6;
433
434 /* Lookup table. */
435 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
436 if (! table)
437 return 0;
438
439 rn = route_node_match (table, (struct prefix *) &p);
440 while (rn)
441 {
442 route_unlock_node (rn);
443
David Warda50c1072009-12-03 15:34:39 +0300444 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000445 if (rn == top)
446 return 0;
447
448 /* Pick up selected route. */
449 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100450 {
451 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
452 continue;
453 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
454 break;
455 }
paul718e3742002-12-13 20:15:29 +0000456
457 /* If there is no selected route or matched route is EGP, go up
458 tree. */
459 if (! match
460 || match->type == ZEBRA_ROUTE_BGP)
461 {
462 do {
463 rn = rn->parent;
464 } while (rn && rn->info == NULL);
465 if (rn)
466 route_lock_node (rn);
467 }
468 else
469 {
470 if (match->type == ZEBRA_ROUTE_CONNECT)
471 {
472 /* Directly point connected route. */
473 newhop = match->nexthop;
474
475 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
476 nexthop->ifindex = newhop->ifindex;
477
478 return 1;
479 }
480 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
481 {
482 for (newhop = match->nexthop; newhop; newhop = newhop->next)
483 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
484 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
485 {
486 if (set)
487 {
488 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
489 nexthop->rtype = newhop->type;
490 if (newhop->type == NEXTHOP_TYPE_IPV6
491 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
492 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
493 nexthop->rgate.ipv6 = newhop->gate.ipv6;
494 if (newhop->type == NEXTHOP_TYPE_IFINDEX
495 || newhop->type == NEXTHOP_TYPE_IFNAME
496 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
497 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
498 nexthop->rifindex = newhop->ifindex;
499 }
500 return 1;
501 }
502 return 0;
503 }
504 else
505 {
506 return 0;
507 }
508 }
509 }
510 return 0;
511}
512#endif /* HAVE_IPV6 */
513
514struct rib *
515rib_match_ipv4 (struct in_addr addr)
516{
517 struct prefix_ipv4 p;
518 struct route_table *table;
519 struct route_node *rn;
520 struct rib *match;
521 struct nexthop *newhop;
522
523 /* Lookup table. */
524 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
525 if (! table)
526 return 0;
527
528 memset (&p, 0, sizeof (struct prefix_ipv4));
529 p.family = AF_INET;
530 p.prefixlen = IPV4_MAX_PREFIXLEN;
531 p.prefix = addr;
532
533 rn = route_node_match (table, (struct prefix *) &p);
534
535 while (rn)
536 {
537 route_unlock_node (rn);
538
539 /* Pick up selected route. */
540 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100541 {
542 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
543 continue;
544 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
545 break;
546 }
paul718e3742002-12-13 20:15:29 +0000547
548 /* If there is no selected route or matched route is EGP, go up
549 tree. */
550 if (! match
551 || match->type == ZEBRA_ROUTE_BGP)
552 {
553 do {
554 rn = rn->parent;
555 } while (rn && rn->info == NULL);
556 if (rn)
557 route_lock_node (rn);
558 }
559 else
560 {
561 if (match->type == ZEBRA_ROUTE_CONNECT)
562 /* Directly point connected route. */
563 return match;
564 else
565 {
566 for (newhop = match->nexthop; newhop; newhop = newhop->next)
567 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
568 return match;
569 return NULL;
570 }
571 }
572 }
573 return NULL;
574}
575
576struct rib *
577rib_lookup_ipv4 (struct prefix_ipv4 *p)
578{
579 struct route_table *table;
580 struct route_node *rn;
581 struct rib *match;
582 struct nexthop *nexthop;
583
584 /* Lookup table. */
585 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
586 if (! table)
587 return 0;
588
589 rn = route_node_lookup (table, (struct prefix *) p);
590
591 /* No route for this prefix. */
592 if (! rn)
593 return NULL;
594
595 /* Unlock node. */
596 route_unlock_node (rn);
597
paul718e3742002-12-13 20:15:29 +0000598 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100599 {
600 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
601 continue;
602 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
603 break;
604 }
paul718e3742002-12-13 20:15:29 +0000605
606 if (! match || match->type == ZEBRA_ROUTE_BGP)
607 return NULL;
608
609 if (match->type == ZEBRA_ROUTE_CONNECT)
610 return match;
611
612 for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
613 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
614 return match;
615
616 return NULL;
617}
618
Denis Ovsienkodc958242007-08-13 16:03:06 +0000619/*
620 * This clone function, unlike its original rib_lookup_ipv4(), checks
621 * if specified IPv4 route record (prefix/mask -> gate) exists in
622 * the whole RIB and has ZEBRA_FLAG_SELECTED set.
623 *
624 * Return values:
625 * -1: error
626 * 0: exact match found
627 * 1: a match was found with a different gate
628 * 2: connected route found
629 * 3: no matches found
630 */
631int
632rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
633{
634 struct route_table *table;
635 struct route_node *rn;
636 struct rib *match;
637 struct nexthop *nexthop;
638
639 /* Lookup table. */
640 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
641 if (! table)
642 return ZEBRA_RIB_LOOKUP_ERROR;
643
644 /* Scan the RIB table for exactly matching RIB entry. */
645 rn = route_node_lookup (table, (struct prefix *) p);
646
647 /* No route for this prefix. */
648 if (! rn)
649 return ZEBRA_RIB_NOTFOUND;
650
651 /* Unlock node. */
652 route_unlock_node (rn);
653
654 /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
655 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100656 {
657 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
658 continue;
659 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
660 break;
661 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000662
663 /* None such found :( */
664 if (!match)
665 return ZEBRA_RIB_NOTFOUND;
666
667 if (match->type == ZEBRA_ROUTE_CONNECT)
668 return ZEBRA_RIB_FOUND_CONNECTED;
669
670 /* Ok, we have a cood candidate, let's check it's nexthop list... */
671 for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
672 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
673 {
674 /* We are happy with either direct or recursive hexthop */
675 if (nexthop->gate.ipv4.s_addr == qgate->sin.sin_addr.s_addr ||
676 nexthop->rgate.ipv4.s_addr == qgate->sin.sin_addr.s_addr)
677 return ZEBRA_RIB_FOUND_EXACT;
678 else
679 {
680 if (IS_ZEBRA_DEBUG_RIB)
681 {
682 char gate_buf[INET_ADDRSTRLEN], rgate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
683 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
684 inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, rgate_buf, INET_ADDRSTRLEN);
685 inet_ntop (AF_INET, &qgate->sin.sin_addr.s_addr, qgate_buf, INET_ADDRSTRLEN);
686 zlog_debug ("%s: qgate == %s, gate == %s, rgate == %s", __func__, qgate_buf, gate_buf, rgate_buf);
687 }
688 return ZEBRA_RIB_FOUND_NOGATE;
689 }
690 }
691
692 return ZEBRA_RIB_NOTFOUND;
693}
694
paul718e3742002-12-13 20:15:29 +0000695#ifdef HAVE_IPV6
696struct rib *
697rib_match_ipv6 (struct in6_addr *addr)
698{
699 struct prefix_ipv6 p;
700 struct route_table *table;
701 struct route_node *rn;
702 struct rib *match;
703 struct nexthop *newhop;
704
705 /* Lookup table. */
706 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
707 if (! table)
708 return 0;
709
710 memset (&p, 0, sizeof (struct prefix_ipv6));
711 p.family = AF_INET6;
712 p.prefixlen = IPV6_MAX_PREFIXLEN;
713 IPV6_ADDR_COPY (&p.prefix, addr);
714
715 rn = route_node_match (table, (struct prefix *) &p);
716
717 while (rn)
718 {
719 route_unlock_node (rn);
720
721 /* Pick up selected route. */
722 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100723 {
724 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
725 continue;
726 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
727 break;
728 }
paul718e3742002-12-13 20:15:29 +0000729
730 /* If there is no selected route or matched route is EGP, go up
731 tree. */
732 if (! match
733 || match->type == ZEBRA_ROUTE_BGP)
734 {
735 do {
736 rn = rn->parent;
737 } while (rn && rn->info == NULL);
738 if (rn)
739 route_lock_node (rn);
740 }
741 else
742 {
743 if (match->type == ZEBRA_ROUTE_CONNECT)
744 /* Directly point connected route. */
745 return match;
746 else
747 {
748 for (newhop = match->nexthop; newhop; newhop = newhop->next)
749 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
750 return match;
751 return NULL;
752 }
753 }
754 }
755 return NULL;
756}
757#endif /* HAVE_IPV6 */
758
Paul Jakma7514fb72007-05-02 16:05:35 +0000759#define RIB_SYSTEM_ROUTE(R) \
760 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
761
Denis Ovsienkodc958242007-08-13 16:03:06 +0000762/* This function verifies reachability of one given nexthop, which can be
763 * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
764 * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
765 * nexthop->ifindex will be updated appropriately as well.
766 * An existing route map can turn (otherwise active) nexthop into inactive, but
767 * not vice versa.
768 *
769 * The return value is the final value of 'ACTIVE' flag.
770 */
771
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300772static unsigned
paul718e3742002-12-13 20:15:29 +0000773nexthop_active_check (struct route_node *rn, struct rib *rib,
774 struct nexthop *nexthop, int set)
775{
776 struct interface *ifp;
Paul Jakma7514fb72007-05-02 16:05:35 +0000777 route_map_result_t ret = RMAP_MATCH;
778 extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
779 struct route_map *rmap;
780 int family;
paul718e3742002-12-13 20:15:29 +0000781
Paul Jakma7514fb72007-05-02 16:05:35 +0000782 family = 0;
paul718e3742002-12-13 20:15:29 +0000783 switch (nexthop->type)
784 {
785 case NEXTHOP_TYPE_IFINDEX:
786 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000787 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000788 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
789 else
790 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
791 break;
paul718e3742002-12-13 20:15:29 +0000792 case NEXTHOP_TYPE_IPV6_IFNAME:
Paul Jakma7514fb72007-05-02 16:05:35 +0000793 family = AFI_IP6;
794 case NEXTHOP_TYPE_IFNAME:
paul718e3742002-12-13 20:15:29 +0000795 ifp = if_lookup_by_name (nexthop->ifname);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000796 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000797 {
798 if (set)
799 nexthop->ifindex = ifp->ifindex;
800 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
801 }
802 else
803 {
804 if (set)
805 nexthop->ifindex = 0;
806 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
807 }
808 break;
809 case NEXTHOP_TYPE_IPV4:
810 case NEXTHOP_TYPE_IPV4_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000811 family = AFI_IP;
paul718e3742002-12-13 20:15:29 +0000812 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
813 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
814 else
815 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
816 break;
817#ifdef HAVE_IPV6
818 case NEXTHOP_TYPE_IPV6:
Paul Jakma7514fb72007-05-02 16:05:35 +0000819 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000820 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
821 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
822 else
823 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
824 break;
825 case NEXTHOP_TYPE_IPV6_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000826 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000827 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
828 {
829 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000830 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000831 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
832 else
833 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
834 }
835 else
836 {
837 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
838 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
839 else
840 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
841 }
842 break;
843#endif /* HAVE_IPV6 */
paul595db7f2003-05-25 21:35:06 +0000844 case NEXTHOP_TYPE_BLACKHOLE:
845 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
846 break;
paul718e3742002-12-13 20:15:29 +0000847 default:
848 break;
849 }
Paul Jakma7514fb72007-05-02 16:05:35 +0000850 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
851 return 0;
852
853 if (RIB_SYSTEM_ROUTE(rib) ||
854 (family == AFI_IP && rn->p.family != AF_INET) ||
855 (family == AFI_IP6 && rn->p.family != AF_INET6))
856 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
857
858 rmap = 0;
859 if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
860 proto_rm[family][rib->type])
861 rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
862 if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
863 rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
864 if (rmap) {
865 ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, nexthop);
866 }
867
868 if (ret == RMAP_DENYMATCH)
869 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
paul718e3742002-12-13 20:15:29 +0000870 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
871}
872
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000873/* Iterate over all nexthops of the given RIB entry and refresh their
874 * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
875 * nexthop is found to toggle the ACTIVE flag, the whole rib structure
876 * is flagged with ZEBRA_FLAG_CHANGED. The 4th 'set' argument is
877 * transparently passed to nexthop_active_check().
878 *
879 * Return value is the new number of active nexthops.
880 */
881
paula1ac18c2005-06-28 17:17:12 +0000882static int
paul718e3742002-12-13 20:15:29 +0000883nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
884{
885 struct nexthop *nexthop;
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300886 unsigned int prev_active, prev_index, new_active;
paul718e3742002-12-13 20:15:29 +0000887
888 rib->nexthop_active_num = 0;
889 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
890
891 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000892 {
893 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
Joakim Tjernlundc3a56062009-06-24 19:15:36 +0200894 prev_index = nexthop->ifindex;
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000895 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
896 rib->nexthop_active_num++;
Joakim Tjernlundc3a56062009-06-24 19:15:36 +0200897 if (prev_active != new_active ||
898 prev_index != nexthop->ifindex)
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000899 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
900 }
paul718e3742002-12-13 20:15:29 +0000901 return rib->nexthop_active_num;
902}
paul6baeb982003-10-28 03:47:15 +0000903
paul718e3742002-12-13 20:15:29 +0000904
paul718e3742002-12-13 20:15:29 +0000905
paula1ac18c2005-06-28 17:17:12 +0000906static void
paul718e3742002-12-13 20:15:29 +0000907rib_install_kernel (struct route_node *rn, struct rib *rib)
908{
909 int ret = 0;
910 struct nexthop *nexthop;
911
912 switch (PREFIX_FAMILY (&rn->p))
913 {
914 case AF_INET:
915 ret = kernel_add_ipv4 (&rn->p, rib);
916 break;
917#ifdef HAVE_IPV6
918 case AF_INET6:
919 ret = kernel_add_ipv6 (&rn->p, rib);
920 break;
921#endif /* HAVE_IPV6 */
922 }
923
Denis Ovsienkodc958242007-08-13 16:03:06 +0000924 /* This condition is never met, if we are using rt_socket.c */
paul718e3742002-12-13 20:15:29 +0000925 if (ret < 0)
926 {
927 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
928 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
929 }
930}
931
932/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +0000933static int
paul718e3742002-12-13 20:15:29 +0000934rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
935{
936 int ret = 0;
937 struct nexthop *nexthop;
938
939 switch (PREFIX_FAMILY (&rn->p))
940 {
941 case AF_INET:
942 ret = kernel_delete_ipv4 (&rn->p, rib);
943 break;
944#ifdef HAVE_IPV6
945 case AF_INET6:
946 ret = kernel_delete_ipv6 (&rn->p, rib);
947 break;
948#endif /* HAVE_IPV6 */
949 }
950
951 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
952 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
953
954 return ret;
955}
956
957/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +0000958static void
paul718e3742002-12-13 20:15:29 +0000959rib_uninstall (struct route_node *rn, struct rib *rib)
960{
961 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
962 {
963 redistribute_delete (&rn->p, rib);
964 if (! RIB_SYSTEM_ROUTE (rib))
965 rib_uninstall_kernel (rn, rib);
966 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
967 }
968}
969
Paul Jakma6d691122006-07-27 21:49:00 +0000970static void rib_unlink (struct route_node *, struct rib *);
971
paul718e3742002-12-13 20:15:29 +0000972/* Core function for processing routing information base. */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +0000973static void
974rib_process (struct route_node *rn)
paul718e3742002-12-13 20:15:29 +0000975{
976 struct rib *rib;
977 struct rib *next;
978 struct rib *fib = NULL;
979 struct rib *select = NULL;
Paul Jakma6d691122006-07-27 21:49:00 +0000980 struct rib *del = NULL;
pauld753e9e2003-01-22 19:45:50 +0000981 int installed = 0;
982 struct nexthop *nexthop = NULL;
Denis Ovsienkof304cb42007-10-03 12:27:16 +0000983 char buf[INET6_ADDRSTRLEN];
paul4d38fdb2005-04-28 17:35:14 +0000984
985 assert (rn);
986
Paul Jakma93bdada2007-08-06 19:25:11 +0000987 if (IS_ZEBRA_DEBUG_RIB || IS_ZEBRA_DEBUG_RIB_Q)
Denis Ovsienkof304cb42007-10-03 12:27:16 +0000988 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +0000989
paul718e3742002-12-13 20:15:29 +0000990 for (rib = rn->info; rib; rib = next)
991 {
Denis Ovsienkodc958242007-08-13 16:03:06 +0000992 /* The next pointer is saved, because current pointer
993 * may be passed to rib_unlink() in the middle of iteration.
994 */
paul718e3742002-12-13 20:15:29 +0000995 next = rib->next;
pauld753e9e2003-01-22 19:45:50 +0000996
paul718e3742002-12-13 20:15:29 +0000997 /* Currently installed rib. */
998 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Paul Jakma6d691122006-07-27 21:49:00 +0000999 {
1000 assert (fib == NULL);
1001 fib = rib;
1002 }
1003
1004 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1005 * which we need to do do further work with below.
1006 */
1007 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1008 {
1009 if (rib != fib)
1010 {
1011 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001012 zlog_debug ("%s: %s/%d: rn %p, removing rib %p", __func__,
1013 buf, rn->p.prefixlen, rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001014 rib_unlink (rn, rib);
1015 }
1016 else
1017 del = rib;
1018
1019 continue;
1020 }
paul4d38fdb2005-04-28 17:35:14 +00001021
paul718e3742002-12-13 20:15:29 +00001022 /* Skip unreachable nexthop. */
1023 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +00001024 continue;
paul718e3742002-12-13 20:15:29 +00001025
1026 /* Infinit distance. */
1027 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +00001028 continue;
paul718e3742002-12-13 20:15:29 +00001029
paulaf887b52006-01-18 14:52:52 +00001030 /* Newly selected rib, the common case. */
1031 if (!select)
1032 {
1033 select = rib;
1034 continue;
1035 }
1036
1037 /* filter route selection in following order:
paulaf887b52006-01-18 14:52:52 +00001038 * - connected beats other types
paula8d9c1f2006-01-25 06:31:04 +00001039 * - lower distance beats higher
paulaf887b52006-01-18 14:52:52 +00001040 * - lower metric beats higher for equal distance
1041 * - last, hence oldest, route wins tie break.
1042 */
paula1038a12006-01-30 14:08:51 +00001043
1044 /* Connected routes. Pick the last connected
1045 * route of the set of lowest metric connected routes.
1046 */
paula8d9c1f2006-01-25 06:31:04 +00001047 if (rib->type == ZEBRA_ROUTE_CONNECT)
1048 {
paula1038a12006-01-30 14:08:51 +00001049 if (select->type != ZEBRA_ROUTE_CONNECT
paula8d9c1f2006-01-25 06:31:04 +00001050 || rib->metric <= select->metric)
paula1038a12006-01-30 14:08:51 +00001051 select = rib;
1052 continue;
paula8d9c1f2006-01-25 06:31:04 +00001053 }
1054 else if (select->type == ZEBRA_ROUTE_CONNECT)
1055 continue;
1056
1057 /* higher distance loses */
1058 if (rib->distance > select->distance)
1059 continue;
1060
1061 /* lower wins */
1062 if (rib->distance < select->distance)
1063 {
paulaf887b52006-01-18 14:52:52 +00001064 select = rib;
paula8d9c1f2006-01-25 06:31:04 +00001065 continue;
1066 }
1067
1068 /* metric tie-breaks equal distance */
1069 if (rib->metric <= select->metric)
1070 select = rib;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001071 } /* for (rib = rn->info; rib; rib = next) */
1072
1073 /* After the cycle is finished, the following pointers will be set:
1074 * select --- the winner RIB entry, if any was found, otherwise NULL
1075 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1076 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1077 * rib --- NULL
1078 */
1079
1080 /* Same RIB entry is selected. Update FIB and finish. */
paul718e3742002-12-13 20:15:29 +00001081 if (select && select == fib)
1082 {
Paul Jakma6d691122006-07-27 21:49:00 +00001083 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001084 zlog_debug ("%s: %s/%d: Updating existing route, select %p, fib %p",
1085 __func__, buf, rn->p.prefixlen, select, fib);
paul718e3742002-12-13 20:15:29 +00001086 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +00001087 {
1088 redistribute_delete (&rn->p, select);
1089 if (! RIB_SYSTEM_ROUTE (select))
1090 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001091
paul4d38fdb2005-04-28 17:35:14 +00001092 /* Set real nexthop. */
1093 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +00001094
paul4d38fdb2005-04-28 17:35:14 +00001095 if (! RIB_SYSTEM_ROUTE (select))
1096 rib_install_kernel (rn, select);
1097 redistribute_add (&rn->p, select);
1098 }
pauld753e9e2003-01-22 19:45:50 +00001099 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001100 {
1101 /* Housekeeping code to deal with
1102 race conditions in kernel with linux
1103 netlink reporting interface up before IPv4 or IPv6 protocol
1104 is ready to add routes.
1105 This makes sure the routes are IN the kernel.
1106 */
pauld753e9e2003-01-22 19:45:50 +00001107
paul4d38fdb2005-04-28 17:35:14 +00001108 for (nexthop = select->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001109 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
paul4d38fdb2005-04-28 17:35:14 +00001110 {
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001111 installed = 1;
1112 break;
paul4d38fdb2005-04-28 17:35:14 +00001113 }
1114 if (! installed)
1115 rib_install_kernel (rn, select);
1116 }
Paul Jakma6d691122006-07-27 21:49:00 +00001117 goto end;
paul718e3742002-12-13 20:15:29 +00001118 }
1119
Denis Ovsienkodc958242007-08-13 16:03:06 +00001120 /* At this point we either haven't found the best RIB entry or it is
1121 * different from what we currently intend to flag with SELECTED. In both
1122 * cases, if a RIB block is present in FIB, it should be withdrawn.
1123 */
paul718e3742002-12-13 20:15:29 +00001124 if (fib)
1125 {
Paul Jakma6d691122006-07-27 21:49:00 +00001126 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001127 zlog_debug ("%s: %s/%d: Removing existing route, fib %p", __func__,
1128 buf, rn->p.prefixlen, fib);
paul718e3742002-12-13 20:15:29 +00001129 redistribute_delete (&rn->p, fib);
1130 if (! RIB_SYSTEM_ROUTE (fib))
1131 rib_uninstall_kernel (rn, fib);
1132 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1133
1134 /* Set real nexthop. */
1135 nexthop_active_update (rn, fib, 1);
1136 }
1137
Denis Ovsienkodc958242007-08-13 16:03:06 +00001138 /* Regardless of some RIB entry being SELECTED or not before, now we can
1139 * tell, that if a new winner exists, FIB is still not updated with this
1140 * data, but ready to be.
1141 */
paul718e3742002-12-13 20:15:29 +00001142 if (select)
1143 {
Paul Jakma6d691122006-07-27 21:49:00 +00001144 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001145 zlog_debug ("%s: %s/%d: Adding route, select %p", __func__, buf,
1146 rn->p.prefixlen, select);
paul718e3742002-12-13 20:15:29 +00001147 /* Set real nexthop. */
1148 nexthop_active_update (rn, select, 1);
1149
1150 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001151 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001152 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1153 redistribute_add (&rn->p, select);
1154 }
paul4d38fdb2005-04-28 17:35:14 +00001155
Paul Jakma6d691122006-07-27 21:49:00 +00001156 /* FIB route was removed, should be deleted */
1157 if (del)
1158 {
1159 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001160 zlog_debug ("%s: %s/%d: Deleting fib %p, rn %p", __func__, buf,
1161 rn->p.prefixlen, del, rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001162 rib_unlink (rn, del);
1163 }
paul4d38fdb2005-04-28 17:35:14 +00001164
Paul Jakma6d691122006-07-27 21:49:00 +00001165end:
1166 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma93bdada2007-08-06 19:25:11 +00001167 zlog_debug ("%s: %s/%d: rn %p dequeued", __func__, buf, rn->p.prefixlen, rn);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001168}
1169
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001170/* Take a list of route_node structs and return 1, if there was a record
1171 * picked from it and processed by rib_process(). Don't process more,
1172 * than one RN record; operate only in the specified sub-queue.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001173 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001174static unsigned int
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001175process_subq (struct list * subq, u_char qindex)
1176{
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001177 struct listnode *lnode = listhead (subq);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001178 struct route_node *rnode;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001179
1180 if (!lnode)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001181 return 0;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001182
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001183 rnode = listgetdata (lnode);
1184 rib_process (rnode);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001185
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001186 if (rnode->info) /* The first RIB record is holding the flags bitmask. */
1187 UNSET_FLAG (((struct rib *)rnode->info)->rn_status, RIB_ROUTE_QUEUED(qindex));
Chris Caputo67b94672009-07-18 04:02:26 +00001188#if 0
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001189 else
1190 {
1191 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1192 __func__, rnode, rnode->lock);
1193 zlog_backtrace(LOG_DEBUG);
1194 }
Chris Caputo67b94672009-07-18 04:02:26 +00001195#endif
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001196 route_unlock_node (rnode);
1197 list_delete_node (subq, lnode);
1198 return 1;
1199}
1200
1201/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1202 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1203 * is pointed to the meta queue structure.
1204 */
1205static wq_item_status
1206meta_queue_process (struct work_queue *dummy, void *data)
1207{
1208 struct meta_queue * mq = data;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001209 unsigned i;
1210
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001211 for (i = 0; i < MQ_SIZE; i++)
1212 if (process_subq (mq->subq[i], i))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001213 {
1214 mq->size--;
1215 break;
1216 }
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001217 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1218}
1219
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001220/* Map from rib types to queue type (priority) in meta queue */
1221static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
1222 [ZEBRA_ROUTE_SYSTEM] = 4,
1223 [ZEBRA_ROUTE_KERNEL] = 0,
1224 [ZEBRA_ROUTE_CONNECT] = 0,
1225 [ZEBRA_ROUTE_STATIC] = 1,
1226 [ZEBRA_ROUTE_RIP] = 2,
1227 [ZEBRA_ROUTE_RIPNG] = 2,
1228 [ZEBRA_ROUTE_OSPF] = 2,
1229 [ZEBRA_ROUTE_OSPF6] = 2,
1230 [ZEBRA_ROUTE_ISIS] = 2,
1231 [ZEBRA_ROUTE_BGP] = 3,
1232 [ZEBRA_ROUTE_HSLS] = 4,
1233};
1234
1235/* Look into the RN and queue it into one or more priority queues,
1236 * increasing the size for each data push done.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001237 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001238static void
1239rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001240{
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001241 struct rib *rib;
1242 char buf[INET6_ADDRSTRLEN];
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001243
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001244 if (IS_ZEBRA_DEBUG_RIB_Q)
1245 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001246
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001247 for (rib = rn->info; rib; rib = rib->next)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001248 {
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001249 u_char qindex = meta_queue_map[rib->type];
1250
1251 /* Invariant: at this point we always have rn->info set. */
1252 if (CHECK_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED(qindex)))
1253 {
1254 if (IS_ZEBRA_DEBUG_RIB_Q)
1255 zlog_debug ("%s: %s/%d: rn %p is already queued in sub-queue %u",
1256 __func__, buf, rn->p.prefixlen, rn, qindex);
1257 continue;
1258 }
1259
1260 SET_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED(qindex));
1261 listnode_add (mq->subq[qindex], rn);
1262 route_lock_node (rn);
1263 mq->size++;
1264
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001265 if (IS_ZEBRA_DEBUG_RIB_Q)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001266 zlog_debug ("%s: %s/%d: queued rn %p into sub-queue %u",
1267 __func__, buf, rn->p.prefixlen, rn, qindex);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001268 }
paul4d38fdb2005-04-28 17:35:14 +00001269}
1270
Paul Jakma6d691122006-07-27 21:49:00 +00001271/* Add route_node to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001272static void
Paul Jakma6d691122006-07-27 21:49:00 +00001273rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
paul4d38fdb2005-04-28 17:35:14 +00001274{
paul4d38fdb2005-04-28 17:35:14 +00001275
Paul Jakma93bdada2007-08-06 19:25:11 +00001276 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma6d691122006-07-27 21:49:00 +00001277 {
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001278 char buf[INET6_ADDRSTRLEN];
1279
1280 zlog_info ("%s: %s/%d: work queue added", __func__,
1281 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN),
1282 rn->p.prefixlen);
Paul Jakma6d691122006-07-27 21:49:00 +00001283 }
paul4d38fdb2005-04-28 17:35:14 +00001284
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001285 /*
1286 * The RIB queue should normally be either empty or holding the only
1287 * work_queue_item element. In the latter case this element would
1288 * hold a pointer to the meta queue structure, which must be used to
1289 * actually queue the route nodes to process. So create the MQ
1290 * holder, if necessary, then push the work into it in any case.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001291 * This semantics was introduced after 0.99.9 release.
1292 */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001293 if (!zebra->ribq->items->count)
1294 work_queue_add (zebra->ribq, zebra->mq);
1295
1296 rib_meta_queue_add (zebra->mq, rn);
paul4d38fdb2005-04-28 17:35:14 +00001297}
1298
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001299/* Create new meta queue.
1300 A destructor function doesn't seem to be necessary here.
1301 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001302static struct meta_queue *
1303meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001304{
1305 struct meta_queue *new;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001306 unsigned i;
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001307
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001308 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1309 assert(new);
1310
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001311 for (i = 0; i < MQ_SIZE; i++)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001312 {
1313 new->subq[i] = list_new ();
1314 assert(new->subq[i]);
1315 }
1316
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001317 return new;
1318}
1319
paul4d38fdb2005-04-28 17:35:14 +00001320/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001321static void
paul4d38fdb2005-04-28 17:35:14 +00001322rib_queue_init (struct zebra_t *zebra)
1323{
paul4d38fdb2005-04-28 17:35:14 +00001324 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001325 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001326 {
Paul Jakma6d691122006-07-27 21:49:00 +00001327 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001328 return;
1329 }
1330
1331 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001332 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001333 zebra->ribq->spec.errorfunc = NULL;
paul4d38fdb2005-04-28 17:35:14 +00001334 /* XXX: TODO: These should be runtime configurable via vty */
1335 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001336 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001337
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001338 if (!(zebra->mq = meta_queue_new ()))
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001339 zlog_err ("%s: could not initialise meta queue!", __func__);
paul718e3742002-12-13 20:15:29 +00001340}
1341
Paul Jakma6d691122006-07-27 21:49:00 +00001342/* RIB updates are processed via a queue of pointers to route_nodes.
1343 *
1344 * The queue length is bounded by the maximal size of the routing table,
1345 * as a route_node will not be requeued, if already queued.
1346 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001347 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1348 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1349 * and then submit route_node to queue for best-path selection later.
1350 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001351 *
1352 * Deleted RIBs are reaped during best-path selection.
1353 *
1354 * rib_addnode
1355 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001356 * |-------->| | best RIB, if required
1357 * | |
1358 * static_install->|->rib_addqueue...... -> rib_process
1359 * | |
1360 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001361 * |-> set RIB_ENTRY_REMOVE |
1362 * rib_delnode (RIB freed)
1363 *
1364 *
1365 * Queueing state for a route_node is kept in the head RIB entry, this
1366 * state must be preserved as and when the head RIB entry of a
1367 * route_node is changed by rib_unlink / rib_link. A small complication,
1368 * but saves having to allocate a dedicated object for this.
1369 *
1370 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1371 *
1372 * - route_nodes: refcounted by:
1373 * - RIBs attached to route_node:
1374 * - managed by: rib_link/unlink
1375 * - route_node processing queue
1376 * - managed by: rib_addqueue, rib_process.
1377 *
1378 */
1379
paul718e3742002-12-13 20:15:29 +00001380/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001381static void
Paul Jakma6d691122006-07-27 21:49:00 +00001382rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001383{
1384 struct rib *head;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001385 char buf[INET6_ADDRSTRLEN];
paul4d38fdb2005-04-28 17:35:14 +00001386
1387 assert (rib && rn);
1388
Paul Jakma6d691122006-07-27 21:49:00 +00001389 route_lock_node (rn); /* rn route table reference */
1390
1391 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001392 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001393 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001394 zlog_debug ("%s: %s/%d: rn %p, rib %p", __func__,
1395 buf, rn->p.prefixlen, rn, rib);
1396 }
Paul Jakma6d691122006-07-27 21:49:00 +00001397
paul718e3742002-12-13 20:15:29 +00001398 head = rn->info;
1399 if (head)
Paul Jakma6d691122006-07-27 21:49:00 +00001400 {
1401 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001402 zlog_debug ("%s: %s/%d: new head, rn_status copied over", __func__,
1403 buf, rn->p.prefixlen);
Paul Jakma6d691122006-07-27 21:49:00 +00001404 head->prev = rib;
1405 /* Transfer the rn status flags to the new head RIB */
1406 rib->rn_status = head->rn_status;
1407 }
paul718e3742002-12-13 20:15:29 +00001408 rib->next = head;
1409 rn->info = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001410 rib_queue_add (&zebrad, rn);
1411}
1412
1413static void
1414rib_addnode (struct route_node *rn, struct rib *rib)
1415{
1416 /* RIB node has been un-removed before route-node is processed.
1417 * route_node must hence already be on the queue for processing..
1418 */
1419 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1420 {
1421 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001422 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001423 char buf[INET6_ADDRSTRLEN];
1424 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001425 zlog_debug ("%s: %s/%d: rn %p, un-removed rib %p",
1426 __func__, buf, rn->p.prefixlen, rn, rib);
1427 }
Paul Jakma6d691122006-07-27 21:49:00 +00001428 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1429 return;
1430 }
1431 rib_link (rn, rib);
1432}
1433
1434static void
1435rib_unlink (struct route_node *rn, struct rib *rib)
1436{
1437 struct nexthop *nexthop, *next;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001438 char buf[INET6_ADDRSTRLEN];
Paul Jakma6d691122006-07-27 21:49:00 +00001439
1440 assert (rn && rib);
1441
1442 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001443 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001444 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001445 zlog_debug ("%s: %s/%d: rn %p, rib %p",
1446 __func__, buf, rn->p.prefixlen, rn, rib);
1447 }
Paul Jakma6d691122006-07-27 21:49:00 +00001448
1449 if (rib->next)
1450 rib->next->prev = rib->prev;
1451
1452 if (rib->prev)
1453 rib->prev->next = rib->next;
1454 else
1455 {
1456 rn->info = rib->next;
1457
1458 if (rn->info)
1459 {
1460 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001461 zlog_debug ("%s: %s/%d: rn %p, rib %p, new head copy",
1462 __func__, buf, rn->p.prefixlen, rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001463 rib->next->rn_status = rib->rn_status;
1464 }
1465 }
1466
1467 /* free RIB and nexthops */
1468 for (nexthop = rib->nexthop; nexthop; nexthop = next)
1469 {
1470 next = nexthop->next;
1471 nexthop_free (nexthop);
1472 }
1473 XFREE (MTYPE_RIB, rib);
1474
1475 route_unlock_node (rn); /* rn route table reference */
paul718e3742002-12-13 20:15:29 +00001476}
1477
paula1ac18c2005-06-28 17:17:12 +00001478static void
paul718e3742002-12-13 20:15:29 +00001479rib_delnode (struct route_node *rn, struct rib *rib)
1480{
Paul Jakma6d691122006-07-27 21:49:00 +00001481 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001482 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001483 char buf[INET6_ADDRSTRLEN];
1484 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001485 zlog_debug ("%s: %s/%d: rn %p, rib %p, removing", __func__,
1486 buf, rn->p.prefixlen, rn, rib);
1487 }
Paul Jakma6d691122006-07-27 21:49:00 +00001488 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1489 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001490}
1491
1492int
1493rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001494 struct in_addr *gate, struct in_addr *src,
1495 unsigned int ifindex, u_int32_t vrf_id,
paul718e3742002-12-13 20:15:29 +00001496 u_int32_t metric, u_char distance)
1497{
1498 struct rib *rib;
1499 struct rib *same = NULL;
1500 struct route_table *table;
1501 struct route_node *rn;
1502 struct nexthop *nexthop;
1503
1504 /* Lookup table. */
1505 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1506 if (! table)
1507 return 0;
1508
1509 /* Make it sure prefixlen is applied to the prefix. */
1510 apply_mask_ipv4 (p);
1511
1512 /* Set default distance by route type. */
1513 if (distance == 0)
1514 {
David Lamparter7052f222009-08-27 00:28:28 +02001515 if ((unsigned)type >= sizeof(route_info) / sizeof(route_info[0]))
1516 distance = 150;
1517 else
1518 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00001519
1520 /* iBGP distance is 200. */
1521 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1522 distance = 200;
1523 }
1524
1525 /* Lookup route node.*/
1526 rn = route_node_get (table, (struct prefix *) p);
1527
1528 /* If same type of route are installed, treat it as a implicit
1529 withdraw. */
1530 for (rib = rn->info; rib; rib = rib->next)
1531 {
Paul Jakma6d691122006-07-27 21:49:00 +00001532 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1533 continue;
1534
hassoebf1ead2005-09-21 14:58:20 +00001535 if (rib->type != type)
1536 continue;
1537 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001538 {
1539 same = rib;
1540 break;
1541 }
hassoebf1ead2005-09-21 14:58:20 +00001542 /* Duplicate connected route comes in. */
1543 else if ((nexthop = rib->nexthop) &&
1544 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001545 nexthop->ifindex == ifindex &&
1546 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001547 {
1548 rib->refcnt++;
1549 return 0 ;
1550 }
paul718e3742002-12-13 20:15:29 +00001551 }
1552
1553 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001554 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001555 rib->type = type;
1556 rib->distance = distance;
1557 rib->flags = flags;
1558 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001559 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001560 rib->nexthop_num = 0;
1561 rib->uptime = time (NULL);
1562
1563 /* Nexthop settings. */
1564 if (gate)
1565 {
1566 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001567 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001568 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001569 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001570 }
1571 else
1572 nexthop_ifindex_add (rib, ifindex);
1573
1574 /* If this route is kernel route, set FIB flag to the route. */
1575 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1576 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1577 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1578
1579 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001580 if (IS_ZEBRA_DEBUG_RIB)
1581 zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
paul718e3742002-12-13 20:15:29 +00001582 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001583
paul718e3742002-12-13 20:15:29 +00001584 /* Free implicit route.*/
1585 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001586 {
1587 if (IS_ZEBRA_DEBUG_RIB)
1588 zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001589 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001590 }
paul4d38fdb2005-04-28 17:35:14 +00001591
1592 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001593 return 0;
1594}
1595
Denis Ovsienkodc958242007-08-13 16:03:06 +00001596/* This function dumps the contents of a given RIB entry into
1597 * standard debug log. Calling function name and IP prefix in
1598 * question are passed as 1st and 2nd arguments.
1599 */
1600
1601void rib_dump (const char * func, const struct prefix_ipv4 * p, const struct rib * rib)
1602{
1603 char straddr1[INET_ADDRSTRLEN], straddr2[INET_ADDRSTRLEN];
1604 struct nexthop *nexthop;
1605
1606 inet_ntop (AF_INET, &p->prefix, straddr1, INET_ADDRSTRLEN);
1607 zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr1, p->prefixlen);
1608 zlog_debug
1609 (
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001610 "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
Denis Ovsienkodc958242007-08-13 16:03:06 +00001611 func,
1612 rib->refcnt,
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001613 (unsigned long) rib->uptime,
Denis Ovsienkodc958242007-08-13 16:03:06 +00001614 rib->type,
1615 rib->table
1616 );
1617 zlog_debug
1618 (
1619 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1620 func,
1621 rib->metric,
1622 rib->distance,
1623 rib->flags,
1624 rib->status
1625 );
1626 zlog_debug
1627 (
1628 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1629 func,
1630 rib->nexthop_num,
1631 rib->nexthop_active_num,
1632 rib->nexthop_fib_num
1633 );
1634 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1635 {
1636 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, straddr1, INET_ADDRSTRLEN);
1637 inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, straddr2, INET_ADDRSTRLEN);
1638 zlog_debug
1639 (
1640 "%s: NH %s (%s) with flags %s%s%s",
1641 func,
1642 straddr1,
1643 straddr2,
1644 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1645 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1646 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1647 );
1648 }
1649 zlog_debug ("%s: dump complete", func);
1650}
1651
1652/* This is an exported helper to rtm_read() to dump the strange
1653 * RIB entry found by rib_lookup_ipv4_route()
1654 */
1655
1656void rib_lookup_and_dump (struct prefix_ipv4 * p)
1657{
1658 struct route_table *table;
1659 struct route_node *rn;
1660 struct rib *rib;
1661 char prefix_buf[INET_ADDRSTRLEN];
1662
1663 /* Lookup table. */
1664 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1665 if (! table)
1666 {
1667 zlog_err ("%s: vrf_table() returned NULL", __func__);
1668 return;
1669 }
1670
1671 inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
1672 /* Scan the RIB table for exactly matching RIB entry. */
1673 rn = route_node_lookup (table, (struct prefix *) p);
1674
1675 /* No route for this prefix. */
1676 if (! rn)
1677 {
1678 zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
1679 return;
1680 }
1681
1682 /* Unlock node. */
1683 route_unlock_node (rn);
1684
1685 /* let's go */
1686 for (rib = rn->info; rib; rib = rib->next)
1687 {
1688 zlog_debug
1689 (
1690 "%s: rn %p, rib %p: %s, %s",
1691 __func__,
1692 rn,
1693 rib,
1694 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
1695 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
1696 );
1697 rib_dump (__func__, p, rib);
1698 }
1699}
1700
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001701/* Check if requested address assignment will fail due to another
1702 * route being installed by zebra in FIB already. Take necessary
1703 * actions, if needed: remove such a route from FIB and deSELECT
1704 * corresponding RIB entry. Then put affected RN into RIBQ head.
1705 */
1706void rib_lookup_and_pushup (struct prefix_ipv4 * p)
1707{
1708 struct route_table *table;
1709 struct route_node *rn;
1710 struct rib *rib;
1711 unsigned changed = 0;
1712
1713 if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
1714 {
1715 zlog_err ("%s: vrf_table() returned NULL", __func__);
1716 return;
1717 }
1718
1719 /* No matches would be the simplest case. */
1720 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
1721 return;
1722
1723 /* Unlock node. */
1724 route_unlock_node (rn);
1725
1726 /* Check all RIB entries. In case any changes have to be done, requeue
1727 * the RN into RIBQ head. If the routing message about the new connected
1728 * route (generated by the IP address we are going to assign very soon)
1729 * comes before the RIBQ is processed, the new RIB entry will join
1730 * RIBQ record already on head. This is necessary for proper revalidation
1731 * of the rest of the RIB.
1732 */
1733 for (rib = rn->info; rib; rib = rib->next)
1734 {
1735 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
1736 ! RIB_SYSTEM_ROUTE (rib))
1737 {
1738 changed = 1;
1739 if (IS_ZEBRA_DEBUG_RIB)
1740 {
1741 char buf[INET_ADDRSTRLEN];
1742 inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
1743 zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
1744 rib_dump (__func__, (struct prefix_ipv4 *)&rn->p, rib);
1745 }
1746 rib_uninstall (rn, rib);
1747 }
1748 }
1749 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001750 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001751}
1752
paul718e3742002-12-13 20:15:29 +00001753int
1754rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib)
1755{
1756 struct route_table *table;
1757 struct route_node *rn;
1758 struct rib *same;
1759 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00001760
paul718e3742002-12-13 20:15:29 +00001761 /* Lookup table. */
1762 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1763 if (! table)
1764 return 0;
paul718e3742002-12-13 20:15:29 +00001765 /* Make it sure prefixlen is applied to the prefix. */
1766 apply_mask_ipv4 (p);
1767
1768 /* Set default distance by route type. */
1769 if (rib->distance == 0)
1770 {
1771 rib->distance = route_info[rib->type].distance;
1772
1773 /* iBGP distance is 200. */
1774 if (rib->type == ZEBRA_ROUTE_BGP
1775 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1776 rib->distance = 200;
1777 }
1778
1779 /* Lookup route node.*/
1780 rn = route_node_get (table, (struct prefix *) p);
1781
1782 /* If same type of route are installed, treat it as a implicit
1783 withdraw. */
1784 for (same = rn->info; same; same = same->next)
1785 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00001786 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00001787 continue;
1788
paul718e3742002-12-13 20:15:29 +00001789 if (same->type == rib->type && same->table == rib->table
1790 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001791 break;
paul718e3742002-12-13 20:15:29 +00001792 }
paul4d38fdb2005-04-28 17:35:14 +00001793
paul718e3742002-12-13 20:15:29 +00001794 /* If this route is kernel route, set FIB flag to the route. */
1795 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
1796 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1797 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1798
1799 /* Link new rib to node.*/
1800 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001801 if (IS_ZEBRA_DEBUG_RIB)
1802 {
1803 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
1804 __func__, rn, rib);
1805 rib_dump (__func__, p, rib);
1806 }
paul718e3742002-12-13 20:15:29 +00001807
paul718e3742002-12-13 20:15:29 +00001808 /* Free implicit route.*/
1809 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001810 {
1811 if (IS_ZEBRA_DEBUG_RIB)
1812 {
1813 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
1814 __func__, rn, same);
1815 rib_dump (__func__, p, same);
1816 }
paul4d38fdb2005-04-28 17:35:14 +00001817 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001818 }
paul4d38fdb2005-04-28 17:35:14 +00001819
1820 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001821 return 0;
1822}
1823
hassoebf1ead2005-09-21 14:58:20 +00001824/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00001825int
1826rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
1827 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
1828{
1829 struct route_table *table;
1830 struct route_node *rn;
1831 struct rib *rib;
1832 struct rib *fib = NULL;
1833 struct rib *same = NULL;
1834 struct nexthop *nexthop;
Stephen Hemminger81cce012009-04-28 14:28:00 -07001835 char buf1[INET_ADDRSTRLEN];
1836 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00001837
1838 /* Lookup table. */
1839 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1840 if (! table)
1841 return 0;
1842
1843 /* Apply mask. */
1844 apply_mask_ipv4 (p);
1845
paul5ec90d22003-06-19 01:41:37 +00001846 if (IS_ZEBRA_DEBUG_KERNEL && gate)
ajsb6178002004-12-07 21:12:56 +00001847 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001848 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul5ec90d22003-06-19 01:41:37 +00001849 p->prefixlen,
1850 inet_ntoa (*gate),
1851 ifindex);
1852
paul718e3742002-12-13 20:15:29 +00001853 /* Lookup route node. */
1854 rn = route_node_lookup (table, (struct prefix *) p);
1855 if (! rn)
1856 {
1857 if (IS_ZEBRA_DEBUG_KERNEL)
1858 {
1859 if (gate)
ajsb6178002004-12-07 21:12:56 +00001860 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001861 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001862 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07001863 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001864 ifindex);
1865 else
ajsb6178002004-12-07 21:12:56 +00001866 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001867 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001868 p->prefixlen,
1869 ifindex);
1870 }
1871 return ZEBRA_ERR_RTNOEXIST;
1872 }
1873
1874 /* Lookup same type route. */
1875 for (rib = rn->info; rib; rib = rib->next)
1876 {
Paul Jakma6d691122006-07-27 21:49:00 +00001877 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1878 continue;
1879
paul718e3742002-12-13 20:15:29 +00001880 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1881 fib = rib;
1882
hassoebf1ead2005-09-21 14:58:20 +00001883 if (rib->type != type)
1884 continue;
1885 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04001886 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00001887 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04001888 if (nexthop->ifindex != ifindex)
1889 continue;
hassoebf1ead2005-09-21 14:58:20 +00001890 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00001891 {
hassoebf1ead2005-09-21 14:58:20 +00001892 rib->refcnt--;
1893 route_unlock_node (rn);
1894 route_unlock_node (rn);
1895 return 0;
paul718e3742002-12-13 20:15:29 +00001896 }
hassoebf1ead2005-09-21 14:58:20 +00001897 same = rib;
1898 break;
paul718e3742002-12-13 20:15:29 +00001899 }
hassoebf1ead2005-09-21 14:58:20 +00001900 /* Make sure that the route found has the same gateway. */
1901 else if (gate == NULL ||
1902 ((nexthop = rib->nexthop) &&
1903 (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
1904 IPV4_ADDR_SAME (&nexthop->rgate.ipv4, gate))))
paul5ec90d22003-06-19 01:41:37 +00001905 {
hassoebf1ead2005-09-21 14:58:20 +00001906 same = rib;
1907 break;
paul718e3742002-12-13 20:15:29 +00001908 }
1909 }
1910
1911 /* If same type of route can't be found and this message is from
1912 kernel. */
1913 if (! same)
1914 {
1915 if (fib && type == ZEBRA_ROUTE_KERNEL)
1916 {
1917 /* Unset flags. */
1918 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1919 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1920
1921 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1922 }
1923 else
1924 {
1925 if (IS_ZEBRA_DEBUG_KERNEL)
1926 {
1927 if (gate)
ajsb6178002004-12-07 21:12:56 +00001928 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001929 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001930 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07001931 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001932 ifindex,
1933 type);
1934 else
ajsb6178002004-12-07 21:12:56 +00001935 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001936 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001937 p->prefixlen,
1938 ifindex,
1939 type);
1940 }
1941 route_unlock_node (rn);
1942 return ZEBRA_ERR_RTNOEXIST;
1943 }
1944 }
paul4d38fdb2005-04-28 17:35:14 +00001945
paul718e3742002-12-13 20:15:29 +00001946 if (same)
1947 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00001948
paul718e3742002-12-13 20:15:29 +00001949 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001950 return 0;
1951}
1952
1953/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00001954static void
paul718e3742002-12-13 20:15:29 +00001955static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
1956{
1957 struct rib *rib;
1958 struct route_node *rn;
1959 struct route_table *table;
1960
1961 /* Lookup table. */
1962 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1963 if (! table)
1964 return;
1965
1966 /* Lookup existing route */
1967 rn = route_node_get (table, p);
1968 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00001969 {
1970 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1971 continue;
1972
1973 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1974 break;
1975 }
paul718e3742002-12-13 20:15:29 +00001976
1977 if (rib)
1978 {
1979 /* Same distance static route is there. Update it with new
1980 nexthop. */
paul718e3742002-12-13 20:15:29 +00001981 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001982 switch (si->type)
paul7021c422003-07-15 12:52:22 +00001983 {
1984 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00001985 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00001986 break;
1987 case STATIC_IPV4_IFNAME:
1988 nexthop_ifname_add (rib, si->gate.ifname);
1989 break;
1990 case STATIC_IPV4_BLACKHOLE:
1991 nexthop_blackhole_add (rib);
1992 break;
paul4d38fdb2005-04-28 17:35:14 +00001993 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00001994 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001995 }
1996 else
1997 {
1998 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00001999 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2000
paul718e3742002-12-13 20:15:29 +00002001 rib->type = ZEBRA_ROUTE_STATIC;
2002 rib->distance = si->distance;
2003 rib->metric = 0;
2004 rib->nexthop_num = 0;
2005
2006 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002007 {
2008 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002009 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002010 break;
2011 case STATIC_IPV4_IFNAME:
2012 nexthop_ifname_add (rib, si->gate.ifname);
2013 break;
2014 case STATIC_IPV4_BLACKHOLE:
2015 nexthop_blackhole_add (rib);
2016 break;
2017 }
paul718e3742002-12-13 20:15:29 +00002018
hasso81dfcaa2003-05-25 19:21:25 +00002019 /* Save the flags of this static routes (reject, blackhole) */
2020 rib->flags = si->flags;
2021
paul718e3742002-12-13 20:15:29 +00002022 /* Link this rib to the tree. */
2023 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002024 }
2025}
2026
paula1ac18c2005-06-28 17:17:12 +00002027static int
paul718e3742002-12-13 20:15:29 +00002028static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2029{
2030 if (nexthop->type == NEXTHOP_TYPE_IPV4
2031 && si->type == STATIC_IPV4_GATEWAY
2032 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2033 return 1;
2034 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2035 && si->type == STATIC_IPV4_IFNAME
2036 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2037 return 1;
paul595db7f2003-05-25 21:35:06 +00002038 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2039 && si->type == STATIC_IPV4_BLACKHOLE)
2040 return 1;
paule8e19462006-01-19 20:16:55 +00002041 return 0;
paul718e3742002-12-13 20:15:29 +00002042}
2043
2044/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002045static void
paul718e3742002-12-13 20:15:29 +00002046static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
2047{
2048 struct route_node *rn;
2049 struct rib *rib;
2050 struct nexthop *nexthop;
2051 struct route_table *table;
2052
2053 /* Lookup table. */
2054 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2055 if (! table)
2056 return;
paul4d38fdb2005-04-28 17:35:14 +00002057
paul718e3742002-12-13 20:15:29 +00002058 /* Lookup existing route with type and distance. */
2059 rn = route_node_lookup (table, p);
2060 if (! rn)
2061 return;
2062
2063 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002064 {
2065 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2066 continue;
2067
2068 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2069 break;
2070 }
paul718e3742002-12-13 20:15:29 +00002071
2072 if (! rib)
2073 {
2074 route_unlock_node (rn);
2075 return;
2076 }
2077
2078 /* Lookup nexthop. */
2079 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2080 if (static_ipv4_nexthop_same (nexthop, si))
2081 break;
2082
2083 /* Can't find nexthop. */
2084 if (! nexthop)
2085 {
2086 route_unlock_node (rn);
2087 return;
2088 }
2089
2090 /* Check nexthop. */
2091 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002092 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002093 else
2094 {
paul6baeb982003-10-28 03:47:15 +00002095 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2096 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002097 nexthop_delete (rib, nexthop);
2098 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002099 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002100 }
paul718e3742002-12-13 20:15:29 +00002101 /* Unlock node. */
2102 route_unlock_node (rn);
2103}
2104
2105/* Add static route into static route configuration. */
2106int
hasso39db97e2004-10-12 20:50:58 +00002107static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00002108 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002109{
2110 u_char type = 0;
2111 struct route_node *rn;
2112 struct static_ipv4 *si;
2113 struct static_ipv4 *pp;
2114 struct static_ipv4 *cp;
2115 struct static_ipv4 *update = NULL;
2116 struct route_table *stable;
2117
2118 /* Lookup table. */
2119 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2120 if (! stable)
2121 return -1;
2122
2123 /* Lookup static route prefix. */
2124 rn = route_node_get (stable, p);
2125
2126 /* Make flags. */
2127 if (gate)
2128 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002129 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002130 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002131 else
2132 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002133
2134 /* Do nothing if there is a same static route. */
2135 for (si = rn->info; si; si = si->next)
2136 {
2137 if (type == si->type
2138 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2139 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2140 {
2141 if (distance == si->distance)
2142 {
2143 route_unlock_node (rn);
2144 return 0;
2145 }
2146 else
2147 update = si;
2148 }
2149 }
2150
Paul Jakma3c0755d2006-12-08 00:53:14 +00002151 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002152 if (update)
2153 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
2154
2155 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002156 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
paul718e3742002-12-13 20:15:29 +00002157
2158 si->type = type;
2159 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002160 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002161
2162 if (gate)
2163 si->gate.ipv4 = *gate;
2164 if (ifname)
2165 si->gate.ifname = XSTRDUP (0, ifname);
2166
2167 /* Add new static route information to the tree with sort by
2168 distance value and gateway address. */
2169 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2170 {
2171 if (si->distance < cp->distance)
2172 break;
2173 if (si->distance > cp->distance)
2174 continue;
2175 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2176 {
2177 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2178 break;
2179 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2180 continue;
2181 }
2182 }
2183
2184 /* Make linked list. */
2185 if (pp)
2186 pp->next = si;
2187 else
2188 rn->info = si;
2189 if (cp)
2190 cp->prev = si;
2191 si->prev = pp;
2192 si->next = cp;
2193
2194 /* Install into rib. */
2195 static_install_ipv4 (p, si);
2196
2197 return 1;
2198}
2199
2200/* Delete static route from static route configuration. */
2201int
hasso39db97e2004-10-12 20:50:58 +00002202static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00002203 u_char distance, u_int32_t vrf_id)
2204{
2205 u_char type = 0;
2206 struct route_node *rn;
2207 struct static_ipv4 *si;
2208 struct route_table *stable;
2209
2210 /* Lookup table. */
2211 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2212 if (! stable)
2213 return -1;
2214
2215 /* Lookup static route prefix. */
2216 rn = route_node_lookup (stable, p);
2217 if (! rn)
2218 return 0;
2219
2220 /* Make flags. */
2221 if (gate)
2222 type = STATIC_IPV4_GATEWAY;
2223 else if (ifname)
2224 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002225 else
2226 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002227
2228 /* Find same static route is the tree */
2229 for (si = rn->info; si; si = si->next)
2230 if (type == si->type
2231 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2232 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2233 break;
2234
2235 /* Can't find static route. */
2236 if (! si)
2237 {
2238 route_unlock_node (rn);
2239 return 0;
2240 }
2241
2242 /* Install into rib. */
2243 static_uninstall_ipv4 (p, si);
2244
2245 /* Unlink static route from linked list. */
2246 if (si->prev)
2247 si->prev->next = si->next;
2248 else
2249 rn->info = si->next;
2250 if (si->next)
2251 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002252 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002253
2254 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002255 if (ifname)
2256 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002257 XFREE (MTYPE_STATIC_IPV4, si);
2258
paul143a3852003-09-29 20:06:13 +00002259 route_unlock_node (rn);
2260
paul718e3742002-12-13 20:15:29 +00002261 return 1;
2262}
2263
2264
2265#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00002266static int
paul718e3742002-12-13 20:15:29 +00002267rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2268 struct in6_addr *gate, unsigned int ifindex, int table)
2269{
hasso726f9b22003-05-25 21:04:54 +00002270 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2271#if defined (MUSICA) || defined (LINUX)
2272 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2273 if (p->prefixlen == 96)
2274 return 0;
2275#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00002276 return 1;
hasso726f9b22003-05-25 21:04:54 +00002277 }
paul718e3742002-12-13 20:15:29 +00002278 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
2279 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
2280 {
2281 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
2282 return 1;
2283 }
2284 return 0;
2285}
2286
2287int
2288rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00002289 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
2290 u_int32_t metric, u_char distance)
paul718e3742002-12-13 20:15:29 +00002291{
2292 struct rib *rib;
2293 struct rib *same = NULL;
2294 struct route_table *table;
2295 struct route_node *rn;
2296 struct nexthop *nexthop;
2297
paul718e3742002-12-13 20:15:29 +00002298 /* Lookup table. */
2299 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2300 if (! table)
2301 return 0;
2302
2303 /* Make sure mask is applied. */
2304 apply_mask_ipv6 (p);
2305
2306 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002307 if (!distance)
2308 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002309
2310 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2311 distance = 200;
2312
2313 /* Filter bogus route. */
2314 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
2315 return 0;
2316
2317 /* Lookup route node.*/
2318 rn = route_node_get (table, (struct prefix *) p);
2319
2320 /* If same type of route are installed, treat it as a implicit
2321 withdraw. */
2322 for (rib = rn->info; rib; rib = rib->next)
2323 {
Paul Jakma6d691122006-07-27 21:49:00 +00002324 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2325 continue;
2326
hassoebf1ead2005-09-21 14:58:20 +00002327 if (rib->type != type)
2328 continue;
2329 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002330 {
2331 same = rib;
paul718e3742002-12-13 20:15:29 +00002332 break;
2333 }
hassoebf1ead2005-09-21 14:58:20 +00002334 else if ((nexthop = rib->nexthop) &&
2335 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2336 nexthop->ifindex == ifindex)
2337 {
2338 rib->refcnt++;
2339 return 0;
2340 }
paul718e3742002-12-13 20:15:29 +00002341 }
2342
2343 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002344 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2345
paul718e3742002-12-13 20:15:29 +00002346 rib->type = type;
2347 rib->distance = distance;
2348 rib->flags = flags;
2349 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00002350 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00002351 rib->nexthop_num = 0;
2352 rib->uptime = time (NULL);
2353
2354 /* Nexthop settings. */
2355 if (gate)
2356 {
2357 if (ifindex)
2358 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2359 else
2360 nexthop_ipv6_add (rib, gate);
2361 }
2362 else
2363 nexthop_ifindex_add (rib, ifindex);
2364
2365 /* If this route is kernel route, set FIB flag to the route. */
2366 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2367 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2368 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2369
2370 /* Link new rib to node.*/
2371 rib_addnode (rn, rib);
2372
paul718e3742002-12-13 20:15:29 +00002373 /* Free implicit route.*/
2374 if (same)
paul4d38fdb2005-04-28 17:35:14 +00002375 rib_delnode (rn, same);
2376
2377 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002378 return 0;
2379}
2380
hassoebf1ead2005-09-21 14:58:20 +00002381/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002382int
2383rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
2384 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
2385{
2386 struct route_table *table;
2387 struct route_node *rn;
2388 struct rib *rib;
2389 struct rib *fib = NULL;
2390 struct rib *same = NULL;
2391 struct nexthop *nexthop;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002392 char buf1[INET6_ADDRSTRLEN];
2393 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002394
2395 /* Apply mask. */
2396 apply_mask_ipv6 (p);
2397
2398 /* Lookup table. */
2399 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2400 if (! table)
2401 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002402
paul718e3742002-12-13 20:15:29 +00002403 /* Lookup route node. */
2404 rn = route_node_lookup (table, (struct prefix *) p);
2405 if (! rn)
2406 {
2407 if (IS_ZEBRA_DEBUG_KERNEL)
2408 {
2409 if (gate)
ajsb6178002004-12-07 21:12:56 +00002410 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002411 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002412 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002413 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002414 ifindex);
2415 else
ajsb6178002004-12-07 21:12:56 +00002416 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002417 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002418 p->prefixlen,
2419 ifindex);
2420 }
2421 return ZEBRA_ERR_RTNOEXIST;
2422 }
2423
2424 /* Lookup same type route. */
2425 for (rib = rn->info; rib; rib = rib->next)
2426 {
Paul Jakma6d691122006-07-27 21:49:00 +00002427 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2428 continue;
2429
paul718e3742002-12-13 20:15:29 +00002430 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2431 fib = rib;
2432
hassoebf1ead2005-09-21 14:58:20 +00002433 if (rib->type != type)
2434 continue;
2435 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002436 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002437 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002438 if (nexthop->ifindex != ifindex)
2439 continue;
hassoebf1ead2005-09-21 14:58:20 +00002440 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002441 {
hassoebf1ead2005-09-21 14:58:20 +00002442 rib->refcnt--;
2443 route_unlock_node (rn);
2444 route_unlock_node (rn);
2445 return 0;
paul718e3742002-12-13 20:15:29 +00002446 }
hassoebf1ead2005-09-21 14:58:20 +00002447 same = rib;
2448 break;
paul718e3742002-12-13 20:15:29 +00002449 }
hassoebf1ead2005-09-21 14:58:20 +00002450 /* Make sure that the route found has the same gateway. */
2451 else if (gate == NULL ||
2452 ((nexthop = rib->nexthop) &&
2453 (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate) ||
2454 IPV6_ADDR_SAME (&nexthop->rgate.ipv6, gate))))
paul718e3742002-12-13 20:15:29 +00002455 {
hassoebf1ead2005-09-21 14:58:20 +00002456 same = rib;
2457 break;
paul718e3742002-12-13 20:15:29 +00002458 }
2459 }
2460
2461 /* If same type of route can't be found and this message is from
2462 kernel. */
2463 if (! same)
2464 {
2465 if (fib && type == ZEBRA_ROUTE_KERNEL)
2466 {
2467 /* Unset flags. */
2468 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2469 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2470
2471 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2472 }
2473 else
2474 {
2475 if (IS_ZEBRA_DEBUG_KERNEL)
2476 {
2477 if (gate)
ajsb6178002004-12-07 21:12:56 +00002478 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002479 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002480 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002481 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002482 ifindex,
2483 type);
2484 else
ajsb6178002004-12-07 21:12:56 +00002485 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002486 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002487 p->prefixlen,
2488 ifindex,
2489 type);
2490 }
2491 route_unlock_node (rn);
2492 return ZEBRA_ERR_RTNOEXIST;
2493 }
2494 }
2495
2496 if (same)
2497 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002498
paul718e3742002-12-13 20:15:29 +00002499 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002500 return 0;
2501}
2502
2503/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002504static void
paul718e3742002-12-13 20:15:29 +00002505static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2506{
2507 struct rib *rib;
2508 struct route_table *table;
2509 struct route_node *rn;
2510
2511 /* Lookup table. */
2512 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2513 if (! table)
2514 return;
2515
2516 /* Lookup existing route */
2517 rn = route_node_get (table, p);
2518 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002519 {
2520 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2521 continue;
2522
2523 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2524 break;
2525 }
paul718e3742002-12-13 20:15:29 +00002526
2527 if (rib)
2528 {
2529 /* Same distance static route is there. Update it with new
2530 nexthop. */
paul718e3742002-12-13 20:15:29 +00002531 route_unlock_node (rn);
2532
2533 switch (si->type)
2534 {
2535 case STATIC_IPV6_GATEWAY:
2536 nexthop_ipv6_add (rib, &si->ipv6);
2537 break;
2538 case STATIC_IPV6_IFNAME:
2539 nexthop_ifname_add (rib, si->ifname);
2540 break;
2541 case STATIC_IPV6_GATEWAY_IFNAME:
2542 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2543 break;
2544 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002545 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002546 }
2547 else
2548 {
2549 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002550 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2551
paul718e3742002-12-13 20:15:29 +00002552 rib->type = ZEBRA_ROUTE_STATIC;
2553 rib->distance = si->distance;
2554 rib->metric = 0;
2555 rib->nexthop_num = 0;
2556
2557 switch (si->type)
2558 {
2559 case STATIC_IPV6_GATEWAY:
2560 nexthop_ipv6_add (rib, &si->ipv6);
2561 break;
2562 case STATIC_IPV6_IFNAME:
2563 nexthop_ifname_add (rib, si->ifname);
2564 break;
2565 case STATIC_IPV6_GATEWAY_IFNAME:
2566 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2567 break;
2568 }
2569
hasso81dfcaa2003-05-25 19:21:25 +00002570 /* Save the flags of this static routes (reject, blackhole) */
2571 rib->flags = si->flags;
2572
paul718e3742002-12-13 20:15:29 +00002573 /* Link this rib to the tree. */
2574 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002575 }
2576}
2577
paula1ac18c2005-06-28 17:17:12 +00002578static int
paul718e3742002-12-13 20:15:29 +00002579static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2580{
2581 if (nexthop->type == NEXTHOP_TYPE_IPV6
2582 && si->type == STATIC_IPV6_GATEWAY
2583 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2584 return 1;
2585 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2586 && si->type == STATIC_IPV6_IFNAME
2587 && strcmp (nexthop->ifname, si->ifname) == 0)
2588 return 1;
2589 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2590 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2591 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2592 && strcmp (nexthop->ifname, si->ifname) == 0)
2593 return 1;
paule8e19462006-01-19 20:16:55 +00002594 return 0;
paul718e3742002-12-13 20:15:29 +00002595}
2596
paula1ac18c2005-06-28 17:17:12 +00002597static void
paul718e3742002-12-13 20:15:29 +00002598static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2599{
2600 struct route_table *table;
2601 struct route_node *rn;
2602 struct rib *rib;
2603 struct nexthop *nexthop;
2604
2605 /* Lookup table. */
2606 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2607 if (! table)
2608 return;
2609
2610 /* Lookup existing route with type and distance. */
2611 rn = route_node_lookup (table, (struct prefix *) p);
2612 if (! rn)
2613 return;
2614
2615 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002616 {
2617 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2618 continue;
2619
2620 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2621 break;
2622 }
2623
paul718e3742002-12-13 20:15:29 +00002624 if (! rib)
2625 {
2626 route_unlock_node (rn);
2627 return;
2628 }
2629
2630 /* Lookup nexthop. */
2631 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2632 if (static_ipv6_nexthop_same (nexthop, si))
2633 break;
2634
2635 /* Can't find nexthop. */
2636 if (! nexthop)
2637 {
2638 route_unlock_node (rn);
2639 return;
2640 }
2641
2642 /* Check nexthop. */
2643 if (rib->nexthop_num == 1)
2644 {
2645 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002646 }
2647 else
2648 {
paul6baeb982003-10-28 03:47:15 +00002649 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2650 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002651 nexthop_delete (rib, nexthop);
2652 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002653 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002654 }
paul718e3742002-12-13 20:15:29 +00002655 /* Unlock node. */
2656 route_unlock_node (rn);
2657}
2658
2659/* Add static route into static route configuration. */
2660int
2661static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002662 const char *ifname, u_char flags, u_char distance,
2663 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002664{
2665 struct route_node *rn;
2666 struct static_ipv6 *si;
2667 struct static_ipv6 *pp;
2668 struct static_ipv6 *cp;
2669 struct route_table *stable;
2670
2671 /* Lookup table. */
2672 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2673 if (! stable)
2674 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00002675
2676 if (!gate &&
2677 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
2678 return -1;
2679
2680 if (!ifname &&
2681 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
2682 return -1;
paul718e3742002-12-13 20:15:29 +00002683
2684 /* Lookup static route prefix. */
2685 rn = route_node_get (stable, p);
2686
2687 /* Do nothing if there is a same static route. */
2688 for (si = rn->info; si; si = si->next)
2689 {
2690 if (distance == si->distance
2691 && type == si->type
2692 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2693 && (! ifname || strcmp (ifname, si->ifname) == 0))
2694 {
2695 route_unlock_node (rn);
2696 return 0;
2697 }
2698 }
2699
2700 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002701 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
paul718e3742002-12-13 20:15:29 +00002702
2703 si->type = type;
2704 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002705 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002706
2707 switch (type)
2708 {
2709 case STATIC_IPV6_GATEWAY:
2710 si->ipv6 = *gate;
2711 break;
2712 case STATIC_IPV6_IFNAME:
2713 si->ifname = XSTRDUP (0, ifname);
2714 break;
2715 case STATIC_IPV6_GATEWAY_IFNAME:
2716 si->ipv6 = *gate;
2717 si->ifname = XSTRDUP (0, ifname);
2718 break;
2719 }
2720
2721 /* Add new static route information to the tree with sort by
2722 distance value and gateway address. */
2723 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2724 {
2725 if (si->distance < cp->distance)
2726 break;
2727 if (si->distance > cp->distance)
2728 continue;
2729 }
2730
2731 /* Make linked list. */
2732 if (pp)
2733 pp->next = si;
2734 else
2735 rn->info = si;
2736 if (cp)
2737 cp->prev = si;
2738 si->prev = pp;
2739 si->next = cp;
2740
2741 /* Install into rib. */
2742 static_install_ipv6 (p, si);
2743
2744 return 1;
2745}
2746
2747/* Delete static route from static route configuration. */
2748int
2749static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002750 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002751{
2752 struct route_node *rn;
2753 struct static_ipv6 *si;
2754 struct route_table *stable;
2755
2756 /* Lookup table. */
2757 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2758 if (! stable)
2759 return -1;
2760
2761 /* Lookup static route prefix. */
2762 rn = route_node_lookup (stable, p);
2763 if (! rn)
2764 return 0;
2765
2766 /* Find same static route is the tree */
2767 for (si = rn->info; si; si = si->next)
2768 if (distance == si->distance
2769 && type == si->type
2770 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2771 && (! ifname || strcmp (ifname, si->ifname) == 0))
2772 break;
2773
2774 /* Can't find static route. */
2775 if (! si)
2776 {
2777 route_unlock_node (rn);
2778 return 0;
2779 }
2780
2781 /* Install into rib. */
2782 static_uninstall_ipv6 (p, si);
2783
2784 /* Unlink static route from linked list. */
2785 if (si->prev)
2786 si->prev->next = si->next;
2787 else
2788 rn->info = si->next;
2789 if (si->next)
2790 si->next->prev = si->prev;
2791
2792 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002793 if (ifname)
2794 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00002795 XFREE (MTYPE_STATIC_IPV6, si);
2796
2797 return 1;
2798}
2799#endif /* HAVE_IPV6 */
2800
2801/* RIB update function. */
2802void
paula1ac18c2005-06-28 17:17:12 +00002803rib_update (void)
paul718e3742002-12-13 20:15:29 +00002804{
2805 struct route_node *rn;
2806 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00002807
paul718e3742002-12-13 20:15:29 +00002808 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2809 if (table)
2810 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002811 if (rn->info)
Paul Jakma6d691122006-07-27 21:49:00 +00002812 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002813
2814 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2815 if (table)
2816 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002817 if (rn->info)
Paul Jakma6d691122006-07-27 21:49:00 +00002818 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002819}
2820
paul718e3742002-12-13 20:15:29 +00002821
2822/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00002823static void
paul718e3742002-12-13 20:15:29 +00002824rib_weed_table (struct route_table *table)
2825{
2826 struct route_node *rn;
2827 struct rib *rib;
2828 struct rib *next;
2829
2830 if (table)
2831 for (rn = route_top (table); rn; rn = route_next (rn))
2832 for (rib = rn->info; rib; rib = next)
2833 {
2834 next = rib->next;
2835
Paul Jakma6d691122006-07-27 21:49:00 +00002836 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2837 continue;
2838
paulb21b19c2003-06-15 01:28:29 +00002839 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00002840 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00002841 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002842 }
2843}
2844
2845/* Delete all routes from non main table. */
2846void
paula1ac18c2005-06-28 17:17:12 +00002847rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00002848{
2849 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2850 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2851}
2852
2853/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00002854static void
paul718e3742002-12-13 20:15:29 +00002855rib_sweep_table (struct route_table *table)
2856{
2857 struct route_node *rn;
2858 struct rib *rib;
2859 struct rib *next;
2860 int ret = 0;
2861
2862 if (table)
2863 for (rn = route_top (table); rn; rn = route_next (rn))
2864 for (rib = rn->info; rib; rib = next)
2865 {
2866 next = rib->next;
2867
Paul Jakma6d691122006-07-27 21:49:00 +00002868 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2869 continue;
2870
paul718e3742002-12-13 20:15:29 +00002871 if (rib->type == ZEBRA_ROUTE_KERNEL &&
2872 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
2873 {
2874 ret = rib_uninstall_kernel (rn, rib);
2875 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00002876 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002877 }
2878 }
2879}
2880
2881/* Sweep all RIB tables. */
2882void
paula1ac18c2005-06-28 17:17:12 +00002883rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00002884{
2885 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2886 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2887}
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04002888
2889/* Remove specific by protocol routes from 'table'. */
2890static unsigned long
2891rib_score_proto_table (u_char proto, struct route_table *table)
2892{
2893 struct route_node *rn;
2894 struct rib *rib;
2895 struct rib *next;
2896 unsigned long n = 0;
2897
2898 if (table)
2899 for (rn = route_top (table); rn; rn = route_next (rn))
2900 for (rib = rn->info; rib; rib = next)
2901 {
2902 next = rib->next;
2903 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2904 continue;
2905 if (rib->type == proto)
2906 {
2907 rib_delnode (rn, rib);
2908 n++;
2909 }
2910 }
2911
2912 return n;
2913}
2914
2915/* Remove specific by protocol routes. */
2916unsigned long
2917rib_score_proto (u_char proto)
2918{
2919 return rib_score_proto_table (proto, vrf_table (AFI_IP, SAFI_UNICAST, 0))
2920 +rib_score_proto_table (proto, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2921}
2922
paul718e3742002-12-13 20:15:29 +00002923/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00002924static void
paul718e3742002-12-13 20:15:29 +00002925rib_close_table (struct route_table *table)
2926{
2927 struct route_node *rn;
2928 struct rib *rib;
2929
2930 if (table)
2931 for (rn = route_top (table); rn; rn = route_next (rn))
2932 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002933 {
2934 if (! RIB_SYSTEM_ROUTE (rib)
2935 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2936 rib_uninstall_kernel (rn, rib);
2937 }
paul718e3742002-12-13 20:15:29 +00002938}
2939
2940/* Close all RIB tables. */
2941void
paula1ac18c2005-06-28 17:17:12 +00002942rib_close (void)
paul718e3742002-12-13 20:15:29 +00002943{
2944 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2945 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2946}
2947
2948/* Routing information base initialize. */
2949void
paula1ac18c2005-06-28 17:17:12 +00002950rib_init (void)
paul718e3742002-12-13 20:15:29 +00002951{
paul4d38fdb2005-04-28 17:35:14 +00002952 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00002953 /* VRF initialization. */
2954 vrf_init ();
2955}