blob: b8a47031f25ff8aac7eef3bf8f395bcf175e9f48 [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
Josh Bailey26e2ae32012-03-22 01:09:21 -0700235struct 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 */
Jorge Boncompte [DTI2]12829322012-04-10 16:57:25 +0200681 if (nexthop->gate.ipv4.s_addr == sockunion2ip (qgate) ||
682 nexthop->rgate.ipv4.s_addr == sockunion2ip (qgate))
Denis Ovsienkodc958242007-08-13 16:03:06 +0000683 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);
Jorge Boncompte [DTI2]12829322012-04-10 16:57:25 +0200691 inet_ntop (AF_INET, &sockunion2ip (qgate), qgate_buf, INET_ADDRSTRLEN);
Denis Ovsienkodc958242007-08-13 16:03:06 +0000692 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{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001282 char buf[INET_ADDRSTRLEN];
1283 assert (zebra && rn);
paul4d38fdb2005-04-28 17:35:14 +00001284
Paul Jakma93bdada2007-08-06 19:25:11 +00001285 if (IS_ZEBRA_DEBUG_RIB_Q)
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001286 inet_ntop (AF_INET, &rn->p.u.prefix, buf, INET_ADDRSTRLEN);
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001287
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001288 /* Pointless to queue a route_node with no RIB entries to add or remove */
1289 if (!rn->info)
1290 {
1291 zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1292 __func__, rn, rn->lock);
1293 zlog_backtrace(LOG_DEBUG);
1294 return;
1295 }
1296
1297 if (IS_ZEBRA_DEBUG_RIB_Q)
1298 zlog_info ("%s: %s/%d: work queue added", __func__, buf, rn->p.prefixlen);
1299
1300 assert (zebra);
1301
1302 if (zebra->ribq == NULL)
1303 {
1304 zlog_err ("%s: work_queue does not exist!", __func__);
1305 return;
Paul Jakma6d691122006-07-27 21:49:00 +00001306 }
paul4d38fdb2005-04-28 17:35:14 +00001307
Stephen Hemmingercc2dd922009-12-09 17:54:49 +03001308 /*
1309 * The RIB queue should normally be either empty or holding the only
1310 * work_queue_item element. In the latter case this element would
1311 * hold a pointer to the meta queue structure, which must be used to
1312 * actually queue the route nodes to process. So create the MQ
1313 * holder, if necessary, then push the work into it in any case.
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001314 * This semantics was introduced after 0.99.9 release.
1315 */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001316 if (!zebra->ribq->items->count)
1317 work_queue_add (zebra->ribq, zebra->mq);
1318
1319 rib_meta_queue_add (zebra->mq, rn);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001320
1321 if (IS_ZEBRA_DEBUG_RIB_Q)
1322 zlog_debug ("%s: %s/%d: rn %p queued", __func__, buf, rn->p.prefixlen, rn);
1323
1324 return;
paul4d38fdb2005-04-28 17:35:14 +00001325}
1326
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001327/* Create new meta queue.
1328 A destructor function doesn't seem to be necessary here.
1329 */
Stephen Hemmingeref9b1132008-08-17 17:44:47 +01001330static struct meta_queue *
1331meta_queue_new (void)
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001332{
1333 struct meta_queue *new;
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001334 unsigned i;
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001335
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001336 new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1337 assert(new);
1338
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001339 for (i = 0; i < MQ_SIZE; i++)
Stephen Hemminger5110a0c2008-08-11 16:22:15 -07001340 {
1341 new->subq[i] = list_new ();
1342 assert(new->subq[i]);
1343 }
1344
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001345 return new;
1346}
1347
paul4d38fdb2005-04-28 17:35:14 +00001348/* initialise zebra rib work queue */
paula1ac18c2005-06-28 17:17:12 +00001349static void
paul4d38fdb2005-04-28 17:35:14 +00001350rib_queue_init (struct zebra_t *zebra)
1351{
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001352 assert (zebra);
1353
paul4d38fdb2005-04-28 17:35:14 +00001354 if (! (zebra->ribq = work_queue_new (zebra->master,
Paul Jakma6d691122006-07-27 21:49:00 +00001355 "route_node processing")))
paul4d38fdb2005-04-28 17:35:14 +00001356 {
Paul Jakma6d691122006-07-27 21:49:00 +00001357 zlog_err ("%s: could not initialise work queue!", __func__);
paul4d38fdb2005-04-28 17:35:14 +00001358 return;
1359 }
1360
1361 /* fill in the work queue spec */
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001362 zebra->ribq->spec.workfunc = &meta_queue_process;
paul4d38fdb2005-04-28 17:35:14 +00001363 zebra->ribq->spec.errorfunc = NULL;
paul4d38fdb2005-04-28 17:35:14 +00001364 /* XXX: TODO: These should be runtime configurable via vty */
1365 zebra->ribq->spec.max_retries = 3;
Paul Jakma457eb9a2006-07-27 19:59:58 +00001366 zebra->ribq->spec.hold = rib_process_hold_time;
paul4d38fdb2005-04-28 17:35:14 +00001367
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001368 if (!(zebra->mq = meta_queue_new ()))
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001369 {
Denis Ovsienkoe96f9202008-06-02 12:03:22 +00001370 zlog_err ("%s: could not initialise meta queue!", __func__);
Subbaiah Venkatafc328ac2012-03-27 16:35:22 -07001371 return;
1372 }
1373 return;
paul718e3742002-12-13 20:15:29 +00001374}
1375
Paul Jakma6d691122006-07-27 21:49:00 +00001376/* RIB updates are processed via a queue of pointers to route_nodes.
1377 *
1378 * The queue length is bounded by the maximal size of the routing table,
1379 * as a route_node will not be requeued, if already queued.
1380 *
Paul Jakma3c0755d2006-12-08 00:53:14 +00001381 * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1382 * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1383 * and then submit route_node to queue for best-path selection later.
1384 * Order of add/delete state changes are preserved for any given RIB.
Paul Jakma6d691122006-07-27 21:49:00 +00001385 *
1386 * Deleted RIBs are reaped during best-path selection.
1387 *
1388 * rib_addnode
1389 * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
Paul Jakma3c0755d2006-12-08 00:53:14 +00001390 * |-------->| | best RIB, if required
1391 * | |
1392 * static_install->|->rib_addqueue...... -> rib_process
1393 * | |
1394 * |-------->| |-> rib_unlink
Paul Jakma6d691122006-07-27 21:49:00 +00001395 * |-> set RIB_ENTRY_REMOVE |
1396 * rib_delnode (RIB freed)
1397 *
1398 *
1399 * Queueing state for a route_node is kept in the head RIB entry, this
1400 * state must be preserved as and when the head RIB entry of a
1401 * route_node is changed by rib_unlink / rib_link. A small complication,
1402 * but saves having to allocate a dedicated object for this.
1403 *
1404 * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1405 *
1406 * - route_nodes: refcounted by:
1407 * - RIBs attached to route_node:
1408 * - managed by: rib_link/unlink
1409 * - route_node processing queue
1410 * - managed by: rib_addqueue, rib_process.
1411 *
1412 */
1413
paul718e3742002-12-13 20:15:29 +00001414/* Add RIB to head of the route node. */
paula1ac18c2005-06-28 17:17:12 +00001415static void
Paul Jakma6d691122006-07-27 21:49:00 +00001416rib_link (struct route_node *rn, struct rib *rib)
paul718e3742002-12-13 20:15:29 +00001417{
1418 struct rib *head;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001419 char buf[INET6_ADDRSTRLEN];
paul4d38fdb2005-04-28 17:35:14 +00001420
1421 assert (rib && rn);
1422
Paul Jakma6d691122006-07-27 21:49:00 +00001423 route_lock_node (rn); /* rn route table reference */
1424
1425 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001426 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001427 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001428 zlog_debug ("%s: %s/%d: rn %p, rib %p", __func__,
1429 buf, rn->p.prefixlen, rn, rib);
1430 }
Paul Jakma6d691122006-07-27 21:49:00 +00001431
paul718e3742002-12-13 20:15:29 +00001432 head = rn->info;
1433 if (head)
Paul Jakma6d691122006-07-27 21:49:00 +00001434 {
1435 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001436 zlog_debug ("%s: %s/%d: new head, rn_status copied over", __func__,
1437 buf, rn->p.prefixlen);
Paul Jakma6d691122006-07-27 21:49:00 +00001438 head->prev = rib;
1439 /* Transfer the rn status flags to the new head RIB */
1440 rib->rn_status = head->rn_status;
1441 }
paul718e3742002-12-13 20:15:29 +00001442 rib->next = head;
1443 rn->info = rib;
Paul Jakma6d691122006-07-27 21:49:00 +00001444 rib_queue_add (&zebrad, rn);
1445}
1446
1447static void
1448rib_addnode (struct route_node *rn, struct rib *rib)
1449{
1450 /* RIB node has been un-removed before route-node is processed.
1451 * route_node must hence already be on the queue for processing..
1452 */
1453 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1454 {
1455 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001456 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001457 char buf[INET6_ADDRSTRLEN];
1458 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001459 zlog_debug ("%s: %s/%d: rn %p, un-removed rib %p",
1460 __func__, buf, rn->p.prefixlen, rn, rib);
1461 }
Paul Jakma6d691122006-07-27 21:49:00 +00001462 UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1463 return;
1464 }
1465 rib_link (rn, rib);
1466}
1467
1468static void
1469rib_unlink (struct route_node *rn, struct rib *rib)
1470{
1471 struct nexthop *nexthop, *next;
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001472 char buf[INET6_ADDRSTRLEN];
Paul Jakma6d691122006-07-27 21:49:00 +00001473
1474 assert (rn && rib);
1475
1476 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001477 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001478 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001479 zlog_debug ("%s: %s/%d: rn %p, rib %p",
1480 __func__, buf, rn->p.prefixlen, rn, rib);
1481 }
Paul Jakma6d691122006-07-27 21:49:00 +00001482
1483 if (rib->next)
1484 rib->next->prev = rib->prev;
1485
1486 if (rib->prev)
1487 rib->prev->next = rib->next;
1488 else
1489 {
1490 rn->info = rib->next;
1491
1492 if (rn->info)
1493 {
1494 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001495 zlog_debug ("%s: %s/%d: rn %p, rib %p, new head copy",
1496 __func__, buf, rn->p.prefixlen, rn, rib);
Paul Jakma6d691122006-07-27 21:49:00 +00001497 rib->next->rn_status = rib->rn_status;
1498 }
1499 }
1500
1501 /* free RIB and nexthops */
1502 for (nexthop = rib->nexthop; nexthop; nexthop = next)
1503 {
1504 next = nexthop->next;
1505 nexthop_free (nexthop);
1506 }
1507 XFREE (MTYPE_RIB, rib);
1508
1509 route_unlock_node (rn); /* rn route table reference */
paul718e3742002-12-13 20:15:29 +00001510}
1511
paula1ac18c2005-06-28 17:17:12 +00001512static void
paul718e3742002-12-13 20:15:29 +00001513rib_delnode (struct route_node *rn, struct rib *rib)
1514{
Paul Jakma6d691122006-07-27 21:49:00 +00001515 if (IS_ZEBRA_DEBUG_RIB)
Paul Jakma93bdada2007-08-06 19:25:11 +00001516 {
Denis Ovsienkof304cb42007-10-03 12:27:16 +00001517 char buf[INET6_ADDRSTRLEN];
1518 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
Paul Jakma93bdada2007-08-06 19:25:11 +00001519 zlog_debug ("%s: %s/%d: rn %p, rib %p, removing", __func__,
1520 buf, rn->p.prefixlen, rn, rib);
1521 }
Paul Jakma6d691122006-07-27 21:49:00 +00001522 SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1523 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00001524}
1525
1526int
1527rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
Paul Jakma7514fb72007-05-02 16:05:35 +00001528 struct in_addr *gate, struct in_addr *src,
1529 unsigned int ifindex, u_int32_t vrf_id,
G.Balajicddf3912011-11-26 21:59:32 +04001530 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001531{
1532 struct rib *rib;
1533 struct rib *same = NULL;
1534 struct route_table *table;
1535 struct route_node *rn;
1536 struct nexthop *nexthop;
1537
1538 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04001539 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00001540 if (! table)
1541 return 0;
1542
1543 /* Make it sure prefixlen is applied to the prefix. */
1544 apply_mask_ipv4 (p);
1545
1546 /* Set default distance by route type. */
1547 if (distance == 0)
1548 {
David Lamparter7052f222009-08-27 00:28:28 +02001549 if ((unsigned)type >= sizeof(route_info) / sizeof(route_info[0]))
1550 distance = 150;
1551 else
1552 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00001553
1554 /* iBGP distance is 200. */
1555 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1556 distance = 200;
1557 }
1558
1559 /* Lookup route node.*/
1560 rn = route_node_get (table, (struct prefix *) p);
1561
1562 /* If same type of route are installed, treat it as a implicit
1563 withdraw. */
1564 for (rib = rn->info; rib; rib = rib->next)
1565 {
Paul Jakma6d691122006-07-27 21:49:00 +00001566 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1567 continue;
1568
hassoebf1ead2005-09-21 14:58:20 +00001569 if (rib->type != type)
1570 continue;
1571 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001572 {
1573 same = rib;
1574 break;
1575 }
hassoebf1ead2005-09-21 14:58:20 +00001576 /* Duplicate connected route comes in. */
1577 else if ((nexthop = rib->nexthop) &&
1578 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
Paul Jakma6d691122006-07-27 21:49:00 +00001579 nexthop->ifindex == ifindex &&
1580 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
hassoebf1ead2005-09-21 14:58:20 +00001581 {
1582 rib->refcnt++;
1583 return 0 ;
1584 }
paul718e3742002-12-13 20:15:29 +00001585 }
1586
1587 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00001588 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001589 rib->type = type;
1590 rib->distance = distance;
1591 rib->flags = flags;
1592 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00001593 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00001594 rib->nexthop_num = 0;
1595 rib->uptime = time (NULL);
1596
1597 /* Nexthop settings. */
1598 if (gate)
1599 {
1600 if (ifindex)
Paul Jakma7514fb72007-05-02 16:05:35 +00001601 nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
paul718e3742002-12-13 20:15:29 +00001602 else
Paul Jakma7514fb72007-05-02 16:05:35 +00001603 nexthop_ipv4_add (rib, gate, src);
paul718e3742002-12-13 20:15:29 +00001604 }
1605 else
1606 nexthop_ifindex_add (rib, ifindex);
1607
1608 /* If this route is kernel route, set FIB flag to the route. */
1609 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1610 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1611 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1612
1613 /* Link new rib to node.*/
Denis Ovsienkodc958242007-08-13 16:03:06 +00001614 if (IS_ZEBRA_DEBUG_RIB)
1615 zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
paul718e3742002-12-13 20:15:29 +00001616 rib_addnode (rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001617
paul718e3742002-12-13 20:15:29 +00001618 /* Free implicit route.*/
1619 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001620 {
1621 if (IS_ZEBRA_DEBUG_RIB)
1622 zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
paul4d38fdb2005-04-28 17:35:14 +00001623 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001624 }
paul4d38fdb2005-04-28 17:35:14 +00001625
1626 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001627 return 0;
1628}
1629
Denis Ovsienkodc958242007-08-13 16:03:06 +00001630/* This function dumps the contents of a given RIB entry into
1631 * standard debug log. Calling function name and IP prefix in
1632 * question are passed as 1st and 2nd arguments.
1633 */
1634
1635void rib_dump (const char * func, const struct prefix_ipv4 * p, const struct rib * rib)
1636{
1637 char straddr1[INET_ADDRSTRLEN], straddr2[INET_ADDRSTRLEN];
1638 struct nexthop *nexthop;
1639
1640 inet_ntop (AF_INET, &p->prefix, straddr1, INET_ADDRSTRLEN);
1641 zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr1, p->prefixlen);
1642 zlog_debug
1643 (
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001644 "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
Denis Ovsienkodc958242007-08-13 16:03:06 +00001645 func,
1646 rib->refcnt,
Stephen Hemmingerd02c56c2009-12-08 13:14:27 +03001647 (unsigned long) rib->uptime,
Denis Ovsienkodc958242007-08-13 16:03:06 +00001648 rib->type,
1649 rib->table
1650 );
1651 zlog_debug
1652 (
1653 "%s: metric == %u, distance == %u, flags == %u, status == %u",
1654 func,
1655 rib->metric,
1656 rib->distance,
1657 rib->flags,
1658 rib->status
1659 );
1660 zlog_debug
1661 (
1662 "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1663 func,
1664 rib->nexthop_num,
1665 rib->nexthop_active_num,
1666 rib->nexthop_fib_num
1667 );
1668 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1669 {
1670 inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, straddr1, INET_ADDRSTRLEN);
1671 inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, straddr2, INET_ADDRSTRLEN);
1672 zlog_debug
1673 (
1674 "%s: NH %s (%s) with flags %s%s%s",
1675 func,
1676 straddr1,
1677 straddr2,
1678 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1679 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1680 (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1681 );
1682 }
1683 zlog_debug ("%s: dump complete", func);
1684}
1685
1686/* This is an exported helper to rtm_read() to dump the strange
1687 * RIB entry found by rib_lookup_ipv4_route()
1688 */
1689
1690void rib_lookup_and_dump (struct prefix_ipv4 * p)
1691{
1692 struct route_table *table;
1693 struct route_node *rn;
1694 struct rib *rib;
1695 char prefix_buf[INET_ADDRSTRLEN];
1696
1697 /* Lookup table. */
1698 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1699 if (! table)
1700 {
1701 zlog_err ("%s: vrf_table() returned NULL", __func__);
1702 return;
1703 }
1704
1705 inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
1706 /* Scan the RIB table for exactly matching RIB entry. */
1707 rn = route_node_lookup (table, (struct prefix *) p);
1708
1709 /* No route for this prefix. */
1710 if (! rn)
1711 {
1712 zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
1713 return;
1714 }
1715
1716 /* Unlock node. */
1717 route_unlock_node (rn);
1718
1719 /* let's go */
1720 for (rib = rn->info; rib; rib = rib->next)
1721 {
1722 zlog_debug
1723 (
1724 "%s: rn %p, rib %p: %s, %s",
1725 __func__,
1726 rn,
1727 rib,
1728 (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
1729 (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
1730 );
1731 rib_dump (__func__, p, rib);
1732 }
1733}
1734
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001735/* Check if requested address assignment will fail due to another
1736 * route being installed by zebra in FIB already. Take necessary
1737 * actions, if needed: remove such a route from FIB and deSELECT
1738 * corresponding RIB entry. Then put affected RN into RIBQ head.
1739 */
1740void rib_lookup_and_pushup (struct prefix_ipv4 * p)
1741{
1742 struct route_table *table;
1743 struct route_node *rn;
1744 struct rib *rib;
1745 unsigned changed = 0;
1746
1747 if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
1748 {
1749 zlog_err ("%s: vrf_table() returned NULL", __func__);
1750 return;
1751 }
1752
1753 /* No matches would be the simplest case. */
1754 if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
1755 return;
1756
1757 /* Unlock node. */
1758 route_unlock_node (rn);
1759
1760 /* Check all RIB entries. In case any changes have to be done, requeue
1761 * the RN into RIBQ head. If the routing message about the new connected
1762 * route (generated by the IP address we are going to assign very soon)
1763 * comes before the RIBQ is processed, the new RIB entry will join
1764 * RIBQ record already on head. This is necessary for proper revalidation
1765 * of the rest of the RIB.
1766 */
1767 for (rib = rn->info; rib; rib = rib->next)
1768 {
1769 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
1770 ! RIB_SYSTEM_ROUTE (rib))
1771 {
1772 changed = 1;
1773 if (IS_ZEBRA_DEBUG_RIB)
1774 {
1775 char buf[INET_ADDRSTRLEN];
1776 inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
1777 zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
1778 rib_dump (__func__, (struct prefix_ipv4 *)&rn->p, rib);
1779 }
1780 rib_uninstall (rn, rib);
1781 }
1782 }
1783 if (changed)
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001784 rib_queue_add (&zebrad, rn);
Denis Ovsienko20e5ff02008-02-26 14:02:24 +00001785}
1786
paul718e3742002-12-13 20:15:29 +00001787int
G.Balajicddf3912011-11-26 21:59:32 +04001788rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001789{
1790 struct route_table *table;
1791 struct route_node *rn;
1792 struct rib *same;
1793 struct nexthop *nexthop;
paul4d38fdb2005-04-28 17:35:14 +00001794
paul718e3742002-12-13 20:15:29 +00001795 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04001796 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00001797 if (! table)
1798 return 0;
G.Balajicddf3912011-11-26 21:59:32 +04001799
paul718e3742002-12-13 20:15:29 +00001800 /* Make it sure prefixlen is applied to the prefix. */
1801 apply_mask_ipv4 (p);
1802
1803 /* Set default distance by route type. */
1804 if (rib->distance == 0)
1805 {
1806 rib->distance = route_info[rib->type].distance;
1807
1808 /* iBGP distance is 200. */
1809 if (rib->type == ZEBRA_ROUTE_BGP
1810 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1811 rib->distance = 200;
1812 }
1813
1814 /* Lookup route node.*/
1815 rn = route_node_get (table, (struct prefix *) p);
1816
1817 /* If same type of route are installed, treat it as a implicit
1818 withdraw. */
1819 for (same = rn->info; same; same = same->next)
1820 {
Paul Jakma0b8c4f12007-06-27 11:12:38 +00001821 if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
Paul Jakma6d691122006-07-27 21:49:00 +00001822 continue;
1823
paul718e3742002-12-13 20:15:29 +00001824 if (same->type == rib->type && same->table == rib->table
1825 && same->type != ZEBRA_ROUTE_CONNECT)
paul4d38fdb2005-04-28 17:35:14 +00001826 break;
paul718e3742002-12-13 20:15:29 +00001827 }
paul4d38fdb2005-04-28 17:35:14 +00001828
paul718e3742002-12-13 20:15:29 +00001829 /* If this route is kernel route, set FIB flag to the route. */
1830 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
1831 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1832 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1833
1834 /* Link new rib to node.*/
1835 rib_addnode (rn, rib);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001836 if (IS_ZEBRA_DEBUG_RIB)
1837 {
1838 zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
1839 __func__, rn, rib);
1840 rib_dump (__func__, p, rib);
1841 }
paul718e3742002-12-13 20:15:29 +00001842
paul718e3742002-12-13 20:15:29 +00001843 /* Free implicit route.*/
1844 if (same)
Denis Ovsienkodc958242007-08-13 16:03:06 +00001845 {
1846 if (IS_ZEBRA_DEBUG_RIB)
1847 {
1848 zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
1849 __func__, rn, same);
1850 rib_dump (__func__, p, same);
1851 }
paul4d38fdb2005-04-28 17:35:14 +00001852 rib_delnode (rn, same);
Denis Ovsienkodc958242007-08-13 16:03:06 +00001853 }
paul4d38fdb2005-04-28 17:35:14 +00001854
1855 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001856 return 0;
1857}
1858
hassoebf1ead2005-09-21 14:58:20 +00001859/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00001860int
1861rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
G.Balajicddf3912011-11-26 21:59:32 +04001862 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00001863{
1864 struct route_table *table;
1865 struct route_node *rn;
1866 struct rib *rib;
1867 struct rib *fib = NULL;
1868 struct rib *same = NULL;
1869 struct nexthop *nexthop;
Stephen Hemminger81cce012009-04-28 14:28:00 -07001870 char buf1[INET_ADDRSTRLEN];
1871 char buf2[INET_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00001872
1873 /* Lookup table. */
G.Balajicddf3912011-11-26 21:59:32 +04001874 table = vrf_table (AFI_IP, safi, 0);
paul718e3742002-12-13 20:15:29 +00001875 if (! table)
1876 return 0;
1877
1878 /* Apply mask. */
1879 apply_mask_ipv4 (p);
1880
paul5ec90d22003-06-19 01:41:37 +00001881 if (IS_ZEBRA_DEBUG_KERNEL && gate)
ajsb6178002004-12-07 21:12:56 +00001882 zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001883 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul5ec90d22003-06-19 01:41:37 +00001884 p->prefixlen,
1885 inet_ntoa (*gate),
1886 ifindex);
1887
paul718e3742002-12-13 20:15:29 +00001888 /* Lookup route node. */
1889 rn = route_node_lookup (table, (struct prefix *) p);
1890 if (! rn)
1891 {
1892 if (IS_ZEBRA_DEBUG_KERNEL)
1893 {
1894 if (gate)
ajsb6178002004-12-07 21:12:56 +00001895 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001896 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001897 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07001898 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001899 ifindex);
1900 else
ajsb6178002004-12-07 21:12:56 +00001901 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001902 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001903 p->prefixlen,
1904 ifindex);
1905 }
1906 return ZEBRA_ERR_RTNOEXIST;
1907 }
1908
1909 /* Lookup same type route. */
1910 for (rib = rn->info; rib; rib = rib->next)
1911 {
Paul Jakma6d691122006-07-27 21:49:00 +00001912 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1913 continue;
1914
paul718e3742002-12-13 20:15:29 +00001915 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1916 fib = rib;
1917
hassoebf1ead2005-09-21 14:58:20 +00001918 if (rib->type != type)
1919 continue;
1920 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04001921 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00001922 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04001923 if (nexthop->ifindex != ifindex)
1924 continue;
hassoebf1ead2005-09-21 14:58:20 +00001925 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00001926 {
hassoebf1ead2005-09-21 14:58:20 +00001927 rib->refcnt--;
1928 route_unlock_node (rn);
1929 route_unlock_node (rn);
1930 return 0;
paul718e3742002-12-13 20:15:29 +00001931 }
hassoebf1ead2005-09-21 14:58:20 +00001932 same = rib;
1933 break;
paul718e3742002-12-13 20:15:29 +00001934 }
hassoebf1ead2005-09-21 14:58:20 +00001935 /* Make sure that the route found has the same gateway. */
1936 else if (gate == NULL ||
1937 ((nexthop = rib->nexthop) &&
1938 (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
1939 IPV4_ADDR_SAME (&nexthop->rgate.ipv4, gate))))
paul5ec90d22003-06-19 01:41:37 +00001940 {
hassoebf1ead2005-09-21 14:58:20 +00001941 same = rib;
1942 break;
paul718e3742002-12-13 20:15:29 +00001943 }
1944 }
1945
1946 /* If same type of route can't be found and this message is from
1947 kernel. */
1948 if (! same)
1949 {
1950 if (fib && type == ZEBRA_ROUTE_KERNEL)
1951 {
1952 /* Unset flags. */
1953 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
1954 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1955
1956 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1957 }
1958 else
1959 {
1960 if (IS_ZEBRA_DEBUG_KERNEL)
1961 {
1962 if (gate)
ajsb6178002004-12-07 21:12:56 +00001963 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001964 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001965 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07001966 inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001967 ifindex,
1968 type);
1969 else
ajsb6178002004-12-07 21:12:56 +00001970 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001971 inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00001972 p->prefixlen,
1973 ifindex,
1974 type);
1975 }
1976 route_unlock_node (rn);
1977 return ZEBRA_ERR_RTNOEXIST;
1978 }
1979 }
paul4d38fdb2005-04-28 17:35:14 +00001980
paul718e3742002-12-13 20:15:29 +00001981 if (same)
1982 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00001983
paul718e3742002-12-13 20:15:29 +00001984 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001985 return 0;
1986}
1987
1988/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00001989static void
paul718e3742002-12-13 20:15:29 +00001990static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
1991{
1992 struct rib *rib;
1993 struct route_node *rn;
1994 struct route_table *table;
1995
1996 /* Lookup table. */
1997 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1998 if (! table)
1999 return;
2000
2001 /* Lookup existing route */
2002 rn = route_node_get (table, p);
2003 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002004 {
2005 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2006 continue;
2007
2008 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2009 break;
2010 }
paul718e3742002-12-13 20:15:29 +00002011
2012 if (rib)
2013 {
2014 /* Same distance static route is there. Update it with new
2015 nexthop. */
paul718e3742002-12-13 20:15:29 +00002016 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002017 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002018 {
2019 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002020 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002021 break;
2022 case STATIC_IPV4_IFNAME:
2023 nexthop_ifname_add (rib, si->gate.ifname);
2024 break;
2025 case STATIC_IPV4_BLACKHOLE:
2026 nexthop_blackhole_add (rib);
2027 break;
paul4d38fdb2005-04-28 17:35:14 +00002028 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002029 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002030 }
2031 else
2032 {
2033 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002034 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2035
paul718e3742002-12-13 20:15:29 +00002036 rib->type = ZEBRA_ROUTE_STATIC;
2037 rib->distance = si->distance;
2038 rib->metric = 0;
Nolan Leakeb0145dd2012-09-13 17:17:31 +00002039 rib->table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00002040 rib->nexthop_num = 0;
2041
2042 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002043 {
2044 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002045 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002046 break;
2047 case STATIC_IPV4_IFNAME:
2048 nexthop_ifname_add (rib, si->gate.ifname);
2049 break;
2050 case STATIC_IPV4_BLACKHOLE:
2051 nexthop_blackhole_add (rib);
2052 break;
2053 }
paul718e3742002-12-13 20:15:29 +00002054
hasso81dfcaa2003-05-25 19:21:25 +00002055 /* Save the flags of this static routes (reject, blackhole) */
2056 rib->flags = si->flags;
2057
paul718e3742002-12-13 20:15:29 +00002058 /* Link this rib to the tree. */
2059 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002060 }
2061}
2062
paula1ac18c2005-06-28 17:17:12 +00002063static int
paul718e3742002-12-13 20:15:29 +00002064static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2065{
2066 if (nexthop->type == NEXTHOP_TYPE_IPV4
2067 && si->type == STATIC_IPV4_GATEWAY
2068 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2069 return 1;
2070 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2071 && si->type == STATIC_IPV4_IFNAME
2072 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2073 return 1;
paul595db7f2003-05-25 21:35:06 +00002074 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2075 && si->type == STATIC_IPV4_BLACKHOLE)
2076 return 1;
paule8e19462006-01-19 20:16:55 +00002077 return 0;
paul718e3742002-12-13 20:15:29 +00002078}
2079
2080/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002081static void
paul718e3742002-12-13 20:15:29 +00002082static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
2083{
2084 struct route_node *rn;
2085 struct rib *rib;
2086 struct nexthop *nexthop;
2087 struct route_table *table;
2088
2089 /* Lookup table. */
2090 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2091 if (! table)
2092 return;
paul4d38fdb2005-04-28 17:35:14 +00002093
paul718e3742002-12-13 20:15:29 +00002094 /* Lookup existing route with type and distance. */
2095 rn = route_node_lookup (table, p);
2096 if (! rn)
2097 return;
2098
2099 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002100 {
2101 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2102 continue;
2103
2104 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2105 break;
2106 }
paul718e3742002-12-13 20:15:29 +00002107
2108 if (! rib)
2109 {
2110 route_unlock_node (rn);
2111 return;
2112 }
2113
2114 /* Lookup nexthop. */
2115 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2116 if (static_ipv4_nexthop_same (nexthop, si))
2117 break;
2118
2119 /* Can't find nexthop. */
2120 if (! nexthop)
2121 {
2122 route_unlock_node (rn);
2123 return;
2124 }
2125
2126 /* Check nexthop. */
2127 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002128 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002129 else
2130 {
paul6baeb982003-10-28 03:47:15 +00002131 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2132 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002133 nexthop_delete (rib, nexthop);
2134 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002135 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002136 }
paul718e3742002-12-13 20:15:29 +00002137 /* Unlock node. */
2138 route_unlock_node (rn);
2139}
2140
2141/* Add static route into static route configuration. */
2142int
hasso39db97e2004-10-12 20:50:58 +00002143static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00002144 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002145{
2146 u_char type = 0;
2147 struct route_node *rn;
2148 struct static_ipv4 *si;
2149 struct static_ipv4 *pp;
2150 struct static_ipv4 *cp;
2151 struct static_ipv4 *update = NULL;
2152 struct route_table *stable;
2153
2154 /* Lookup table. */
2155 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2156 if (! stable)
2157 return -1;
2158
2159 /* Lookup static route prefix. */
2160 rn = route_node_get (stable, p);
2161
2162 /* Make flags. */
2163 if (gate)
2164 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002165 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002166 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002167 else
2168 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002169
2170 /* Do nothing if there is a same static route. */
2171 for (si = rn->info; si; si = si->next)
2172 {
2173 if (type == si->type
2174 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2175 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2176 {
2177 if (distance == si->distance)
2178 {
2179 route_unlock_node (rn);
2180 return 0;
2181 }
2182 else
2183 update = si;
2184 }
2185 }
2186
Paul Jakma3c0755d2006-12-08 00:53:14 +00002187 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002188 if (update)
2189 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
2190
2191 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002192 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
paul718e3742002-12-13 20:15:29 +00002193
2194 si->type = type;
2195 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002196 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002197
2198 if (gate)
2199 si->gate.ipv4 = *gate;
2200 if (ifname)
2201 si->gate.ifname = XSTRDUP (0, ifname);
2202
2203 /* Add new static route information to the tree with sort by
2204 distance value and gateway address. */
2205 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2206 {
2207 if (si->distance < cp->distance)
2208 break;
2209 if (si->distance > cp->distance)
2210 continue;
2211 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2212 {
2213 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2214 break;
2215 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2216 continue;
2217 }
2218 }
2219
2220 /* Make linked list. */
2221 if (pp)
2222 pp->next = si;
2223 else
2224 rn->info = si;
2225 if (cp)
2226 cp->prev = si;
2227 si->prev = pp;
2228 si->next = cp;
2229
2230 /* Install into rib. */
2231 static_install_ipv4 (p, si);
2232
2233 return 1;
2234}
2235
2236/* Delete static route from static route configuration. */
2237int
hasso39db97e2004-10-12 20:50:58 +00002238static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00002239 u_char distance, u_int32_t vrf_id)
2240{
2241 u_char type = 0;
2242 struct route_node *rn;
2243 struct static_ipv4 *si;
2244 struct route_table *stable;
2245
2246 /* Lookup table. */
2247 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2248 if (! stable)
2249 return -1;
2250
2251 /* Lookup static route prefix. */
2252 rn = route_node_lookup (stable, p);
2253 if (! rn)
2254 return 0;
2255
2256 /* Make flags. */
2257 if (gate)
2258 type = STATIC_IPV4_GATEWAY;
2259 else if (ifname)
2260 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002261 else
2262 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002263
2264 /* Find same static route is the tree */
2265 for (si = rn->info; si; si = si->next)
2266 if (type == si->type
2267 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2268 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2269 break;
2270
2271 /* Can't find static route. */
2272 if (! si)
2273 {
2274 route_unlock_node (rn);
2275 return 0;
2276 }
2277
2278 /* Install into rib. */
2279 static_uninstall_ipv4 (p, si);
2280
2281 /* Unlink static route from linked list. */
2282 if (si->prev)
2283 si->prev->next = si->next;
2284 else
2285 rn->info = si->next;
2286 if (si->next)
2287 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002288 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002289
2290 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002291 if (ifname)
2292 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002293 XFREE (MTYPE_STATIC_IPV4, si);
2294
paul143a3852003-09-29 20:06:13 +00002295 route_unlock_node (rn);
2296
paul718e3742002-12-13 20:15:29 +00002297 return 1;
2298}
2299
2300
2301#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00002302static int
paul718e3742002-12-13 20:15:29 +00002303rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2304 struct in6_addr *gate, unsigned int ifindex, int table)
2305{
hasso726f9b22003-05-25 21:04:54 +00002306 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2307#if defined (MUSICA) || defined (LINUX)
2308 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2309 if (p->prefixlen == 96)
2310 return 0;
2311#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00002312 return 1;
hasso726f9b22003-05-25 21:04:54 +00002313 }
paul718e3742002-12-13 20:15:29 +00002314 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
2315 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
2316 {
2317 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
2318 return 1;
2319 }
2320 return 0;
2321}
2322
2323int
2324rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00002325 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
G.Balajif768f362011-11-26 22:10:39 +04002326 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002327{
2328 struct rib *rib;
2329 struct rib *same = NULL;
2330 struct route_table *table;
2331 struct route_node *rn;
2332 struct nexthop *nexthop;
2333
paul718e3742002-12-13 20:15:29 +00002334 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002335 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002336 if (! table)
2337 return 0;
2338
2339 /* Make sure mask is applied. */
2340 apply_mask_ipv6 (p);
2341
2342 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002343 if (!distance)
2344 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002345
2346 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2347 distance = 200;
2348
2349 /* Filter bogus route. */
2350 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
2351 return 0;
2352
2353 /* Lookup route node.*/
2354 rn = route_node_get (table, (struct prefix *) p);
2355
2356 /* If same type of route are installed, treat it as a implicit
2357 withdraw. */
2358 for (rib = rn->info; rib; rib = rib->next)
2359 {
Paul Jakma6d691122006-07-27 21:49:00 +00002360 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2361 continue;
2362
hassoebf1ead2005-09-21 14:58:20 +00002363 if (rib->type != type)
2364 continue;
2365 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002366 {
2367 same = rib;
paul718e3742002-12-13 20:15:29 +00002368 break;
2369 }
hassoebf1ead2005-09-21 14:58:20 +00002370 else if ((nexthop = rib->nexthop) &&
2371 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2372 nexthop->ifindex == ifindex)
2373 {
2374 rib->refcnt++;
2375 return 0;
2376 }
paul718e3742002-12-13 20:15:29 +00002377 }
2378
2379 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002380 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2381
paul718e3742002-12-13 20:15:29 +00002382 rib->type = type;
2383 rib->distance = distance;
2384 rib->flags = flags;
2385 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00002386 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00002387 rib->nexthop_num = 0;
2388 rib->uptime = time (NULL);
2389
2390 /* Nexthop settings. */
2391 if (gate)
2392 {
2393 if (ifindex)
2394 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2395 else
2396 nexthop_ipv6_add (rib, gate);
2397 }
2398 else
2399 nexthop_ifindex_add (rib, ifindex);
2400
2401 /* If this route is kernel route, set FIB flag to the route. */
2402 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2403 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2404 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2405
2406 /* Link new rib to node.*/
2407 rib_addnode (rn, rib);
2408
paul718e3742002-12-13 20:15:29 +00002409 /* Free implicit route.*/
2410 if (same)
paul4d38fdb2005-04-28 17:35:14 +00002411 rib_delnode (rn, same);
2412
2413 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002414 return 0;
2415}
2416
hassoebf1ead2005-09-21 14:58:20 +00002417/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002418int
2419rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
G.Balajif768f362011-11-26 22:10:39 +04002420 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002421{
2422 struct route_table *table;
2423 struct route_node *rn;
2424 struct rib *rib;
2425 struct rib *fib = NULL;
2426 struct rib *same = NULL;
2427 struct nexthop *nexthop;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002428 char buf1[INET6_ADDRSTRLEN];
2429 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002430
2431 /* Apply mask. */
2432 apply_mask_ipv6 (p);
2433
2434 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002435 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002436 if (! table)
2437 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002438
paul718e3742002-12-13 20:15:29 +00002439 /* Lookup route node. */
2440 rn = route_node_lookup (table, (struct prefix *) p);
2441 if (! rn)
2442 {
2443 if (IS_ZEBRA_DEBUG_KERNEL)
2444 {
2445 if (gate)
ajsb6178002004-12-07 21:12:56 +00002446 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002447 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002448 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002449 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002450 ifindex);
2451 else
ajsb6178002004-12-07 21:12:56 +00002452 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002453 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002454 p->prefixlen,
2455 ifindex);
2456 }
2457 return ZEBRA_ERR_RTNOEXIST;
2458 }
2459
2460 /* Lookup same type route. */
2461 for (rib = rn->info; rib; rib = rib->next)
2462 {
Paul Jakma6d691122006-07-27 21:49:00 +00002463 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2464 continue;
2465
paul718e3742002-12-13 20:15:29 +00002466 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2467 fib = rib;
2468
hassoebf1ead2005-09-21 14:58:20 +00002469 if (rib->type != type)
2470 continue;
2471 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002472 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002473 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002474 if (nexthop->ifindex != ifindex)
2475 continue;
hassoebf1ead2005-09-21 14:58:20 +00002476 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002477 {
hassoebf1ead2005-09-21 14:58:20 +00002478 rib->refcnt--;
2479 route_unlock_node (rn);
2480 route_unlock_node (rn);
2481 return 0;
paul718e3742002-12-13 20:15:29 +00002482 }
hassoebf1ead2005-09-21 14:58:20 +00002483 same = rib;
2484 break;
paul718e3742002-12-13 20:15:29 +00002485 }
hassoebf1ead2005-09-21 14:58:20 +00002486 /* Make sure that the route found has the same gateway. */
2487 else if (gate == NULL ||
2488 ((nexthop = rib->nexthop) &&
2489 (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate) ||
2490 IPV6_ADDR_SAME (&nexthop->rgate.ipv6, gate))))
paul718e3742002-12-13 20:15:29 +00002491 {
hassoebf1ead2005-09-21 14:58:20 +00002492 same = rib;
2493 break;
paul718e3742002-12-13 20:15:29 +00002494 }
2495 }
2496
2497 /* If same type of route can't be found and this message is from
2498 kernel. */
2499 if (! same)
2500 {
2501 if (fib && type == ZEBRA_ROUTE_KERNEL)
2502 {
2503 /* Unset flags. */
2504 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2505 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2506
2507 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2508 }
2509 else
2510 {
2511 if (IS_ZEBRA_DEBUG_KERNEL)
2512 {
2513 if (gate)
ajsb6178002004-12-07 21:12:56 +00002514 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002515 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002516 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002517 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002518 ifindex,
2519 type);
2520 else
ajsb6178002004-12-07 21:12:56 +00002521 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002522 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002523 p->prefixlen,
2524 ifindex,
2525 type);
2526 }
2527 route_unlock_node (rn);
2528 return ZEBRA_ERR_RTNOEXIST;
2529 }
2530 }
2531
2532 if (same)
2533 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002534
paul718e3742002-12-13 20:15:29 +00002535 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002536 return 0;
2537}
2538
2539/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002540static void
paul718e3742002-12-13 20:15:29 +00002541static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2542{
2543 struct rib *rib;
2544 struct route_table *table;
2545 struct route_node *rn;
2546
2547 /* Lookup table. */
2548 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2549 if (! table)
2550 return;
2551
2552 /* Lookup existing route */
2553 rn = route_node_get (table, p);
2554 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002555 {
2556 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2557 continue;
2558
2559 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2560 break;
2561 }
paul718e3742002-12-13 20:15:29 +00002562
2563 if (rib)
2564 {
2565 /* Same distance static route is there. Update it with new
2566 nexthop. */
paul718e3742002-12-13 20:15:29 +00002567 route_unlock_node (rn);
2568
2569 switch (si->type)
2570 {
2571 case STATIC_IPV6_GATEWAY:
2572 nexthop_ipv6_add (rib, &si->ipv6);
2573 break;
2574 case STATIC_IPV6_IFNAME:
2575 nexthop_ifname_add (rib, si->ifname);
2576 break;
2577 case STATIC_IPV6_GATEWAY_IFNAME:
2578 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2579 break;
2580 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002581 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002582 }
2583 else
2584 {
2585 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002586 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2587
paul718e3742002-12-13 20:15:29 +00002588 rib->type = ZEBRA_ROUTE_STATIC;
2589 rib->distance = si->distance;
2590 rib->metric = 0;
2591 rib->nexthop_num = 0;
2592
2593 switch (si->type)
2594 {
2595 case STATIC_IPV6_GATEWAY:
2596 nexthop_ipv6_add (rib, &si->ipv6);
2597 break;
2598 case STATIC_IPV6_IFNAME:
2599 nexthop_ifname_add (rib, si->ifname);
2600 break;
2601 case STATIC_IPV6_GATEWAY_IFNAME:
2602 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2603 break;
2604 }
2605
hasso81dfcaa2003-05-25 19:21:25 +00002606 /* Save the flags of this static routes (reject, blackhole) */
2607 rib->flags = si->flags;
2608
paul718e3742002-12-13 20:15:29 +00002609 /* Link this rib to the tree. */
2610 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002611 }
2612}
2613
paula1ac18c2005-06-28 17:17:12 +00002614static int
paul718e3742002-12-13 20:15:29 +00002615static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2616{
2617 if (nexthop->type == NEXTHOP_TYPE_IPV6
2618 && si->type == STATIC_IPV6_GATEWAY
2619 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2620 return 1;
2621 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2622 && si->type == STATIC_IPV6_IFNAME
2623 && strcmp (nexthop->ifname, si->ifname) == 0)
2624 return 1;
2625 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2626 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2627 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2628 && strcmp (nexthop->ifname, si->ifname) == 0)
2629 return 1;
paule8e19462006-01-19 20:16:55 +00002630 return 0;
paul718e3742002-12-13 20:15:29 +00002631}
2632
paula1ac18c2005-06-28 17:17:12 +00002633static void
paul718e3742002-12-13 20:15:29 +00002634static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2635{
2636 struct route_table *table;
2637 struct route_node *rn;
2638 struct rib *rib;
2639 struct nexthop *nexthop;
2640
2641 /* Lookup table. */
2642 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2643 if (! table)
2644 return;
2645
2646 /* Lookup existing route with type and distance. */
2647 rn = route_node_lookup (table, (struct prefix *) p);
2648 if (! rn)
2649 return;
2650
2651 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002652 {
2653 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2654 continue;
2655
2656 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2657 break;
2658 }
2659
paul718e3742002-12-13 20:15:29 +00002660 if (! rib)
2661 {
2662 route_unlock_node (rn);
2663 return;
2664 }
2665
2666 /* Lookup nexthop. */
2667 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2668 if (static_ipv6_nexthop_same (nexthop, si))
2669 break;
2670
2671 /* Can't find nexthop. */
2672 if (! nexthop)
2673 {
2674 route_unlock_node (rn);
2675 return;
2676 }
2677
2678 /* Check nexthop. */
2679 if (rib->nexthop_num == 1)
2680 {
2681 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002682 }
2683 else
2684 {
paul6baeb982003-10-28 03:47:15 +00002685 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2686 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002687 nexthop_delete (rib, nexthop);
2688 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002689 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002690 }
paul718e3742002-12-13 20:15:29 +00002691 /* Unlock node. */
2692 route_unlock_node (rn);
2693}
2694
2695/* Add static route into static route configuration. */
2696int
2697static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002698 const char *ifname, u_char flags, u_char distance,
2699 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002700{
2701 struct route_node *rn;
2702 struct static_ipv6 *si;
2703 struct static_ipv6 *pp;
2704 struct static_ipv6 *cp;
2705 struct route_table *stable;
2706
2707 /* Lookup table. */
2708 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2709 if (! stable)
2710 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00002711
2712 if (!gate &&
2713 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
2714 return -1;
2715
2716 if (!ifname &&
2717 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
2718 return -1;
paul718e3742002-12-13 20:15:29 +00002719
2720 /* Lookup static route prefix. */
2721 rn = route_node_get (stable, p);
2722
2723 /* Do nothing if there is a same static route. */
2724 for (si = rn->info; si; si = si->next)
2725 {
2726 if (distance == si->distance
2727 && type == si->type
2728 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2729 && (! ifname || strcmp (ifname, si->ifname) == 0))
2730 {
2731 route_unlock_node (rn);
2732 return 0;
2733 }
2734 }
2735
2736 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002737 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
paul718e3742002-12-13 20:15:29 +00002738
2739 si->type = type;
2740 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002741 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002742
2743 switch (type)
2744 {
2745 case STATIC_IPV6_GATEWAY:
2746 si->ipv6 = *gate;
2747 break;
2748 case STATIC_IPV6_IFNAME:
2749 si->ifname = XSTRDUP (0, ifname);
2750 break;
2751 case STATIC_IPV6_GATEWAY_IFNAME:
2752 si->ipv6 = *gate;
2753 si->ifname = XSTRDUP (0, ifname);
2754 break;
2755 }
2756
2757 /* Add new static route information to the tree with sort by
2758 distance value and gateway address. */
2759 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2760 {
2761 if (si->distance < cp->distance)
2762 break;
2763 if (si->distance > cp->distance)
2764 continue;
2765 }
2766
2767 /* Make linked list. */
2768 if (pp)
2769 pp->next = si;
2770 else
2771 rn->info = si;
2772 if (cp)
2773 cp->prev = si;
2774 si->prev = pp;
2775 si->next = cp;
2776
2777 /* Install into rib. */
2778 static_install_ipv6 (p, si);
2779
2780 return 1;
2781}
2782
2783/* Delete static route from static route configuration. */
2784int
2785static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002786 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002787{
2788 struct route_node *rn;
2789 struct static_ipv6 *si;
2790 struct route_table *stable;
2791
2792 /* Lookup table. */
2793 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2794 if (! stable)
2795 return -1;
2796
2797 /* Lookup static route prefix. */
2798 rn = route_node_lookup (stable, p);
2799 if (! rn)
2800 return 0;
2801
2802 /* Find same static route is the tree */
2803 for (si = rn->info; si; si = si->next)
2804 if (distance == si->distance
2805 && type == si->type
2806 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2807 && (! ifname || strcmp (ifname, si->ifname) == 0))
2808 break;
2809
2810 /* Can't find static route. */
2811 if (! si)
2812 {
2813 route_unlock_node (rn);
2814 return 0;
2815 }
2816
2817 /* Install into rib. */
2818 static_uninstall_ipv6 (p, si);
2819
2820 /* Unlink static route from linked list. */
2821 if (si->prev)
2822 si->prev->next = si->next;
2823 else
2824 rn->info = si->next;
2825 if (si->next)
2826 si->next->prev = si->prev;
2827
2828 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002829 if (ifname)
2830 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00002831 XFREE (MTYPE_STATIC_IPV6, si);
2832
2833 return 1;
2834}
2835#endif /* HAVE_IPV6 */
2836
2837/* RIB update function. */
2838void
paula1ac18c2005-06-28 17:17:12 +00002839rib_update (void)
paul718e3742002-12-13 20:15:29 +00002840{
2841 struct route_node *rn;
2842 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00002843
paul718e3742002-12-13 20:15:29 +00002844 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2845 if (table)
2846 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002847 if (rn->info)
Paul Jakma6d691122006-07-27 21:49:00 +00002848 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002849
2850 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2851 if (table)
2852 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002853 if (rn->info)
Paul Jakma6d691122006-07-27 21:49:00 +00002854 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002855}
2856
paul718e3742002-12-13 20:15:29 +00002857
2858/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00002859static void
paul718e3742002-12-13 20:15:29 +00002860rib_weed_table (struct route_table *table)
2861{
2862 struct route_node *rn;
2863 struct rib *rib;
2864 struct rib *next;
2865
2866 if (table)
2867 for (rn = route_top (table); rn; rn = route_next (rn))
2868 for (rib = rn->info; rib; rib = next)
2869 {
2870 next = rib->next;
2871
Paul Jakma6d691122006-07-27 21:49:00 +00002872 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2873 continue;
2874
paulb21b19c2003-06-15 01:28:29 +00002875 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00002876 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00002877 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002878 }
2879}
2880
2881/* Delete all routes from non main table. */
2882void
paula1ac18c2005-06-28 17:17:12 +00002883rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00002884{
2885 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2886 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2887}
2888
2889/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00002890static void
paul718e3742002-12-13 20:15:29 +00002891rib_sweep_table (struct route_table *table)
2892{
2893 struct route_node *rn;
2894 struct rib *rib;
2895 struct rib *next;
2896 int ret = 0;
2897
2898 if (table)
2899 for (rn = route_top (table); rn; rn = route_next (rn))
2900 for (rib = rn->info; rib; rib = next)
2901 {
2902 next = rib->next;
2903
Paul Jakma6d691122006-07-27 21:49:00 +00002904 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2905 continue;
2906
paul718e3742002-12-13 20:15:29 +00002907 if (rib->type == ZEBRA_ROUTE_KERNEL &&
2908 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
2909 {
2910 ret = rib_uninstall_kernel (rn, rib);
2911 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00002912 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002913 }
2914 }
2915}
2916
2917/* Sweep all RIB tables. */
2918void
paula1ac18c2005-06-28 17:17:12 +00002919rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00002920{
2921 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2922 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2923}
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04002924
2925/* Remove specific by protocol routes from 'table'. */
2926static unsigned long
2927rib_score_proto_table (u_char proto, struct route_table *table)
2928{
2929 struct route_node *rn;
2930 struct rib *rib;
2931 struct rib *next;
2932 unsigned long n = 0;
2933
2934 if (table)
2935 for (rn = route_top (table); rn; rn = route_next (rn))
2936 for (rib = rn->info; rib; rib = next)
2937 {
2938 next = rib->next;
2939 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2940 continue;
2941 if (rib->type == proto)
2942 {
2943 rib_delnode (rn, rib);
2944 n++;
2945 }
2946 }
2947
2948 return n;
2949}
2950
2951/* Remove specific by protocol routes. */
2952unsigned long
2953rib_score_proto (u_char proto)
2954{
2955 return rib_score_proto_table (proto, vrf_table (AFI_IP, SAFI_UNICAST, 0))
2956 +rib_score_proto_table (proto, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2957}
2958
paul718e3742002-12-13 20:15:29 +00002959/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00002960static void
paul718e3742002-12-13 20:15:29 +00002961rib_close_table (struct route_table *table)
2962{
2963 struct route_node *rn;
2964 struct rib *rib;
2965
2966 if (table)
2967 for (rn = route_top (table); rn; rn = route_next (rn))
2968 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002969 {
2970 if (! RIB_SYSTEM_ROUTE (rib)
2971 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2972 rib_uninstall_kernel (rn, rib);
2973 }
paul718e3742002-12-13 20:15:29 +00002974}
2975
2976/* Close all RIB tables. */
2977void
paula1ac18c2005-06-28 17:17:12 +00002978rib_close (void)
paul718e3742002-12-13 20:15:29 +00002979{
2980 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2981 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2982}
2983
2984/* Routing information base initialize. */
2985void
paula1ac18c2005-06-28 17:17:12 +00002986rib_init (void)
paul718e3742002-12-13 20:15:29 +00002987{
paul4d38fdb2005-04-28 17:35:14 +00002988 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00002989 /* VRF initialization. */
2990 vrf_init ();
2991}