blob: f7f4d0a21543349216e7c20e63f84d6463127aff [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;
Paul Jakma57345092011-12-25 17:52:09 +010058} route_info[ZEBRA_ROUTE_MAX] =
paul718e3742002-12-13 20:15:29 +000059{
Paul Jakma57345092011-12-25 17:52:09 +010060 [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0},
61 [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0},
62 [ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0},
63 [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1},
64 [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120},
65 [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120},
66 [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110},
67 [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110},
68 [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115},
69 [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */},
70 [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 95},
David Lamparter7052f222009-08-27 00:28:28 +020071 /* no entry/default: 150 */
paul718e3742002-12-13 20:15:29 +000072};
73
74/* Vector for routing table. */
Stephen Hemmingerd145bc02008-08-17 17:41:37 +010075static vector vrf_vector;
paul718e3742002-12-13 20:15:29 +000076
77/* Allocate new VRF. */
paula1ac18c2005-06-28 17:17:12 +000078static struct vrf *
hassofce954f2004-10-07 20:29:24 +000079vrf_alloc (const char *name)
paul718e3742002-12-13 20:15:29 +000080{
81 struct vrf *vrf;
82
83 vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
84
85 /* Put name. */
86 if (name)
87 vrf->name = XSTRDUP (MTYPE_VRF_NAME, name);
88
89 /* Allocate routing table and static table. */
90 vrf->table[AFI_IP][SAFI_UNICAST] = route_table_init ();
91 vrf->table[AFI_IP6][SAFI_UNICAST] = route_table_init ();
92 vrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
93 vrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
G.Balajicddf3912011-11-26 21:59:32 +040094 vrf->table[AFI_IP][SAFI_MULTICAST] = route_table_init ();
95 vrf->table[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
96 vrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
97 vrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
98
paul718e3742002-12-13 20:15:29 +000099
100 return vrf;
101}
102
paul718e3742002-12-13 20:15:29 +0000103/* Lookup VRF by identifier. */
104struct vrf *
105vrf_lookup (u_int32_t id)
106{
107 return vector_lookup (vrf_vector, id);
108}
109
paul718e3742002-12-13 20:15:29 +0000110/* Initialize VRF. */
paula1ac18c2005-06-28 17:17:12 +0000111static void
112vrf_init (void)
paul718e3742002-12-13 20:15:29 +0000113{
114 struct vrf *default_table;
115
116 /* Allocate VRF vector. */
117 vrf_vector = vector_init (1);
118
119 /* Allocate default main table. */
120 default_table = vrf_alloc ("Default-IP-Routing-Table");
121
122 /* Default table index must be 0. */
123 vector_set_index (vrf_vector, 0, default_table);
124}
125
126/* Lookup route table. */
127struct route_table *
128vrf_table (afi_t afi, safi_t safi, u_int32_t id)
129{
130 struct vrf *vrf;
131
132 vrf = vrf_lookup (id);
133 if (! vrf)
134 return NULL;
135
136 return vrf->table[afi][safi];
137}
138
139/* Lookup static route table. */
140struct route_table *
141vrf_static_table (afi_t afi, safi_t safi, u_int32_t id)
142{
143 struct vrf *vrf;
144
145 vrf = vrf_lookup (id);
146 if (! vrf)
147 return NULL;
148
149 return vrf->stable[afi][safi];
150}
151
152/* Add nexthop to the end of the list. */
paula1ac18c2005-06-28 17:17:12 +0000153static void
paul718e3742002-12-13 20:15:29 +0000154nexthop_add (struct rib *rib, struct nexthop *nexthop)
155{
156 struct nexthop *last;
157
158 for (last = rib->nexthop; last && last->next; last = last->next)
159 ;
160 if (last)
161 last->next = nexthop;
162 else
163 rib->nexthop = nexthop;
164 nexthop->prev = last;
165
166 rib->nexthop_num++;
167}
168
169/* Delete specified nexthop from the list. */
paula1ac18c2005-06-28 17:17:12 +0000170static void
paul718e3742002-12-13 20:15:29 +0000171nexthop_delete (struct rib *rib, struct nexthop *nexthop)
172{
173 if (nexthop->next)
174 nexthop->next->prev = nexthop->prev;
175 if (nexthop->prev)
176 nexthop->prev->next = nexthop->next;
177 else
178 rib->nexthop = nexthop->next;
179 rib->nexthop_num--;
180}
181
182/* Free nexthop. */
paula1ac18c2005-06-28 17:17:12 +0000183static void
paul718e3742002-12-13 20:15:29 +0000184nexthop_free (struct nexthop *nexthop)
185{
paula4b70762003-05-16 17:19:48 +0000186 if (nexthop->ifname)
187 XFREE (0, nexthop->ifname);
paul718e3742002-12-13 20:15:29 +0000188 XFREE (MTYPE_NEXTHOP, nexthop);
189}
190
191struct nexthop *
192nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
193{
194 struct nexthop *nexthop;
195
Stephen Hemminger393deb92008-08-18 14:13:29 -0700196 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000197 nexthop->type = NEXTHOP_TYPE_IFINDEX;
198 nexthop->ifindex = ifindex;
199
200 nexthop_add (rib, nexthop);
201
202 return nexthop;
203}
204
205struct nexthop *
206nexthop_ifname_add (struct rib *rib, char *ifname)
207{
208 struct nexthop *nexthop;
209
Stephen Hemminger393deb92008-08-18 14:13:29 -0700210 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000211 nexthop->type = NEXTHOP_TYPE_IFNAME;
paula4b70762003-05-16 17:19:48 +0000212 nexthop->ifname = XSTRDUP (0, ifname);
paul718e3742002-12-13 20:15:29 +0000213
214 nexthop_add (rib, nexthop);
215
216 return nexthop;
217}
218
219struct nexthop *
Paul Jakma7514fb72007-05-02 16:05:35 +0000220nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src)
paul718e3742002-12-13 20:15:29 +0000221{
222 struct nexthop *nexthop;
223
Stephen Hemminger393deb92008-08-18 14:13:29 -0700224 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000225 nexthop->type = NEXTHOP_TYPE_IPV4;
226 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000227 if (src)
228 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000229
230 nexthop_add (rib, nexthop);
231
232 return nexthop;
233}
234
paula1ac18c2005-06-28 17:17:12 +0000235static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000236nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
Paul Jakma7514fb72007-05-02 16:05:35 +0000237 struct in_addr *src, unsigned int ifindex)
paul718e3742002-12-13 20:15:29 +0000238{
239 struct nexthop *nexthop;
240
Stephen Hemminger393deb92008-08-18 14:13:29 -0700241 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000242 nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
243 nexthop->gate.ipv4 = *ipv4;
Paul Jakma7514fb72007-05-02 16:05:35 +0000244 if (src)
245 nexthop->src.ipv4 = *src;
paul718e3742002-12-13 20:15:29 +0000246 nexthop->ifindex = ifindex;
247
248 nexthop_add (rib, nexthop);
249
250 return nexthop;
251}
252
253#ifdef HAVE_IPV6
254struct nexthop *
255nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
256{
257 struct nexthop *nexthop;
258
Stephen Hemminger393deb92008-08-18 14:13:29 -0700259 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000260 nexthop->type = NEXTHOP_TYPE_IPV6;
261 nexthop->gate.ipv6 = *ipv6;
262
263 nexthop_add (rib, nexthop);
264
265 return nexthop;
266}
267
paula1ac18c2005-06-28 17:17:12 +0000268static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000269nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
270 char *ifname)
271{
272 struct nexthop *nexthop;
273
Stephen Hemminger393deb92008-08-18 14:13:29 -0700274 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000275 nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
276 nexthop->gate.ipv6 = *ipv6;
277 nexthop->ifname = XSTRDUP (0, ifname);
278
279 nexthop_add (rib, nexthop);
280
281 return nexthop;
282}
283
paula1ac18c2005-06-28 17:17:12 +0000284static struct nexthop *
paul718e3742002-12-13 20:15:29 +0000285nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
286 unsigned int ifindex)
287{
288 struct nexthop *nexthop;
289
Stephen Hemminger393deb92008-08-18 14:13:29 -0700290 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul718e3742002-12-13 20:15:29 +0000291 nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
292 nexthop->gate.ipv6 = *ipv6;
293 nexthop->ifindex = ifindex;
294
295 nexthop_add (rib, nexthop);
296
297 return nexthop;
298}
299#endif /* HAVE_IPV6 */
300
paul595db7f2003-05-25 21:35:06 +0000301struct nexthop *
302nexthop_blackhole_add (struct rib *rib)
303{
304 struct nexthop *nexthop;
305
Stephen Hemminger393deb92008-08-18 14:13:29 -0700306 nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
paul595db7f2003-05-25 21:35:06 +0000307 nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
308 SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
309
310 nexthop_add (rib, nexthop);
311
312 return nexthop;
313}
314
paul718e3742002-12-13 20:15:29 +0000315/* If force flag is not set, do not modify falgs at all for uninstall
316 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000317static int
paul718e3742002-12-13 20:15:29 +0000318nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
319 struct route_node *top)
320{
321 struct prefix_ipv4 p;
322 struct route_table *table;
323 struct route_node *rn;
324 struct rib *match;
325 struct nexthop *newhop;
326
327 if (nexthop->type == NEXTHOP_TYPE_IPV4)
328 nexthop->ifindex = 0;
329
330 if (set)
331 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
332
333 /* Make lookup prefix. */
334 memset (&p, 0, sizeof (struct prefix_ipv4));
335 p.family = AF_INET;
336 p.prefixlen = IPV4_MAX_PREFIXLEN;
337 p.prefix = nexthop->gate.ipv4;
338
339 /* Lookup table. */
340 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
341 if (! table)
342 return 0;
343
344 rn = route_node_match (table, (struct prefix *) &p);
345 while (rn)
346 {
347 route_unlock_node (rn);
348
David Warda50c1072009-12-03 15:34:39 +0300349 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000350 if (rn == top)
351 return 0;
352
353 /* Pick up selected route. */
354 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100355 {
356 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
357 continue;
358 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
359 break;
360 }
paul718e3742002-12-13 20:15:29 +0000361
362 /* If there is no selected route or matched route is EGP, go up
363 tree. */
364 if (! match
365 || match->type == ZEBRA_ROUTE_BGP)
366 {
367 do {
368 rn = rn->parent;
369 } while (rn && rn->info == NULL);
370 if (rn)
371 route_lock_node (rn);
372 }
373 else
374 {
375 if (match->type == ZEBRA_ROUTE_CONNECT)
376 {
377 /* Directly point connected route. */
378 newhop = match->nexthop;
379 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
380 nexthop->ifindex = newhop->ifindex;
381
382 return 1;
383 }
384 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
385 {
386 for (newhop = match->nexthop; newhop; newhop = newhop->next)
387 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
388 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
389 {
390 if (set)
391 {
392 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
393 nexthop->rtype = newhop->type;
394 if (newhop->type == NEXTHOP_TYPE_IPV4 ||
395 newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
396 nexthop->rgate.ipv4 = newhop->gate.ipv4;
397 if (newhop->type == NEXTHOP_TYPE_IFINDEX
398 || newhop->type == NEXTHOP_TYPE_IFNAME
399 || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
400 nexthop->rifindex = newhop->ifindex;
401 }
402 return 1;
403 }
404 return 0;
405 }
406 else
407 {
408 return 0;
409 }
410 }
411 }
412 return 0;
413}
414
415#ifdef HAVE_IPV6
416/* If force flag is not set, do not modify falgs at all for uninstall
417 the route from FIB. */
paula1ac18c2005-06-28 17:17:12 +0000418static int
paul718e3742002-12-13 20:15:29 +0000419nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
420 struct route_node *top)
421{
422 struct prefix_ipv6 p;
423 struct route_table *table;
424 struct route_node *rn;
425 struct rib *match;
426 struct nexthop *newhop;
427
428 if (nexthop->type == NEXTHOP_TYPE_IPV6)
429 nexthop->ifindex = 0;
430
431 if (set)
432 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
433
434 /* Make lookup prefix. */
435 memset (&p, 0, sizeof (struct prefix_ipv6));
436 p.family = AF_INET6;
437 p.prefixlen = IPV6_MAX_PREFIXLEN;
438 p.prefix = nexthop->gate.ipv6;
439
440 /* Lookup table. */
441 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
442 if (! table)
443 return 0;
444
445 rn = route_node_match (table, (struct prefix *) &p);
446 while (rn)
447 {
448 route_unlock_node (rn);
449
David Warda50c1072009-12-03 15:34:39 +0300450 /* If lookup self prefix return immediately. */
paul718e3742002-12-13 20:15:29 +0000451 if (rn == top)
452 return 0;
453
454 /* Pick up selected route. */
455 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100456 {
457 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
458 continue;
459 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
460 break;
461 }
paul718e3742002-12-13 20:15:29 +0000462
463 /* If there is no selected route or matched route is EGP, go up
464 tree. */
465 if (! match
466 || match->type == ZEBRA_ROUTE_BGP)
467 {
468 do {
469 rn = rn->parent;
470 } while (rn && rn->info == NULL);
471 if (rn)
472 route_lock_node (rn);
473 }
474 else
475 {
476 if (match->type == ZEBRA_ROUTE_CONNECT)
477 {
478 /* Directly point connected route. */
479 newhop = match->nexthop;
480
481 if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
482 nexthop->ifindex = newhop->ifindex;
483
484 return 1;
485 }
486 else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
487 {
488 for (newhop = match->nexthop; newhop; newhop = newhop->next)
489 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
490 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
491 {
492 if (set)
493 {
494 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
495 nexthop->rtype = newhop->type;
496 if (newhop->type == NEXTHOP_TYPE_IPV6
497 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
498 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
499 nexthop->rgate.ipv6 = newhop->gate.ipv6;
500 if (newhop->type == NEXTHOP_TYPE_IFINDEX
501 || newhop->type == NEXTHOP_TYPE_IFNAME
502 || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
503 || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
504 nexthop->rifindex = newhop->ifindex;
505 }
506 return 1;
507 }
508 return 0;
509 }
510 else
511 {
512 return 0;
513 }
514 }
515 }
516 return 0;
517}
518#endif /* HAVE_IPV6 */
519
520struct rib *
521rib_match_ipv4 (struct in_addr addr)
522{
523 struct prefix_ipv4 p;
524 struct route_table *table;
525 struct route_node *rn;
526 struct rib *match;
527 struct nexthop *newhop;
528
529 /* Lookup table. */
530 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
531 if (! table)
532 return 0;
533
534 memset (&p, 0, sizeof (struct prefix_ipv4));
535 p.family = AF_INET;
536 p.prefixlen = IPV4_MAX_PREFIXLEN;
537 p.prefix = addr;
538
539 rn = route_node_match (table, (struct prefix *) &p);
540
541 while (rn)
542 {
543 route_unlock_node (rn);
544
545 /* Pick up selected route. */
546 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100547 {
548 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
549 continue;
550 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
551 break;
552 }
paul718e3742002-12-13 20:15:29 +0000553
554 /* If there is no selected route or matched route is EGP, go up
555 tree. */
556 if (! match
557 || match->type == ZEBRA_ROUTE_BGP)
558 {
559 do {
560 rn = rn->parent;
561 } while (rn && rn->info == NULL);
562 if (rn)
563 route_lock_node (rn);
564 }
565 else
566 {
567 if (match->type == ZEBRA_ROUTE_CONNECT)
568 /* Directly point connected route. */
569 return match;
570 else
571 {
572 for (newhop = match->nexthop; newhop; newhop = newhop->next)
573 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
574 return match;
575 return NULL;
576 }
577 }
578 }
579 return NULL;
580}
581
582struct rib *
583rib_lookup_ipv4 (struct prefix_ipv4 *p)
584{
585 struct route_table *table;
586 struct route_node *rn;
587 struct rib *match;
588 struct nexthop *nexthop;
589
590 /* Lookup table. */
591 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
592 if (! table)
593 return 0;
594
595 rn = route_node_lookup (table, (struct prefix *) p);
596
597 /* No route for this prefix. */
598 if (! rn)
599 return NULL;
600
601 /* Unlock node. */
602 route_unlock_node (rn);
603
paul718e3742002-12-13 20:15:29 +0000604 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100605 {
606 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
607 continue;
608 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
609 break;
610 }
paul718e3742002-12-13 20:15:29 +0000611
612 if (! match || match->type == ZEBRA_ROUTE_BGP)
613 return NULL;
614
615 if (match->type == ZEBRA_ROUTE_CONNECT)
616 return match;
617
618 for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
619 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
620 return match;
621
622 return NULL;
623}
624
Denis Ovsienkodc958242007-08-13 16:03:06 +0000625/*
626 * This clone function, unlike its original rib_lookup_ipv4(), checks
627 * if specified IPv4 route record (prefix/mask -> gate) exists in
628 * the whole RIB and has ZEBRA_FLAG_SELECTED set.
629 *
630 * Return values:
631 * -1: error
632 * 0: exact match found
633 * 1: a match was found with a different gate
634 * 2: connected route found
635 * 3: no matches found
636 */
637int
638rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
639{
640 struct route_table *table;
641 struct route_node *rn;
642 struct rib *match;
643 struct nexthop *nexthop;
644
645 /* Lookup table. */
646 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
647 if (! table)
648 return ZEBRA_RIB_LOOKUP_ERROR;
649
650 /* Scan the RIB table for exactly matching RIB entry. */
651 rn = route_node_lookup (table, (struct prefix *) p);
652
653 /* No route for this prefix. */
654 if (! rn)
655 return ZEBRA_RIB_NOTFOUND;
656
657 /* Unlock node. */
658 route_unlock_node (rn);
659
660 /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
661 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100662 {
663 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
664 continue;
665 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
666 break;
667 }
Denis Ovsienkodc958242007-08-13 16:03:06 +0000668
669 /* None such found :( */
670 if (!match)
671 return ZEBRA_RIB_NOTFOUND;
672
673 if (match->type == ZEBRA_ROUTE_CONNECT)
674 return ZEBRA_RIB_FOUND_CONNECTED;
675
676 /* Ok, we have a cood candidate, let's check it's nexthop list... */
677 for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
678 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
679 {
680 /* We are happy with either direct or recursive hexthop */
681 if (nexthop->gate.ipv4.s_addr == qgate->sin.sin_addr.s_addr ||
682 nexthop->rgate.ipv4.s_addr == qgate->sin.sin_addr.s_addr)
683 return ZEBRA_RIB_FOUND_EXACT;
684 else
685 {
686 if (IS_ZEBRA_DEBUG_RIB)
687 {
688 char gate_buf[INET_ADDRSTRLEN], rgate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
689 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
690 inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, rgate_buf, INET_ADDRSTRLEN);
691 inet_ntop (AF_INET, &qgate->sin.sin_addr.s_addr, qgate_buf, INET_ADDRSTRLEN);
692 zlog_debug ("%s: qgate == %s, gate == %s, rgate == %s", __func__, qgate_buf, gate_buf, rgate_buf);
693 }
694 return ZEBRA_RIB_FOUND_NOGATE;
695 }
696 }
697
698 return ZEBRA_RIB_NOTFOUND;
699}
700
paul718e3742002-12-13 20:15:29 +0000701#ifdef HAVE_IPV6
702struct rib *
703rib_match_ipv6 (struct in6_addr *addr)
704{
705 struct prefix_ipv6 p;
706 struct route_table *table;
707 struct route_node *rn;
708 struct rib *match;
709 struct nexthop *newhop;
710
711 /* Lookup table. */
712 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
713 if (! table)
714 return 0;
715
716 memset (&p, 0, sizeof (struct prefix_ipv6));
717 p.family = AF_INET6;
718 p.prefixlen = IPV6_MAX_PREFIXLEN;
719 IPV6_ADDR_COPY (&p.prefix, addr);
720
721 rn = route_node_match (table, (struct prefix *) &p);
722
723 while (rn)
724 {
725 route_unlock_node (rn);
726
727 /* Pick up selected route. */
728 for (match = rn->info; match; match = match->next)
Stephen Hemminger16814f92008-08-17 17:39:31 +0100729 {
730 if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
731 continue;
732 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
733 break;
734 }
paul718e3742002-12-13 20:15:29 +0000735
736 /* If there is no selected route or matched route is EGP, go up
737 tree. */
738 if (! match
739 || match->type == ZEBRA_ROUTE_BGP)
740 {
741 do {
742 rn = rn->parent;
743 } while (rn && rn->info == NULL);
744 if (rn)
745 route_lock_node (rn);
746 }
747 else
748 {
749 if (match->type == ZEBRA_ROUTE_CONNECT)
750 /* Directly point connected route. */
751 return match;
752 else
753 {
754 for (newhop = match->nexthop; newhop; newhop = newhop->next)
755 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
756 return match;
757 return NULL;
758 }
759 }
760 }
761 return NULL;
762}
763#endif /* HAVE_IPV6 */
764
Paul Jakma7514fb72007-05-02 16:05:35 +0000765#define RIB_SYSTEM_ROUTE(R) \
766 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
767
Denis Ovsienkodc958242007-08-13 16:03:06 +0000768/* This function verifies reachability of one given nexthop, which can be
769 * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
770 * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
771 * nexthop->ifindex will be updated appropriately as well.
772 * An existing route map can turn (otherwise active) nexthop into inactive, but
773 * not vice versa.
774 *
775 * The return value is the final value of 'ACTIVE' flag.
776 */
777
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300778static unsigned
paul718e3742002-12-13 20:15:29 +0000779nexthop_active_check (struct route_node *rn, struct rib *rib,
780 struct nexthop *nexthop, int set)
781{
782 struct interface *ifp;
Paul Jakma7514fb72007-05-02 16:05:35 +0000783 route_map_result_t ret = RMAP_MATCH;
784 extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
785 struct route_map *rmap;
786 int family;
paul718e3742002-12-13 20:15:29 +0000787
Paul Jakma7514fb72007-05-02 16:05:35 +0000788 family = 0;
paul718e3742002-12-13 20:15:29 +0000789 switch (nexthop->type)
790 {
791 case NEXTHOP_TYPE_IFINDEX:
792 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000793 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000794 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
795 else
796 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
797 break;
paul718e3742002-12-13 20:15:29 +0000798 case NEXTHOP_TYPE_IPV6_IFNAME:
Paul Jakma7514fb72007-05-02 16:05:35 +0000799 family = AFI_IP6;
800 case NEXTHOP_TYPE_IFNAME:
paul718e3742002-12-13 20:15:29 +0000801 ifp = if_lookup_by_name (nexthop->ifname);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000802 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000803 {
804 if (set)
805 nexthop->ifindex = ifp->ifindex;
806 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
807 }
808 else
809 {
810 if (set)
811 nexthop->ifindex = 0;
812 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
813 }
814 break;
815 case NEXTHOP_TYPE_IPV4:
816 case NEXTHOP_TYPE_IPV4_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000817 family = AFI_IP;
paul718e3742002-12-13 20:15:29 +0000818 if (nexthop_active_ipv4 (rib, nexthop, set, rn))
819 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
820 else
821 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
822 break;
823#ifdef HAVE_IPV6
824 case NEXTHOP_TYPE_IPV6:
Paul Jakma7514fb72007-05-02 16:05:35 +0000825 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000826 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
827 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
828 else
829 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
830 break;
831 case NEXTHOP_TYPE_IPV6_IFINDEX:
Paul Jakma7514fb72007-05-02 16:05:35 +0000832 family = AFI_IP6;
paul718e3742002-12-13 20:15:29 +0000833 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
834 {
835 ifp = if_lookup_by_index (nexthop->ifindex);
Andrew J. Schorr3f087672008-01-08 20:12:46 +0000836 if (ifp && if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000837 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
838 else
839 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
840 }
841 else
842 {
843 if (nexthop_active_ipv6 (rib, nexthop, set, rn))
844 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
845 else
846 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
847 }
848 break;
849#endif /* HAVE_IPV6 */
paul595db7f2003-05-25 21:35:06 +0000850 case NEXTHOP_TYPE_BLACKHOLE:
851 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
852 break;
paul718e3742002-12-13 20:15:29 +0000853 default:
854 break;
855 }
Paul Jakma7514fb72007-05-02 16:05:35 +0000856 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
857 return 0;
858
859 if (RIB_SYSTEM_ROUTE(rib) ||
860 (family == AFI_IP && rn->p.family != AF_INET) ||
861 (family == AFI_IP6 && rn->p.family != AF_INET6))
862 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
863
864 rmap = 0;
865 if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
866 proto_rm[family][rib->type])
867 rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
868 if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
869 rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
870 if (rmap) {
871 ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, nexthop);
872 }
873
874 if (ret == RMAP_DENYMATCH)
875 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
paul718e3742002-12-13 20:15:29 +0000876 return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
877}
878
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000879/* Iterate over all nexthops of the given RIB entry and refresh their
880 * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
881 * nexthop is found to toggle the ACTIVE flag, the whole rib structure
882 * is flagged with ZEBRA_FLAG_CHANGED. The 4th 'set' argument is
883 * transparently passed to nexthop_active_check().
884 *
885 * Return value is the new number of active nexthops.
886 */
887
paula1ac18c2005-06-28 17:17:12 +0000888static int
paul718e3742002-12-13 20:15:29 +0000889nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
890{
891 struct nexthop *nexthop;
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +0300892 unsigned int prev_active, prev_index, new_active;
paul718e3742002-12-13 20:15:29 +0000893
894 rib->nexthop_active_num = 0;
895 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
896
897 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000898 {
899 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
Joakim Tjernlundc3a56062009-06-24 19:15:36 +0200900 prev_index = nexthop->ifindex;
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000901 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
902 rib->nexthop_active_num++;
Joakim Tjernlundc3a56062009-06-24 19:15:36 +0200903 if (prev_active != new_active ||
904 prev_index != nexthop->ifindex)
Denis Ovsienko03e232a2007-08-14 09:46:48 +0000905 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
906 }
paul718e3742002-12-13 20:15:29 +0000907 return rib->nexthop_active_num;
908}
paul6baeb982003-10-28 03:47:15 +0000909
paul718e3742002-12-13 20:15:29 +0000910
paul718e3742002-12-13 20:15:29 +0000911
paula1ac18c2005-06-28 17:17:12 +0000912static void
paul718e3742002-12-13 20:15:29 +0000913rib_install_kernel (struct route_node *rn, struct rib *rib)
914{
915 int ret = 0;
916 struct nexthop *nexthop;
917
918 switch (PREFIX_FAMILY (&rn->p))
919 {
920 case AF_INET:
921 ret = kernel_add_ipv4 (&rn->p, rib);
922 break;
923#ifdef HAVE_IPV6
924 case AF_INET6:
925 ret = kernel_add_ipv6 (&rn->p, rib);
926 break;
927#endif /* HAVE_IPV6 */
928 }
929
Denis Ovsienkodc958242007-08-13 16:03:06 +0000930 /* This condition is never met, if we are using rt_socket.c */
paul718e3742002-12-13 20:15:29 +0000931 if (ret < 0)
932 {
933 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
934 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
935 }
936}
937
938/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +0000939static int
paul718e3742002-12-13 20:15:29 +0000940rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
941{
942 int ret = 0;
943 struct nexthop *nexthop;
944
945 switch (PREFIX_FAMILY (&rn->p))
946 {
947 case AF_INET:
948 ret = kernel_delete_ipv4 (&rn->p, rib);
949 break;
950#ifdef HAVE_IPV6
951 case AF_INET6:
952 ret = kernel_delete_ipv6 (&rn->p, rib);
953 break;
954#endif /* HAVE_IPV6 */
955 }
956
957 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
958 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
959
960 return ret;
961}
962
963/* Uninstall the route from kernel. */
paula1ac18c2005-06-28 17:17:12 +0000964static void
paul718e3742002-12-13 20:15:29 +0000965rib_uninstall (struct route_node *rn, struct rib *rib)
966{
967 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
968 {
969 redistribute_delete (&rn->p, rib);
970 if (! RIB_SYSTEM_ROUTE (rib))
971 rib_uninstall_kernel (rn, rib);
972 UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
973 }
974}
975
Paul Jakma6d691122006-07-27 21:49:00 +0000976static void rib_unlink (struct route_node *, struct rib *);
977
paul718e3742002-12-13 20:15:29 +0000978/* Core function for processing routing information base. */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +0000979static void
980rib_process (struct route_node *rn)
paul718e3742002-12-13 20:15:29 +0000981{
982 struct rib *rib;
983 struct rib *next;
984 struct rib *fib = NULL;
985 struct rib *select = NULL;
Paul Jakma6d691122006-07-27 21:49:00 +0000986 struct rib *del = NULL;
pauld753e9e2003-01-22 19:45:50 +0000987 int installed = 0;
988 struct nexthop *nexthop = NULL;
Denis Ovsienkof304cb42007-10-03 12:27:16 +0000989 char buf[INET6_ADDRSTRLEN];
paul4d38fdb2005-04-28 17:35:14 +0000990
991 assert (rn);
992
Paul Jakma93bdada2007-08-06 19:25:11 +0000993 if (IS_ZEBRA_DEBUG_RIB || IS_ZEBRA_DEBUG_RIB_Q)
Denis Ovsienkof304cb42007-10-03 12:27:16 +0000994 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +0000995
paul718e3742002-12-13 20:15:29 +0000996 for (rib = rn->info; rib; rib = next)
997 {
Denis Ovsienkodc958242007-08-13 16:03:06 +0000998 /* The next pointer is saved, because current pointer
999 * may be passed to rib_unlink() in the middle of iteration.
1000 */
paul718e3742002-12-13 20:15:29 +00001001 next = rib->next;
pauld753e9e2003-01-22 19:45:50 +00001002
paul718e3742002-12-13 20:15:29 +00001003 /* Currently installed rib. */
1004 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Paul Jakma6d691122006-07-27 21:49:00 +00001005 {
1006 assert (fib == NULL);
1007 fib = rib;
1008 }
1009
1010 /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1011 * which we need to do do further work with below.
1012 */
1013 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1014 {
1015 if (rib != fib)
1016 {
1017 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001018 zlog_debug ("%s: %s/%d: rn %p, removing rib %p", __func__,
1019 buf, rn->p.prefixlen, rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001020 rib_unlink (rn, rib);
1021 }
1022 else
1023 del = rib;
1024
1025 continue;
1026 }
paul4d38fdb2005-04-28 17:35:14 +00001027
paul718e3742002-12-13 20:15:29 +00001028 /* Skip unreachable nexthop. */
1029 if (! nexthop_active_update (rn, rib, 0))
paul7021c422003-07-15 12:52:22 +00001030 continue;
paul718e3742002-12-13 20:15:29 +00001031
1032 /* Infinit distance. */
1033 if (rib->distance == DISTANCE_INFINITY)
paul7021c422003-07-15 12:52:22 +00001034 continue;
paul718e3742002-12-13 20:15:29 +00001035
paulaf887b52006-01-18 14:52:52 +00001036 /* Newly selected rib, the common case. */
1037 if (!select)
1038 {
1039 select = rib;
1040 continue;
1041 }
1042
1043 /* filter route selection in following order:
paulaf887b52006-01-18 14:52:52 +00001044 * - connected beats other types
paula8d9c1f2006-01-25 06:31:04 +00001045 * - lower distance beats higher
paulaf887b52006-01-18 14:52:52 +00001046 * - lower metric beats higher for equal distance
1047 * - last, hence oldest, route wins tie break.
1048 */
paula1038a12006-01-30 14:08:51 +00001049
1050 /* Connected routes. Pick the last connected
1051 * route of the set of lowest metric connected routes.
1052 */
paula8d9c1f2006-01-25 06:31:04 +00001053 if (rib->type == ZEBRA_ROUTE_CONNECT)
1054 {
paula1038a12006-01-30 14:08:51 +00001055 if (select->type != ZEBRA_ROUTE_CONNECT
paula8d9c1f2006-01-25 06:31:04 +00001056 || rib->metric <= select->metric)
paula1038a12006-01-30 14:08:51 +00001057 select = rib;
1058 continue;
paula8d9c1f2006-01-25 06:31:04 +00001059 }
1060 else if (select->type == ZEBRA_ROUTE_CONNECT)
1061 continue;
1062
1063 /* higher distance loses */
1064 if (rib->distance > select->distance)
1065 continue;
1066
1067 /* lower wins */
1068 if (rib->distance < select->distance)
1069 {
paulaf887b52006-01-18 14:52:52 +00001070 select = rib;
paula8d9c1f2006-01-25 06:31:04 +00001071 continue;
1072 }
1073
1074 /* metric tie-breaks equal distance */
1075 if (rib->metric <= select->metric)
1076 select = rib;
Denis Ovsienkodc958242007-08-13 16:03:06 +00001077 } /* for (rib = rn->info; rib; rib = next) */
1078
1079 /* After the cycle is finished, the following pointers will be set:
1080 * select --- the winner RIB entry, if any was found, otherwise NULL
1081 * fib --- the SELECTED RIB entry, if any, otherwise NULL
1082 * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1083 * rib --- NULL
1084 */
1085
1086 /* Same RIB entry is selected. Update FIB and finish. */
paul718e3742002-12-13 20:15:29 +00001087 if (select && select == fib)
1088 {
Paul Jakma6d691122006-07-27 21:49:00 +00001089 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001090 zlog_debug ("%s: %s/%d: Updating existing route, select %p, fib %p",
1091 __func__, buf, rn->p.prefixlen, select, fib);
paul718e3742002-12-13 20:15:29 +00001092 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
paul4d38fdb2005-04-28 17:35:14 +00001093 {
1094 redistribute_delete (&rn->p, select);
1095 if (! RIB_SYSTEM_ROUTE (select))
1096 rib_uninstall_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001097
paul4d38fdb2005-04-28 17:35:14 +00001098 /* Set real nexthop. */
1099 nexthop_active_update (rn, select, 1);
paul718e3742002-12-13 20:15:29 +00001100
paul4d38fdb2005-04-28 17:35:14 +00001101 if (! RIB_SYSTEM_ROUTE (select))
1102 rib_install_kernel (rn, select);
1103 redistribute_add (&rn->p, select);
1104 }
pauld753e9e2003-01-22 19:45:50 +00001105 else if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001106 {
1107 /* Housekeeping code to deal with
1108 race conditions in kernel with linux
1109 netlink reporting interface up before IPv4 or IPv6 protocol
1110 is ready to add routes.
1111 This makes sure the routes are IN the kernel.
1112 */
pauld753e9e2003-01-22 19:45:50 +00001113
paul4d38fdb2005-04-28 17:35:14 +00001114 for (nexthop = select->nexthop; nexthop; nexthop = nexthop->next)
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001115 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
paul4d38fdb2005-04-28 17:35:14 +00001116 {
Denis Ovsienkoa3aaf5b2007-10-04 10:49:21 +00001117 installed = 1;
1118 break;
paul4d38fdb2005-04-28 17:35:14 +00001119 }
1120 if (! installed)
1121 rib_install_kernel (rn, select);
1122 }
Paul Jakma6d691122006-07-27 21:49:00 +00001123 goto end;
paul718e3742002-12-13 20:15:29 +00001124 }
1125
Denis Ovsienkodc958242007-08-13 16:03:06 +00001126 /* At this point we either haven't found the best RIB entry or it is
1127 * different from what we currently intend to flag with SELECTED. In both
1128 * cases, if a RIB block is present in FIB, it should be withdrawn.
1129 */
paul718e3742002-12-13 20:15:29 +00001130 if (fib)
1131 {
Paul Jakma6d691122006-07-27 21:49:00 +00001132 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001133 zlog_debug ("%s: %s/%d: Removing existing route, fib %p", __func__,
1134 buf, rn->p.prefixlen, fib);
paul718e3742002-12-13 20:15:29 +00001135 redistribute_delete (&rn->p, fib);
1136 if (! RIB_SYSTEM_ROUTE (fib))
1137 rib_uninstall_kernel (rn, fib);
1138 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1139
1140 /* Set real nexthop. */
1141 nexthop_active_update (rn, fib, 1);
1142 }
1143
Denis Ovsienkodc958242007-08-13 16:03:06 +00001144 /* Regardless of some RIB entry being SELECTED or not before, now we can
1145 * tell, that if a new winner exists, FIB is still not updated with this
1146 * data, but ready to be.
1147 */
paul718e3742002-12-13 20:15:29 +00001148 if (select)
1149 {
Paul Jakma6d691122006-07-27 21:49:00 +00001150 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001151 zlog_debug ("%s: %s/%d: Adding route, select %p", __func__, buf,
1152 rn->p.prefixlen, select);
paul718e3742002-12-13 20:15:29 +00001153 /* Set real nexthop. */
1154 nexthop_active_update (rn, select, 1);
1155
1156 if (! RIB_SYSTEM_ROUTE (select))
paul4d38fdb2005-04-28 17:35:14 +00001157 rib_install_kernel (rn, select);
paul718e3742002-12-13 20:15:29 +00001158 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1159 redistribute_add (&rn->p, select);
1160 }
paul4d38fdb2005-04-28 17:35:14 +00001161
Paul Jakma6d691122006-07-27 21:49:00 +00001162 /* FIB route was removed, should be deleted */
1163 if (del)
1164 {
1165 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001166 zlog_debug ("%s: %s/%d: Deleting fib %p, rn %p", __func__, buf,
1167 rn->p.prefixlen, del, rn);
Paul Jakma6d691122006-07-27 21:49:00 +00001168 rib_unlink (rn, del);
1169 }
paul4d38fdb2005-04-28 17:35:14 +00001170
Paul Jakma6d691122006-07-27 21:49:00 +00001171end:
1172 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma93bdada2007-08-06 19:25:11 +00001173 zlog_debug ("%s: %s/%d: rn %p dequeued", __func__, buf, rn->p.prefixlen, rn);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001174}
1175
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001176/* Take a list of route_node structs and return 1, if there was a record
1177 * picked from it and processed by rib_process(). Don't process more,
1178 * than one RN record; operate only in the specified sub-queue.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001179 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001180static unsigned int
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001181process_subq (struct list * subq, u_char qindex)
1182{
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001183 struct listnode *lnode = listhead (subq);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001184 struct route_node *rnode;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001185
1186 if (!lnode)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001187 return 0;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001188
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001189 rnode = listgetdata (lnode);
1190 rib_process (rnode);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001191
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001192 if (rnode->info) /* The first RIB record is holding the flags bitmask. */
1193 UNSET_FLAG (((struct rib *)rnode->info)->rn_status, RIB_ROUTE_QUEUED(qindex));
Chris Caputo67b94672009-07-18 04:02:26 +00001194#if 0
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001195 else
1196 {
1197 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1198 __func__, rnode, rnode->lock);
1199 zlog_backtrace(LOG_DEBUG);
1200 }
Chris Caputo67b94672009-07-18 04:02:26 +00001201#endif
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001202 route_unlock_node (rnode);
1203 list_delete_node (subq, lnode);
1204 return 1;
1205}
1206
1207/* Dispatch the meta queue by picking, processing and unlocking the next RN from
1208 * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1209 * is pointed to the meta queue structure.
1210 */
1211static wq_item_status
1212meta_queue_process (struct work_queue *dummy, void *data)
1213{
1214 struct meta_queue * mq = data;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001215 unsigned i;
1216
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001217 for (i = 0; i < MQ_SIZE; i++)
1218 if (process_subq (mq->subq[i], i))
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001219 {
1220 mq->size--;
1221 break;
1222 }
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001223 return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1224}
1225
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001226/* Map from rib types to queue type (priority) in meta queue */
1227static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
1228 [ZEBRA_ROUTE_SYSTEM] = 4,
1229 [ZEBRA_ROUTE_KERNEL] = 0,
1230 [ZEBRA_ROUTE_CONNECT] = 0,
1231 [ZEBRA_ROUTE_STATIC] = 1,
1232 [ZEBRA_ROUTE_RIP] = 2,
1233 [ZEBRA_ROUTE_RIPNG] = 2,
1234 [ZEBRA_ROUTE_OSPF] = 2,
1235 [ZEBRA_ROUTE_OSPF6] = 2,
1236 [ZEBRA_ROUTE_ISIS] = 2,
1237 [ZEBRA_ROUTE_BGP] = 3,
1238 [ZEBRA_ROUTE_HSLS] = 4,
Paul Jakma57345092011-12-25 17:52:09 +01001239 [ZEBRA_ROUTE_BABEL] = 2,
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001240};
1241
1242/* Look into the RN and queue it into one or more priority queues,
1243 * increasing the size for each data push done.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001244 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001245static void
1246rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001247{
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001248 struct rib *rib;
1249 char buf[INET6_ADDRSTRLEN];
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001250
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001251 if (IS_ZEBRA_DEBUG_RIB_Q)
1252 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001253
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001254 for (rib = rn->info; rib; rib = rib->next)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001255 {
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001256 u_char qindex = meta_queue_map[rib->type];
1257
1258 /* Invariant: at this point we always have rn->info set. */
1259 if (CHECK_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED(qindex)))
1260 {
1261 if (IS_ZEBRA_DEBUG_RIB_Q)
1262 zlog_debug ("%s: %s/%d: rn %p is already queued in sub-queue %u",
1263 __func__, buf, rn->p.prefixlen, rn, qindex);
1264 continue;
1265 }
1266
1267 SET_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED(qindex));
1268 listnode_add (mq->subq[qindex], rn);
1269 route_lock_node (rn);
1270 mq->size++;
1271
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001272 if (IS_ZEBRA_DEBUG_RIB_Q)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001273 zlog_debug ("%s: %s/%d: queued rn %p into sub-queue %u",
1274 __func__, buf, rn->p.prefixlen, rn, qindex);
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001275 }
paul4d38fdb2005-04-28 17:35:14 +00001276}
1277
Paul Jakma6d691122006-07-27 21:49:00 +00001278/* Add route_node to work queue and schedule processing */
paula1ac18c2005-06-28 17:17:12 +00001279static void
Paul Jakma6d691122006-07-27 21:49:00 +00001280rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
paul4d38fdb2005-04-28 17:35:14 +00001281{
paul4d38fdb2005-04-28 17:35:14 +00001282
Paul Jakma93bdada2007-08-06 19:25:11 +00001283 if (IS_ZEBRA_DEBUG_RIB_Q)
Paul Jakma6d691122006-07-27 21:49:00 +00001284 {
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001285 char buf[INET6_ADDRSTRLEN];
1286
1287 zlog_info ("%s: %s/%d: work queue added", __func__,
1288 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN),
1289 rn->p.prefixlen);
Paul Jakma6d691122006-07-27 21:49:00 +00001290 }
paul4d38fdb2005-04-28 17:35:14 +00001291
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001292 /*
1293 * The RIB queue should normally be either empty or holding the only
1294 * work_queue_item element. In the latter case this element would
1295 * hold a pointer to the meta queue structure, which must be used to
1296 * actually queue the route nodes to process. So create the MQ
1297 * holder, if necessary, then push the work into it in any case.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001298 * This semantics was introduced after 0.99.9 release.
1299 */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001300 if (!zebra->ribq->items->count)
1301 work_queue_add (zebra->ribq, zebra->mq);
1302
1303 rib_meta_queue_add (zebra->mq, rn);
paul4d38fdb2005-04-28 17:35:14 +00001304}
1305
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001306/* Create new meta queue.
1307 A destructor function doesn't seem to be necessary here.
1308 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001309static struct meta_queue *
1310meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001311{
1312 struct meta_queue *new;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001313 unsigned i;
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001314
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001315 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1316 assert(new);
1317
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001318 for (i = 0; i < MQ_SIZE; i++)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001319 {
1320 new->subq[i] = list_new ();
1321 assert(new->subq[i]);
1322 }
1323
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001324 return new;
1325}
1326
paul4d38fdb2005-04-28 17:35:14 +00001327/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001328static void
paul4d38fdb2005-04-28 17:35:14 +00001329rib_queue_init (struct zebra_t *zebra)
1330{
paul4d38fdb2005-04-28 17:35:14 +00001331 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001332 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001333 {
Paul Jakma6d691122006-07-27 21:49:00 +00001334 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001335 return;
1336 }
1337
1338 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001339 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001340 zebra->ribq->spec.errorfunc = NULL;
paul4d38fdb2005-04-28 17:35:14 +00001341 /* XXX: TODO: These should be runtime configurable via vty */
1342 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001343 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001344
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001345 if (!(zebra->mq = meta_queue_new ()))
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001346 zlog_err ("%s: could not initialise meta queue!", __func__);
paul718e3742002-12-13 20:15:29 +00001347}
1348
Paul Jakma6d691122006-07-27 21:49:00 +00001349/* RIB updates are processed via a queue of pointers to route_nodes.
1350 *
1351 * The queue length is bounded by the maximal size of the routing table,
1352 * as a route_node will not be requeued, if already queued.
1353 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001354 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1355 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1356 * and then submit route_node to queue for best-path selection later.
1357 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001358 *
1359 * Deleted RIBs are reaped during best-path selection.
1360 *
1361 * rib_addnode
1362 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001363 * |-------->| | best RIB, if required
1364 * | |
1365 * static_install->|->rib_addqueue...... -> rib_process
1366 * | |
1367 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001368 * |-> set RIB_ENTRY_REMOVE |
1369 * rib_delnode (RIB freed)
1370 *
1371 *
1372 * Queueing state for a route_node is kept in the head RIB entry, this
1373 * state must be preserved as and when the head RIB entry of a
1374 * route_node is changed by rib_unlink / rib_link. A small complication,
1375 * but saves having to allocate a dedicated object for this.
1376 *
1377 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1378 *
1379 * - route_nodes: refcounted by:
1380 * - RIBs attached to route_node:
1381 * - managed by: rib_link/unlink
1382 * - route_node processing queue
1383 * - managed by: rib_addqueue, rib_process.
1384 *
1385 */
1386
paul718e3742002-12-13 20:15:29 +00001387/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001388static void
Paul Jakma6d691122006-07-27 21:49:00 +00001389rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001390{
1391 struct rib *head;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001392 char buf[INET6_ADDRSTRLEN];
paul4d38fdb2005-04-28 17:35:14 +00001393
1394 assert (rib && rn);
1395
Paul Jakma6d691122006-07-27 21:49:00 +00001396 route_lock_node (rn); /* rn route table reference */
1397
1398 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001399 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001400 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001401 zlog_debug ("%s: %s/%d: rn %p, rib %p", __func__,
1402 buf, rn->p.prefixlen, rn, rib);
1403 }
Paul Jakma6d691122006-07-27 21:49:00 +00001404
paul718e3742002-12-13 20:15:29 +00001405 head = rn->info;
1406 if (head)
Paul Jakma6d691122006-07-27 21:49:00 +00001407 {
1408 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001409 zlog_debug ("%s: %s/%d: new head, rn_status copied over", __func__,
1410 buf, rn->p.prefixlen);
Paul Jakma6d691122006-07-27 21:49:00 +00001411 head->prev = rib;
1412 /* Transfer the rn status flags to the new head RIB */
1413 rib->rn_status = head->rn_status;
1414 }
paul718e3742002-12-13 20:15:29 +00001415 rib->next = head;
1416 rn->info = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001417 rib_queue_add (&zebrad, rn);
1418}
1419
1420static void
1421rib_addnode (struct route_node *rn, struct rib *rib)
1422{
1423 /* RIB node has been un-removed before route-node is processed.
1424 * route_node must hence already be on the queue for processing..
1425 */
1426 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1427 {
1428 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001429 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001430 char buf[INET6_ADDRSTRLEN];
1431 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001432 zlog_debug ("%s: %s/%d: rn %p, un-removed rib %p",
1433 __func__, buf, rn->p.prefixlen, rn, rib);
1434 }
Paul Jakma6d691122006-07-27 21:49:00 +00001435 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1436 return;
1437 }
1438 rib_link (rn, rib);
1439}
1440
1441static void
1442rib_unlink (struct route_node *rn, struct rib *rib)
1443{
1444 struct nexthop *nexthop, *next;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001445 char buf[INET6_ADDRSTRLEN];
Paul Jakma6d691122006-07-27 21:49:00 +00001446
1447 assert (rn && rib);
1448
1449 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001450 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001451 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001452 zlog_debug ("%s: %s/%d: rn %p, rib %p",
1453 __func__, buf, rn->p.prefixlen, rn, rib);
1454 }
Paul Jakma6d691122006-07-27 21:49:00 +00001455
1456 if (rib->next)
1457 rib->next->prev = rib->prev;
1458
1459 if (rib->prev)
1460 rib->prev->next = rib->next;
1461 else
1462 {
1463 rn->info = rib->next;
1464
1465 if (rn->info)
1466 {
1467 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001468 zlog_debug ("%s: %s/%d: rn %p, rib %p, new head copy",
1469 __func__, buf, rn->p.prefixlen, rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001470 rib->next->rn_status = rib->rn_status;
1471 }
1472 }
1473
1474 /* free RIB and nexthops */
1475 for (nexthop = rib->nexthop; nexthop; nexthop = next)
1476 {
1477 next = nexthop->next;
1478 nexthop_free (nexthop);
1479 }
1480 XFREE (MTYPE_RIB, rib);
1481
1482 route_unlock_node (rn); /* rn route table reference */
paul718e3742002-12-13 20:15:29 +00001483}
1484
paula1ac18c2005-06-28 17:17:12 +00001485static void
paul718e3742002-12-13 20:15:29 +00001486rib_delnode (struct route_node *rn, struct rib *rib)
1487{
Paul Jakma6d691122006-07-27 21:49:00 +00001488 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001489 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001490 char buf[INET6_ADDRSTRLEN];
1491 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001492 zlog_debug ("%s: %s/%d: rn %p, rib %p, removing", __func__,
1493 buf, rn->p.prefixlen, rn, rib);
1494 }
Paul Jakma6d691122006-07-27 21:49:00 +00001495 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1496 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001497}
1498
1499int
1500rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001501 struct in_addr *gate, struct in_addr *src,
1502 unsigned int ifindex, u_int32_t vrf_id,
G.Balajicddf3912011-11-26 21:59:32 +04001503 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001504{
1505 struct rib *rib;
1506 struct rib *same = NULL;
1507 struct route_table *table;
1508 struct route_node *rn;
1509 struct nexthop *nexthop;
1510
1511 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04001512 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00001513 if (! table)
1514 return 0;
1515
1516 /* Make it sure prefixlen is applied to the prefix. */
1517 apply_mask_ipv4 (p);
1518
1519 /* Set default distance by route type. */
1520 if (distance == 0)
1521 {
David Lamparter7052f222009-08-27 00:28:28 +02001522 if ((unsigned)type >= sizeof(route_info) / sizeof(route_info[0]))
1523 distance = 150;
1524 else
1525 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00001526
1527 /* iBGP distance is 200. */
1528 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1529 distance = 200;
1530 }
1531
1532 /* Lookup route node.*/
1533 rn = route_node_get (table, (struct prefix *) p);
1534
1535 /* If same type of route are installed, treat it as a implicit
1536 withdraw. */
1537 for (rib = rn->info; rib; rib = rib->next)
1538 {
Paul Jakma6d691122006-07-27 21:49:00 +00001539 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1540 continue;
1541
hassoebf1ead2005-09-21 14:58:20 +00001542 if (rib->type != type)
1543 continue;
1544 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001545 {
1546 same = rib;
1547 break;
1548 }
hassoebf1ead2005-09-21 14:58:20 +00001549 /* Duplicate connected route comes in. */
1550 else if ((nexthop = rib->nexthop) &&
1551 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001552 nexthop->ifindex == ifindex &&
1553 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001554 {
1555 rib->refcnt++;
1556 return 0 ;
1557 }
paul718e3742002-12-13 20:15:29 +00001558 }
1559
1560 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001561 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001562 rib->type = type;
1563 rib->distance = distance;
1564 rib->flags = flags;
1565 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001566 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001567 rib->nexthop_num = 0;
1568 rib->uptime = time (NULL);
1569
1570 /* Nexthop settings. */
1571 if (gate)
1572 {
1573 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001574 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001575 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001576 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001577 }
1578 else
1579 nexthop_ifindex_add (rib, ifindex);
1580
1581 /* If this route is kernel route, set FIB flag to the route. */
1582 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1583 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1584 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1585
1586 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001587 if (IS_ZEBRA_DEBUG_RIB)
1588 zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
paul718e3742002-12-13 20:15:29 +00001589 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001590
paul718e3742002-12-13 20:15:29 +00001591 /* Free implicit route.*/
1592 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001593 {
1594 if (IS_ZEBRA_DEBUG_RIB)
1595 zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001596 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001597 }
paul4d38fdb2005-04-28 17:35:14 +00001598
1599 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001600 return 0;
1601}
1602
Denis Ovsienkodc958242007-08-13 16:03:06 +00001603/* This function dumps the contents of a given RIB entry into
1604 * standard debug log. Calling function name and IP prefix in
1605 * question are passed as 1st and 2nd arguments.
1606 */
1607
1608void rib_dump (const char * func, const struct prefix_ipv4 * p, const struct rib * rib)
1609{
1610 char straddr1[INET_ADDRSTRLEN], straddr2[INET_ADDRSTRLEN];
1611 struct nexthop *nexthop;
1612
1613 inet_ntop (AF_INET, &p->prefix, straddr1, INET_ADDRSTRLEN);
1614 zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr1, p->prefixlen);
1615 zlog_debug
1616 (
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001617 "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
Denis Ovsienkodc958242007-08-13 16:03:06 +00001618 func,
1619 rib->refcnt,
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001620 (unsigned long) rib->uptime,
Denis Ovsienkodc958242007-08-13 16:03:06 +00001621 rib->type,
1622 rib->table
1623 );
1624 zlog_debug
1625 (
1626 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1627 func,
1628 rib->metric,
1629 rib->distance,
1630 rib->flags,
1631 rib->status
1632 );
1633 zlog_debug
1634 (
1635 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1636 func,
1637 rib->nexthop_num,
1638 rib->nexthop_active_num,
1639 rib->nexthop_fib_num
1640 );
1641 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1642 {
1643 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, straddr1, INET_ADDRSTRLEN);
1644 inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, straddr2, INET_ADDRSTRLEN);
1645 zlog_debug
1646 (
1647 "%s: NH %s (%s) with flags %s%s%s",
1648 func,
1649 straddr1,
1650 straddr2,
1651 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1652 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1653 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1654 );
1655 }
1656 zlog_debug ("%s: dump complete", func);
1657}
1658
1659/* This is an exported helper to rtm_read() to dump the strange
1660 * RIB entry found by rib_lookup_ipv4_route()
1661 */
1662
1663void rib_lookup_and_dump (struct prefix_ipv4 * p)
1664{
1665 struct route_table *table;
1666 struct route_node *rn;
1667 struct rib *rib;
1668 char prefix_buf[INET_ADDRSTRLEN];
1669
1670 /* Lookup table. */
1671 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1672 if (! table)
1673 {
1674 zlog_err ("%s: vrf_table() returned NULL", __func__);
1675 return;
1676 }
1677
1678 inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
1679 /* Scan the RIB table for exactly matching RIB entry. */
1680 rn = route_node_lookup (table, (struct prefix *) p);
1681
1682 /* No route for this prefix. */
1683 if (! rn)
1684 {
1685 zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
1686 return;
1687 }
1688
1689 /* Unlock node. */
1690 route_unlock_node (rn);
1691
1692 /* let's go */
1693 for (rib = rn->info; rib; rib = rib->next)
1694 {
1695 zlog_debug
1696 (
1697 "%s: rn %p, rib %p: %s, %s",
1698 __func__,
1699 rn,
1700 rib,
1701 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
1702 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
1703 );
1704 rib_dump (__func__, p, rib);
1705 }
1706}
1707
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001708/* Check if requested address assignment will fail due to another
1709 * route being installed by zebra in FIB already. Take necessary
1710 * actions, if needed: remove such a route from FIB and deSELECT
1711 * corresponding RIB entry. Then put affected RN into RIBQ head.
1712 */
1713void rib_lookup_and_pushup (struct prefix_ipv4 * p)
1714{
1715 struct route_table *table;
1716 struct route_node *rn;
1717 struct rib *rib;
1718 unsigned changed = 0;
1719
1720 if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
1721 {
1722 zlog_err ("%s: vrf_table() returned NULL", __func__);
1723 return;
1724 }
1725
1726 /* No matches would be the simplest case. */
1727 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
1728 return;
1729
1730 /* Unlock node. */
1731 route_unlock_node (rn);
1732
1733 /* Check all RIB entries. In case any changes have to be done, requeue
1734 * the RN into RIBQ head. If the routing message about the new connected
1735 * route (generated by the IP address we are going to assign very soon)
1736 * comes before the RIBQ is processed, the new RIB entry will join
1737 * RIBQ record already on head. This is necessary for proper revalidation
1738 * of the rest of the RIB.
1739 */
1740 for (rib = rn->info; rib; rib = rib->next)
1741 {
1742 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
1743 ! RIB_SYSTEM_ROUTE (rib))
1744 {
1745 changed = 1;
1746 if (IS_ZEBRA_DEBUG_RIB)
1747 {
1748 char buf[INET_ADDRSTRLEN];
1749 inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
1750 zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
1751 rib_dump (__func__, (struct prefix_ipv4 *)&rn->p, rib);
1752 }
1753 rib_uninstall (rn, rib);
1754 }
1755 }
1756 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001757 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001758}
1759
paul718e3742002-12-13 20:15:29 +00001760int
G.Balajicddf3912011-11-26 21:59:32 +04001761rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001762{
1763 struct route_table *table;
1764 struct route_node *rn;
1765 struct rib *same;
1766 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00001767
paul718e3742002-12-13 20:15:29 +00001768 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04001769 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00001770 if (! table)
1771 return 0;
G.Balajicddf3912011-11-26 21:59:32 +04001772
paul718e3742002-12-13 20:15:29 +00001773 /* Make it sure prefixlen is applied to the prefix. */
1774 apply_mask_ipv4 (p);
1775
1776 /* Set default distance by route type. */
1777 if (rib->distance == 0)
1778 {
1779 rib->distance = route_info[rib->type].distance;
1780
1781 /* iBGP distance is 200. */
1782 if (rib->type == ZEBRA_ROUTE_BGP
1783 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1784 rib->distance = 200;
1785 }
1786
1787 /* Lookup route node.*/
1788 rn = route_node_get (table, (struct prefix *) p);
1789
1790 /* If same type of route are installed, treat it as a implicit
1791 withdraw. */
1792 for (same = rn->info; same; same = same->next)
1793 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00001794 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00001795 continue;
1796
paul718e3742002-12-13 20:15:29 +00001797 if (same->type == rib->type && same->table == rib->table
1798 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001799 break;
paul718e3742002-12-13 20:15:29 +00001800 }
paul4d38fdb2005-04-28 17:35:14 +00001801
paul718e3742002-12-13 20:15:29 +00001802 /* If this route is kernel route, set FIB flag to the route. */
1803 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
1804 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1805 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1806
1807 /* Link new rib to node.*/
1808 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001809 if (IS_ZEBRA_DEBUG_RIB)
1810 {
1811 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
1812 __func__, rn, rib);
1813 rib_dump (__func__, p, rib);
1814 }
paul718e3742002-12-13 20:15:29 +00001815
paul718e3742002-12-13 20:15:29 +00001816 /* Free implicit route.*/
1817 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001818 {
1819 if (IS_ZEBRA_DEBUG_RIB)
1820 {
1821 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
1822 __func__, rn, same);
1823 rib_dump (__func__, p, same);
1824 }
paul4d38fdb2005-04-28 17:35:14 +00001825 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001826 }
paul4d38fdb2005-04-28 17:35:14 +00001827
1828 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001829 return 0;
1830}
1831
hassoebf1ead2005-09-21 14:58:20 +00001832/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00001833int
1834rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
G.Balajicddf3912011-11-26 21:59:32 +04001835 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001836{
1837 struct route_table *table;
1838 struct route_node *rn;
1839 struct rib *rib;
1840 struct rib *fib = NULL;
1841 struct rib *same = NULL;
1842 struct nexthop *nexthop;
Stephen Hemminger81cce012009-04-28 14:28:00 -07001843 char buf1[INET_ADDRSTRLEN];
1844 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00001845
1846 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04001847 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00001848 if (! table)
1849 return 0;
1850
1851 /* Apply mask. */
1852 apply_mask_ipv4 (p);
1853
paul5ec90d22003-06-19 01:41:37 +00001854 if (IS_ZEBRA_DEBUG_KERNEL && gate)
ajsb6178002004-12-07 21:12:56 +00001855 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001856 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul5ec90d22003-06-19 01:41:37 +00001857 p->prefixlen,
1858 inet_ntoa (*gate),
1859 ifindex);
1860
paul718e3742002-12-13 20:15:29 +00001861 /* Lookup route node. */
1862 rn = route_node_lookup (table, (struct prefix *) p);
1863 if (! rn)
1864 {
1865 if (IS_ZEBRA_DEBUG_KERNEL)
1866 {
1867 if (gate)
ajsb6178002004-12-07 21:12:56 +00001868 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001869 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001870 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07001871 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001872 ifindex);
1873 else
ajsb6178002004-12-07 21:12:56 +00001874 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001875 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001876 p->prefixlen,
1877 ifindex);
1878 }
1879 return ZEBRA_ERR_RTNOEXIST;
1880 }
1881
1882 /* Lookup same type route. */
1883 for (rib = rn->info; rib; rib = rib->next)
1884 {
Paul Jakma6d691122006-07-27 21:49:00 +00001885 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1886 continue;
1887
paul718e3742002-12-13 20:15:29 +00001888 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1889 fib = rib;
1890
hassoebf1ead2005-09-21 14:58:20 +00001891 if (rib->type != type)
1892 continue;
1893 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04001894 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00001895 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04001896 if (nexthop->ifindex != ifindex)
1897 continue;
hassoebf1ead2005-09-21 14:58:20 +00001898 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00001899 {
hassoebf1ead2005-09-21 14:58:20 +00001900 rib->refcnt--;
1901 route_unlock_node (rn);
1902 route_unlock_node (rn);
1903 return 0;
paul718e3742002-12-13 20:15:29 +00001904 }
hassoebf1ead2005-09-21 14:58:20 +00001905 same = rib;
1906 break;
paul718e3742002-12-13 20:15:29 +00001907 }
hassoebf1ead2005-09-21 14:58:20 +00001908 /* Make sure that the route found has the same gateway. */
1909 else if (gate == NULL ||
1910 ((nexthop = rib->nexthop) &&
1911 (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
1912 IPV4_ADDR_SAME (&nexthop->rgate.ipv4, gate))))
paul5ec90d22003-06-19 01:41:37 +00001913 {
hassoebf1ead2005-09-21 14:58:20 +00001914 same = rib;
1915 break;
paul718e3742002-12-13 20:15:29 +00001916 }
1917 }
1918
1919 /* If same type of route can't be found and this message is from
1920 kernel. */
1921 if (! same)
1922 {
1923 if (fib && type == ZEBRA_ROUTE_KERNEL)
1924 {
1925 /* Unset flags. */
1926 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1927 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1928
1929 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1930 }
1931 else
1932 {
1933 if (IS_ZEBRA_DEBUG_KERNEL)
1934 {
1935 if (gate)
ajsb6178002004-12-07 21:12:56 +00001936 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001937 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001938 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07001939 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001940 ifindex,
1941 type);
1942 else
ajsb6178002004-12-07 21:12:56 +00001943 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001944 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001945 p->prefixlen,
1946 ifindex,
1947 type);
1948 }
1949 route_unlock_node (rn);
1950 return ZEBRA_ERR_RTNOEXIST;
1951 }
1952 }
paul4d38fdb2005-04-28 17:35:14 +00001953
paul718e3742002-12-13 20:15:29 +00001954 if (same)
1955 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00001956
paul718e3742002-12-13 20:15:29 +00001957 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001958 return 0;
1959}
1960
1961/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00001962static void
paul718e3742002-12-13 20:15:29 +00001963static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
1964{
1965 struct rib *rib;
1966 struct route_node *rn;
1967 struct route_table *table;
1968
1969 /* Lookup table. */
1970 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1971 if (! table)
1972 return;
1973
1974 /* Lookup existing route */
1975 rn = route_node_get (table, p);
1976 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00001977 {
1978 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1979 continue;
1980
1981 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
1982 break;
1983 }
paul718e3742002-12-13 20:15:29 +00001984
1985 if (rib)
1986 {
1987 /* Same distance static route is there. Update it with new
1988 nexthop. */
paul718e3742002-12-13 20:15:29 +00001989 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001990 switch (si->type)
paul7021c422003-07-15 12:52:22 +00001991 {
1992 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00001993 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00001994 break;
1995 case STATIC_IPV4_IFNAME:
1996 nexthop_ifname_add (rib, si->gate.ifname);
1997 break;
1998 case STATIC_IPV4_BLACKHOLE:
1999 nexthop_blackhole_add (rib);
2000 break;
paul4d38fdb2005-04-28 17:35:14 +00002001 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002002 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002003 }
2004 else
2005 {
2006 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002007 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2008
paul718e3742002-12-13 20:15:29 +00002009 rib->type = ZEBRA_ROUTE_STATIC;
2010 rib->distance = si->distance;
2011 rib->metric = 0;
2012 rib->nexthop_num = 0;
2013
2014 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002015 {
2016 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002017 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002018 break;
2019 case STATIC_IPV4_IFNAME:
2020 nexthop_ifname_add (rib, si->gate.ifname);
2021 break;
2022 case STATIC_IPV4_BLACKHOLE:
2023 nexthop_blackhole_add (rib);
2024 break;
2025 }
paul718e3742002-12-13 20:15:29 +00002026
hasso81dfcaa2003-05-25 19:21:25 +00002027 /* Save the flags of this static routes (reject, blackhole) */
2028 rib->flags = si->flags;
2029
paul718e3742002-12-13 20:15:29 +00002030 /* Link this rib to the tree. */
2031 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002032 }
2033}
2034
paula1ac18c2005-06-28 17:17:12 +00002035static int
paul718e3742002-12-13 20:15:29 +00002036static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2037{
2038 if (nexthop->type == NEXTHOP_TYPE_IPV4
2039 && si->type == STATIC_IPV4_GATEWAY
2040 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2041 return 1;
2042 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2043 && si->type == STATIC_IPV4_IFNAME
2044 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2045 return 1;
paul595db7f2003-05-25 21:35:06 +00002046 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2047 && si->type == STATIC_IPV4_BLACKHOLE)
2048 return 1;
paule8e19462006-01-19 20:16:55 +00002049 return 0;
paul718e3742002-12-13 20:15:29 +00002050}
2051
2052/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002053static void
paul718e3742002-12-13 20:15:29 +00002054static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
2055{
2056 struct route_node *rn;
2057 struct rib *rib;
2058 struct nexthop *nexthop;
2059 struct route_table *table;
2060
2061 /* Lookup table. */
2062 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2063 if (! table)
2064 return;
paul4d38fdb2005-04-28 17:35:14 +00002065
paul718e3742002-12-13 20:15:29 +00002066 /* Lookup existing route with type and distance. */
2067 rn = route_node_lookup (table, p);
2068 if (! rn)
2069 return;
2070
2071 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002072 {
2073 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2074 continue;
2075
2076 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2077 break;
2078 }
paul718e3742002-12-13 20:15:29 +00002079
2080 if (! rib)
2081 {
2082 route_unlock_node (rn);
2083 return;
2084 }
2085
2086 /* Lookup nexthop. */
2087 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2088 if (static_ipv4_nexthop_same (nexthop, si))
2089 break;
2090
2091 /* Can't find nexthop. */
2092 if (! nexthop)
2093 {
2094 route_unlock_node (rn);
2095 return;
2096 }
2097
2098 /* Check nexthop. */
2099 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002100 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002101 else
2102 {
paul6baeb982003-10-28 03:47:15 +00002103 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2104 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002105 nexthop_delete (rib, nexthop);
2106 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002107 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002108 }
paul718e3742002-12-13 20:15:29 +00002109 /* Unlock node. */
2110 route_unlock_node (rn);
2111}
2112
2113/* Add static route into static route configuration. */
2114int
hasso39db97e2004-10-12 20:50:58 +00002115static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00002116 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002117{
2118 u_char type = 0;
2119 struct route_node *rn;
2120 struct static_ipv4 *si;
2121 struct static_ipv4 *pp;
2122 struct static_ipv4 *cp;
2123 struct static_ipv4 *update = NULL;
2124 struct route_table *stable;
2125
2126 /* Lookup table. */
2127 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2128 if (! stable)
2129 return -1;
2130
2131 /* Lookup static route prefix. */
2132 rn = route_node_get (stable, p);
2133
2134 /* Make flags. */
2135 if (gate)
2136 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002137 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002138 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002139 else
2140 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002141
2142 /* Do nothing if there is a same static route. */
2143 for (si = rn->info; si; si = si->next)
2144 {
2145 if (type == si->type
2146 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2147 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2148 {
2149 if (distance == si->distance)
2150 {
2151 route_unlock_node (rn);
2152 return 0;
2153 }
2154 else
2155 update = si;
2156 }
2157 }
2158
Paul Jakma3c0755d2006-12-08 00:53:14 +00002159 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002160 if (update)
2161 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
2162
2163 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002164 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
paul718e3742002-12-13 20:15:29 +00002165
2166 si->type = type;
2167 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002168 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002169
2170 if (gate)
2171 si->gate.ipv4 = *gate;
2172 if (ifname)
2173 si->gate.ifname = XSTRDUP (0, ifname);
2174
2175 /* Add new static route information to the tree with sort by
2176 distance value and gateway address. */
2177 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2178 {
2179 if (si->distance < cp->distance)
2180 break;
2181 if (si->distance > cp->distance)
2182 continue;
2183 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2184 {
2185 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2186 break;
2187 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2188 continue;
2189 }
2190 }
2191
2192 /* Make linked list. */
2193 if (pp)
2194 pp->next = si;
2195 else
2196 rn->info = si;
2197 if (cp)
2198 cp->prev = si;
2199 si->prev = pp;
2200 si->next = cp;
2201
2202 /* Install into rib. */
2203 static_install_ipv4 (p, si);
2204
2205 return 1;
2206}
2207
2208/* Delete static route from static route configuration. */
2209int
hasso39db97e2004-10-12 20:50:58 +00002210static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00002211 u_char distance, u_int32_t vrf_id)
2212{
2213 u_char type = 0;
2214 struct route_node *rn;
2215 struct static_ipv4 *si;
2216 struct route_table *stable;
2217
2218 /* Lookup table. */
2219 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2220 if (! stable)
2221 return -1;
2222
2223 /* Lookup static route prefix. */
2224 rn = route_node_lookup (stable, p);
2225 if (! rn)
2226 return 0;
2227
2228 /* Make flags. */
2229 if (gate)
2230 type = STATIC_IPV4_GATEWAY;
2231 else if (ifname)
2232 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002233 else
2234 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002235
2236 /* Find same static route is the tree */
2237 for (si = rn->info; si; si = si->next)
2238 if (type == si->type
2239 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2240 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2241 break;
2242
2243 /* Can't find static route. */
2244 if (! si)
2245 {
2246 route_unlock_node (rn);
2247 return 0;
2248 }
2249
2250 /* Install into rib. */
2251 static_uninstall_ipv4 (p, si);
2252
2253 /* Unlink static route from linked list. */
2254 if (si->prev)
2255 si->prev->next = si->next;
2256 else
2257 rn->info = si->next;
2258 if (si->next)
2259 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002260 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002261
2262 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002263 if (ifname)
2264 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002265 XFREE (MTYPE_STATIC_IPV4, si);
2266
paul143a3852003-09-29 20:06:13 +00002267 route_unlock_node (rn);
2268
paul718e3742002-12-13 20:15:29 +00002269 return 1;
2270}
2271
2272
2273#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00002274static int
paul718e3742002-12-13 20:15:29 +00002275rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2276 struct in6_addr *gate, unsigned int ifindex, int table)
2277{
hasso726f9b22003-05-25 21:04:54 +00002278 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2279#if defined (MUSICA) || defined (LINUX)
2280 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2281 if (p->prefixlen == 96)
2282 return 0;
2283#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00002284 return 1;
hasso726f9b22003-05-25 21:04:54 +00002285 }
paul718e3742002-12-13 20:15:29 +00002286 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
2287 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
2288 {
2289 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
2290 return 1;
2291 }
2292 return 0;
2293}
2294
2295int
2296rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00002297 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
G.Balajif768f362011-11-26 22:10:39 +04002298 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002299{
2300 struct rib *rib;
2301 struct rib *same = NULL;
2302 struct route_table *table;
2303 struct route_node *rn;
2304 struct nexthop *nexthop;
2305
paul718e3742002-12-13 20:15:29 +00002306 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002307 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002308 if (! table)
2309 return 0;
2310
2311 /* Make sure mask is applied. */
2312 apply_mask_ipv6 (p);
2313
2314 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002315 if (!distance)
2316 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002317
2318 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2319 distance = 200;
2320
2321 /* Filter bogus route. */
2322 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
2323 return 0;
2324
2325 /* Lookup route node.*/
2326 rn = route_node_get (table, (struct prefix *) p);
2327
2328 /* If same type of route are installed, treat it as a implicit
2329 withdraw. */
2330 for (rib = rn->info; rib; rib = rib->next)
2331 {
Paul Jakma6d691122006-07-27 21:49:00 +00002332 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2333 continue;
2334
hassoebf1ead2005-09-21 14:58:20 +00002335 if (rib->type != type)
2336 continue;
2337 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002338 {
2339 same = rib;
paul718e3742002-12-13 20:15:29 +00002340 break;
2341 }
hassoebf1ead2005-09-21 14:58:20 +00002342 else if ((nexthop = rib->nexthop) &&
2343 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2344 nexthop->ifindex == ifindex)
2345 {
2346 rib->refcnt++;
2347 return 0;
2348 }
paul718e3742002-12-13 20:15:29 +00002349 }
2350
2351 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002352 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2353
paul718e3742002-12-13 20:15:29 +00002354 rib->type = type;
2355 rib->distance = distance;
2356 rib->flags = flags;
2357 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00002358 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00002359 rib->nexthop_num = 0;
2360 rib->uptime = time (NULL);
2361
2362 /* Nexthop settings. */
2363 if (gate)
2364 {
2365 if (ifindex)
2366 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2367 else
2368 nexthop_ipv6_add (rib, gate);
2369 }
2370 else
2371 nexthop_ifindex_add (rib, ifindex);
2372
2373 /* If this route is kernel route, set FIB flag to the route. */
2374 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2375 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2376 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2377
2378 /* Link new rib to node.*/
2379 rib_addnode (rn, rib);
2380
paul718e3742002-12-13 20:15:29 +00002381 /* Free implicit route.*/
2382 if (same)
paul4d38fdb2005-04-28 17:35:14 +00002383 rib_delnode (rn, same);
2384
2385 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002386 return 0;
2387}
2388
hassoebf1ead2005-09-21 14:58:20 +00002389/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002390int
2391rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
G.Balajif768f362011-11-26 22:10:39 +04002392 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002393{
2394 struct route_table *table;
2395 struct route_node *rn;
2396 struct rib *rib;
2397 struct rib *fib = NULL;
2398 struct rib *same = NULL;
2399 struct nexthop *nexthop;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002400 char buf1[INET6_ADDRSTRLEN];
2401 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002402
2403 /* Apply mask. */
2404 apply_mask_ipv6 (p);
2405
2406 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002407 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002408 if (! table)
2409 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002410
paul718e3742002-12-13 20:15:29 +00002411 /* Lookup route node. */
2412 rn = route_node_lookup (table, (struct prefix *) p);
2413 if (! rn)
2414 {
2415 if (IS_ZEBRA_DEBUG_KERNEL)
2416 {
2417 if (gate)
ajsb6178002004-12-07 21:12:56 +00002418 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002419 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002420 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002421 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002422 ifindex);
2423 else
ajsb6178002004-12-07 21:12:56 +00002424 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002425 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002426 p->prefixlen,
2427 ifindex);
2428 }
2429 return ZEBRA_ERR_RTNOEXIST;
2430 }
2431
2432 /* Lookup same type route. */
2433 for (rib = rn->info; rib; rib = rib->next)
2434 {
Paul Jakma6d691122006-07-27 21:49:00 +00002435 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2436 continue;
2437
paul718e3742002-12-13 20:15:29 +00002438 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2439 fib = rib;
2440
hassoebf1ead2005-09-21 14:58:20 +00002441 if (rib->type != type)
2442 continue;
2443 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002444 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002445 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002446 if (nexthop->ifindex != ifindex)
2447 continue;
hassoebf1ead2005-09-21 14:58:20 +00002448 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002449 {
hassoebf1ead2005-09-21 14:58:20 +00002450 rib->refcnt--;
2451 route_unlock_node (rn);
2452 route_unlock_node (rn);
2453 return 0;
paul718e3742002-12-13 20:15:29 +00002454 }
hassoebf1ead2005-09-21 14:58:20 +00002455 same = rib;
2456 break;
paul718e3742002-12-13 20:15:29 +00002457 }
hassoebf1ead2005-09-21 14:58:20 +00002458 /* Make sure that the route found has the same gateway. */
2459 else if (gate == NULL ||
2460 ((nexthop = rib->nexthop) &&
2461 (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate) ||
2462 IPV6_ADDR_SAME (&nexthop->rgate.ipv6, gate))))
paul718e3742002-12-13 20:15:29 +00002463 {
hassoebf1ead2005-09-21 14:58:20 +00002464 same = rib;
2465 break;
paul718e3742002-12-13 20:15:29 +00002466 }
2467 }
2468
2469 /* If same type of route can't be found and this message is from
2470 kernel. */
2471 if (! same)
2472 {
2473 if (fib && type == ZEBRA_ROUTE_KERNEL)
2474 {
2475 /* Unset flags. */
2476 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2477 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2478
2479 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2480 }
2481 else
2482 {
2483 if (IS_ZEBRA_DEBUG_KERNEL)
2484 {
2485 if (gate)
ajsb6178002004-12-07 21:12:56 +00002486 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002487 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002488 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002489 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002490 ifindex,
2491 type);
2492 else
ajsb6178002004-12-07 21:12:56 +00002493 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002494 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002495 p->prefixlen,
2496 ifindex,
2497 type);
2498 }
2499 route_unlock_node (rn);
2500 return ZEBRA_ERR_RTNOEXIST;
2501 }
2502 }
2503
2504 if (same)
2505 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002506
paul718e3742002-12-13 20:15:29 +00002507 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002508 return 0;
2509}
2510
2511/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002512static void
paul718e3742002-12-13 20:15:29 +00002513static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2514{
2515 struct rib *rib;
2516 struct route_table *table;
2517 struct route_node *rn;
2518
2519 /* Lookup table. */
2520 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2521 if (! table)
2522 return;
2523
2524 /* Lookup existing route */
2525 rn = route_node_get (table, p);
2526 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002527 {
2528 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2529 continue;
2530
2531 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2532 break;
2533 }
paul718e3742002-12-13 20:15:29 +00002534
2535 if (rib)
2536 {
2537 /* Same distance static route is there. Update it with new
2538 nexthop. */
paul718e3742002-12-13 20:15:29 +00002539 route_unlock_node (rn);
2540
2541 switch (si->type)
2542 {
2543 case STATIC_IPV6_GATEWAY:
2544 nexthop_ipv6_add (rib, &si->ipv6);
2545 break;
2546 case STATIC_IPV6_IFNAME:
2547 nexthop_ifname_add (rib, si->ifname);
2548 break;
2549 case STATIC_IPV6_GATEWAY_IFNAME:
2550 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2551 break;
2552 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002553 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002554 }
2555 else
2556 {
2557 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002558 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2559
paul718e3742002-12-13 20:15:29 +00002560 rib->type = ZEBRA_ROUTE_STATIC;
2561 rib->distance = si->distance;
2562 rib->metric = 0;
2563 rib->nexthop_num = 0;
2564
2565 switch (si->type)
2566 {
2567 case STATIC_IPV6_GATEWAY:
2568 nexthop_ipv6_add (rib, &si->ipv6);
2569 break;
2570 case STATIC_IPV6_IFNAME:
2571 nexthop_ifname_add (rib, si->ifname);
2572 break;
2573 case STATIC_IPV6_GATEWAY_IFNAME:
2574 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2575 break;
2576 }
2577
hasso81dfcaa2003-05-25 19:21:25 +00002578 /* Save the flags of this static routes (reject, blackhole) */
2579 rib->flags = si->flags;
2580
paul718e3742002-12-13 20:15:29 +00002581 /* Link this rib to the tree. */
2582 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002583 }
2584}
2585
paula1ac18c2005-06-28 17:17:12 +00002586static int
paul718e3742002-12-13 20:15:29 +00002587static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2588{
2589 if (nexthop->type == NEXTHOP_TYPE_IPV6
2590 && si->type == STATIC_IPV6_GATEWAY
2591 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2592 return 1;
2593 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2594 && si->type == STATIC_IPV6_IFNAME
2595 && strcmp (nexthop->ifname, si->ifname) == 0)
2596 return 1;
2597 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2598 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2599 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2600 && strcmp (nexthop->ifname, si->ifname) == 0)
2601 return 1;
paule8e19462006-01-19 20:16:55 +00002602 return 0;
paul718e3742002-12-13 20:15:29 +00002603}
2604
paula1ac18c2005-06-28 17:17:12 +00002605static void
paul718e3742002-12-13 20:15:29 +00002606static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2607{
2608 struct route_table *table;
2609 struct route_node *rn;
2610 struct rib *rib;
2611 struct nexthop *nexthop;
2612
2613 /* Lookup table. */
2614 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2615 if (! table)
2616 return;
2617
2618 /* Lookup existing route with type and distance. */
2619 rn = route_node_lookup (table, (struct prefix *) p);
2620 if (! rn)
2621 return;
2622
2623 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002624 {
2625 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2626 continue;
2627
2628 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2629 break;
2630 }
2631
paul718e3742002-12-13 20:15:29 +00002632 if (! rib)
2633 {
2634 route_unlock_node (rn);
2635 return;
2636 }
2637
2638 /* Lookup nexthop. */
2639 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2640 if (static_ipv6_nexthop_same (nexthop, si))
2641 break;
2642
2643 /* Can't find nexthop. */
2644 if (! nexthop)
2645 {
2646 route_unlock_node (rn);
2647 return;
2648 }
2649
2650 /* Check nexthop. */
2651 if (rib->nexthop_num == 1)
2652 {
2653 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002654 }
2655 else
2656 {
paul6baeb982003-10-28 03:47:15 +00002657 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2658 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002659 nexthop_delete (rib, nexthop);
2660 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002661 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002662 }
paul718e3742002-12-13 20:15:29 +00002663 /* Unlock node. */
2664 route_unlock_node (rn);
2665}
2666
2667/* Add static route into static route configuration. */
2668int
2669static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002670 const char *ifname, u_char flags, u_char distance,
2671 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002672{
2673 struct route_node *rn;
2674 struct static_ipv6 *si;
2675 struct static_ipv6 *pp;
2676 struct static_ipv6 *cp;
2677 struct route_table *stable;
2678
2679 /* Lookup table. */
2680 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2681 if (! stable)
2682 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00002683
2684 if (!gate &&
2685 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
2686 return -1;
2687
2688 if (!ifname &&
2689 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
2690 return -1;
paul718e3742002-12-13 20:15:29 +00002691
2692 /* Lookup static route prefix. */
2693 rn = route_node_get (stable, p);
2694
2695 /* Do nothing if there is a same static route. */
2696 for (si = rn->info; si; si = si->next)
2697 {
2698 if (distance == si->distance
2699 && type == si->type
2700 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2701 && (! ifname || strcmp (ifname, si->ifname) == 0))
2702 {
2703 route_unlock_node (rn);
2704 return 0;
2705 }
2706 }
2707
2708 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002709 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
paul718e3742002-12-13 20:15:29 +00002710
2711 si->type = type;
2712 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002713 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002714
2715 switch (type)
2716 {
2717 case STATIC_IPV6_GATEWAY:
2718 si->ipv6 = *gate;
2719 break;
2720 case STATIC_IPV6_IFNAME:
2721 si->ifname = XSTRDUP (0, ifname);
2722 break;
2723 case STATIC_IPV6_GATEWAY_IFNAME:
2724 si->ipv6 = *gate;
2725 si->ifname = XSTRDUP (0, ifname);
2726 break;
2727 }
2728
2729 /* Add new static route information to the tree with sort by
2730 distance value and gateway address. */
2731 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2732 {
2733 if (si->distance < cp->distance)
2734 break;
2735 if (si->distance > cp->distance)
2736 continue;
2737 }
2738
2739 /* Make linked list. */
2740 if (pp)
2741 pp->next = si;
2742 else
2743 rn->info = si;
2744 if (cp)
2745 cp->prev = si;
2746 si->prev = pp;
2747 si->next = cp;
2748
2749 /* Install into rib. */
2750 static_install_ipv6 (p, si);
2751
2752 return 1;
2753}
2754
2755/* Delete static route from static route configuration. */
2756int
2757static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002758 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002759{
2760 struct route_node *rn;
2761 struct static_ipv6 *si;
2762 struct route_table *stable;
2763
2764 /* Lookup table. */
2765 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2766 if (! stable)
2767 return -1;
2768
2769 /* Lookup static route prefix. */
2770 rn = route_node_lookup (stable, p);
2771 if (! rn)
2772 return 0;
2773
2774 /* Find same static route is the tree */
2775 for (si = rn->info; si; si = si->next)
2776 if (distance == si->distance
2777 && type == si->type
2778 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2779 && (! ifname || strcmp (ifname, si->ifname) == 0))
2780 break;
2781
2782 /* Can't find static route. */
2783 if (! si)
2784 {
2785 route_unlock_node (rn);
2786 return 0;
2787 }
2788
2789 /* Install into rib. */
2790 static_uninstall_ipv6 (p, si);
2791
2792 /* Unlink static route from linked list. */
2793 if (si->prev)
2794 si->prev->next = si->next;
2795 else
2796 rn->info = si->next;
2797 if (si->next)
2798 si->next->prev = si->prev;
2799
2800 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002801 if (ifname)
2802 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00002803 XFREE (MTYPE_STATIC_IPV6, si);
2804
2805 return 1;
2806}
2807#endif /* HAVE_IPV6 */
2808
2809/* RIB update function. */
2810void
paula1ac18c2005-06-28 17:17:12 +00002811rib_update (void)
paul718e3742002-12-13 20:15:29 +00002812{
2813 struct route_node *rn;
2814 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00002815
paul718e3742002-12-13 20:15:29 +00002816 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2817 if (table)
2818 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002819 if (rn->info)
Paul Jakma6d691122006-07-27 21:49:00 +00002820 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002821
2822 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2823 if (table)
2824 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002825 if (rn->info)
Paul Jakma6d691122006-07-27 21:49:00 +00002826 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002827}
2828
paul718e3742002-12-13 20:15:29 +00002829
2830/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00002831static void
paul718e3742002-12-13 20:15:29 +00002832rib_weed_table (struct route_table *table)
2833{
2834 struct route_node *rn;
2835 struct rib *rib;
2836 struct rib *next;
2837
2838 if (table)
2839 for (rn = route_top (table); rn; rn = route_next (rn))
2840 for (rib = rn->info; rib; rib = next)
2841 {
2842 next = rib->next;
2843
Paul Jakma6d691122006-07-27 21:49:00 +00002844 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2845 continue;
2846
paulb21b19c2003-06-15 01:28:29 +00002847 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00002848 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00002849 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002850 }
2851}
2852
2853/* Delete all routes from non main table. */
2854void
paula1ac18c2005-06-28 17:17:12 +00002855rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00002856{
2857 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2858 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2859}
2860
2861/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00002862static void
paul718e3742002-12-13 20:15:29 +00002863rib_sweep_table (struct route_table *table)
2864{
2865 struct route_node *rn;
2866 struct rib *rib;
2867 struct rib *next;
2868 int ret = 0;
2869
2870 if (table)
2871 for (rn = route_top (table); rn; rn = route_next (rn))
2872 for (rib = rn->info; rib; rib = next)
2873 {
2874 next = rib->next;
2875
Paul Jakma6d691122006-07-27 21:49:00 +00002876 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2877 continue;
2878
paul718e3742002-12-13 20:15:29 +00002879 if (rib->type == ZEBRA_ROUTE_KERNEL &&
2880 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
2881 {
2882 ret = rib_uninstall_kernel (rn, rib);
2883 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00002884 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002885 }
2886 }
2887}
2888
2889/* Sweep all RIB tables. */
2890void
paula1ac18c2005-06-28 17:17:12 +00002891rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00002892{
2893 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2894 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2895}
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04002896
2897/* Remove specific by protocol routes from 'table'. */
2898static unsigned long
2899rib_score_proto_table (u_char proto, struct route_table *table)
2900{
2901 struct route_node *rn;
2902 struct rib *rib;
2903 struct rib *next;
2904 unsigned long n = 0;
2905
2906 if (table)
2907 for (rn = route_top (table); rn; rn = route_next (rn))
2908 for (rib = rn->info; rib; rib = next)
2909 {
2910 next = rib->next;
2911 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2912 continue;
2913 if (rib->type == proto)
2914 {
2915 rib_delnode (rn, rib);
2916 n++;
2917 }
2918 }
2919
2920 return n;
2921}
2922
2923/* Remove specific by protocol routes. */
2924unsigned long
2925rib_score_proto (u_char proto)
2926{
2927 return rib_score_proto_table (proto, vrf_table (AFI_IP, SAFI_UNICAST, 0))
2928 +rib_score_proto_table (proto, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2929}
2930
paul718e3742002-12-13 20:15:29 +00002931/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00002932static void
paul718e3742002-12-13 20:15:29 +00002933rib_close_table (struct route_table *table)
2934{
2935 struct route_node *rn;
2936 struct rib *rib;
2937
2938 if (table)
2939 for (rn = route_top (table); rn; rn = route_next (rn))
2940 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002941 {
2942 if (! RIB_SYSTEM_ROUTE (rib)
2943 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2944 rib_uninstall_kernel (rn, rib);
2945 }
paul718e3742002-12-13 20:15:29 +00002946}
2947
2948/* Close all RIB tables. */
2949void
paula1ac18c2005-06-28 17:17:12 +00002950rib_close (void)
paul718e3742002-12-13 20:15:29 +00002951{
2952 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2953 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2954}
2955
2956/* Routing information base initialize. */
2957void
paula1ac18c2005-06-28 17:17:12 +00002958rib_init (void)
paul718e3742002-12-13 20:15:29 +00002959{
paul4d38fdb2005-04-28 17:35:14 +00002960 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00002961 /* VRF initialization. */
2962 vrf_init ();
2963}