blob: 50674ee889f9281fbe9abd387f19035835439cc5 [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;
2039 rib->nexthop_num = 0;
2040
2041 switch (si->type)
paul7021c422003-07-15 12:52:22 +00002042 {
2043 case STATIC_IPV4_GATEWAY:
Paul Jakma7514fb72007-05-02 16:05:35 +00002044 nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
paul7021c422003-07-15 12:52:22 +00002045 break;
2046 case STATIC_IPV4_IFNAME:
2047 nexthop_ifname_add (rib, si->gate.ifname);
2048 break;
2049 case STATIC_IPV4_BLACKHOLE:
2050 nexthop_blackhole_add (rib);
2051 break;
2052 }
paul718e3742002-12-13 20:15:29 +00002053
hasso81dfcaa2003-05-25 19:21:25 +00002054 /* Save the flags of this static routes (reject, blackhole) */
2055 rib->flags = si->flags;
2056
paul718e3742002-12-13 20:15:29 +00002057 /* Link this rib to the tree. */
2058 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002059 }
2060}
2061
paula1ac18c2005-06-28 17:17:12 +00002062static int
paul718e3742002-12-13 20:15:29 +00002063static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2064{
2065 if (nexthop->type == NEXTHOP_TYPE_IPV4
2066 && si->type == STATIC_IPV4_GATEWAY
2067 && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2068 return 1;
2069 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2070 && si->type == STATIC_IPV4_IFNAME
2071 && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2072 return 1;
paul595db7f2003-05-25 21:35:06 +00002073 if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2074 && si->type == STATIC_IPV4_BLACKHOLE)
2075 return 1;
paule8e19462006-01-19 20:16:55 +00002076 return 0;
paul718e3742002-12-13 20:15:29 +00002077}
2078
2079/* Uninstall static route from RIB. */
paula1ac18c2005-06-28 17:17:12 +00002080static void
paul718e3742002-12-13 20:15:29 +00002081static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
2082{
2083 struct route_node *rn;
2084 struct rib *rib;
2085 struct nexthop *nexthop;
2086 struct route_table *table;
2087
2088 /* Lookup table. */
2089 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2090 if (! table)
2091 return;
paul4d38fdb2005-04-28 17:35:14 +00002092
paul718e3742002-12-13 20:15:29 +00002093 /* Lookup existing route with type and distance. */
2094 rn = route_node_lookup (table, p);
2095 if (! rn)
2096 return;
2097
2098 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002099 {
2100 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2101 continue;
2102
2103 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2104 break;
2105 }
paul718e3742002-12-13 20:15:29 +00002106
2107 if (! rib)
2108 {
2109 route_unlock_node (rn);
2110 return;
2111 }
2112
2113 /* Lookup nexthop. */
2114 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2115 if (static_ipv4_nexthop_same (nexthop, si))
2116 break;
2117
2118 /* Can't find nexthop. */
2119 if (! nexthop)
2120 {
2121 route_unlock_node (rn);
2122 return;
2123 }
2124
2125 /* Check nexthop. */
2126 if (rib->nexthop_num == 1)
Paul Jakma6d691122006-07-27 21:49:00 +00002127 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002128 else
2129 {
paul6baeb982003-10-28 03:47:15 +00002130 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2131 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002132 nexthop_delete (rib, nexthop);
2133 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002134 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002135 }
paul718e3742002-12-13 20:15:29 +00002136 /* Unlock node. */
2137 route_unlock_node (rn);
2138}
2139
2140/* Add static route into static route configuration. */
2141int
hasso39db97e2004-10-12 20:50:58 +00002142static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
hasso81dfcaa2003-05-25 19:21:25 +00002143 u_char flags, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002144{
2145 u_char type = 0;
2146 struct route_node *rn;
2147 struct static_ipv4 *si;
2148 struct static_ipv4 *pp;
2149 struct static_ipv4 *cp;
2150 struct static_ipv4 *update = NULL;
2151 struct route_table *stable;
2152
2153 /* Lookup table. */
2154 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2155 if (! stable)
2156 return -1;
2157
2158 /* Lookup static route prefix. */
2159 rn = route_node_get (stable, p);
2160
2161 /* Make flags. */
2162 if (gate)
2163 type = STATIC_IPV4_GATEWAY;
paul368aa3f2003-05-25 23:24:50 +00002164 else if (ifname)
paul718e3742002-12-13 20:15:29 +00002165 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002166 else
2167 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002168
2169 /* Do nothing if there is a same static route. */
2170 for (si = rn->info; si; si = si->next)
2171 {
2172 if (type == si->type
2173 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2174 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2175 {
2176 if (distance == si->distance)
2177 {
2178 route_unlock_node (rn);
2179 return 0;
2180 }
2181 else
2182 update = si;
2183 }
2184 }
2185
Paul Jakma3c0755d2006-12-08 00:53:14 +00002186 /* Distance changed. */
paul718e3742002-12-13 20:15:29 +00002187 if (update)
2188 static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
2189
2190 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002191 si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
paul718e3742002-12-13 20:15:29 +00002192
2193 si->type = type;
2194 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002195 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002196
2197 if (gate)
2198 si->gate.ipv4 = *gate;
2199 if (ifname)
2200 si->gate.ifname = XSTRDUP (0, ifname);
2201
2202 /* Add new static route information to the tree with sort by
2203 distance value and gateway address. */
2204 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2205 {
2206 if (si->distance < cp->distance)
2207 break;
2208 if (si->distance > cp->distance)
2209 continue;
2210 if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2211 {
2212 if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2213 break;
2214 if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2215 continue;
2216 }
2217 }
2218
2219 /* Make linked list. */
2220 if (pp)
2221 pp->next = si;
2222 else
2223 rn->info = si;
2224 if (cp)
2225 cp->prev = si;
2226 si->prev = pp;
2227 si->next = cp;
2228
2229 /* Install into rib. */
2230 static_install_ipv4 (p, si);
2231
2232 return 1;
2233}
2234
2235/* Delete static route from static route configuration. */
2236int
hasso39db97e2004-10-12 20:50:58 +00002237static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
paul718e3742002-12-13 20:15:29 +00002238 u_char distance, u_int32_t vrf_id)
2239{
2240 u_char type = 0;
2241 struct route_node *rn;
2242 struct static_ipv4 *si;
2243 struct route_table *stable;
2244
2245 /* Lookup table. */
2246 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2247 if (! stable)
2248 return -1;
2249
2250 /* Lookup static route prefix. */
2251 rn = route_node_lookup (stable, p);
2252 if (! rn)
2253 return 0;
2254
2255 /* Make flags. */
2256 if (gate)
2257 type = STATIC_IPV4_GATEWAY;
2258 else if (ifname)
2259 type = STATIC_IPV4_IFNAME;
paul595db7f2003-05-25 21:35:06 +00002260 else
2261 type = STATIC_IPV4_BLACKHOLE;
paul718e3742002-12-13 20:15:29 +00002262
2263 /* Find same static route is the tree */
2264 for (si = rn->info; si; si = si->next)
2265 if (type == si->type
2266 && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2267 && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2268 break;
2269
2270 /* Can't find static route. */
2271 if (! si)
2272 {
2273 route_unlock_node (rn);
2274 return 0;
2275 }
2276
2277 /* Install into rib. */
2278 static_uninstall_ipv4 (p, si);
2279
2280 /* Unlink static route from linked list. */
2281 if (si->prev)
2282 si->prev->next = si->next;
2283 else
2284 rn->info = si->next;
2285 if (si->next)
2286 si->next->prev = si->prev;
paul143a3852003-09-29 20:06:13 +00002287 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002288
2289 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002290 if (ifname)
2291 XFREE (0, si->gate.ifname);
paul718e3742002-12-13 20:15:29 +00002292 XFREE (MTYPE_STATIC_IPV4, si);
2293
paul143a3852003-09-29 20:06:13 +00002294 route_unlock_node (rn);
2295
paul718e3742002-12-13 20:15:29 +00002296 return 1;
2297}
2298
2299
2300#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00002301static int
paul718e3742002-12-13 20:15:29 +00002302rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2303 struct in6_addr *gate, unsigned int ifindex, int table)
2304{
hasso726f9b22003-05-25 21:04:54 +00002305 if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2306#if defined (MUSICA) || defined (LINUX)
2307 /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2308 if (p->prefixlen == 96)
2309 return 0;
2310#endif /* MUSICA */
paul718e3742002-12-13 20:15:29 +00002311 return 1;
hasso726f9b22003-05-25 21:04:54 +00002312 }
paul718e3742002-12-13 20:15:29 +00002313 if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
2314 && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
2315 {
2316 kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
2317 return 1;
2318 }
2319 return 0;
2320}
2321
2322int
2323rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
hassobe61c4e2005-08-27 06:05:47 +00002324 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
G.Balajif768f362011-11-26 22:10:39 +04002325 u_int32_t metric, u_char distance, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002326{
2327 struct rib *rib;
2328 struct rib *same = NULL;
2329 struct route_table *table;
2330 struct route_node *rn;
2331 struct nexthop *nexthop;
2332
paul718e3742002-12-13 20:15:29 +00002333 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002334 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002335 if (! table)
2336 return 0;
2337
2338 /* Make sure mask is applied. */
2339 apply_mask_ipv6 (p);
2340
2341 /* Set default distance by route type. */
hassobe61c4e2005-08-27 06:05:47 +00002342 if (!distance)
2343 distance = route_info[type].distance;
paul718e3742002-12-13 20:15:29 +00002344
2345 if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2346 distance = 200;
2347
2348 /* Filter bogus route. */
2349 if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
2350 return 0;
2351
2352 /* Lookup route node.*/
2353 rn = route_node_get (table, (struct prefix *) p);
2354
2355 /* If same type of route are installed, treat it as a implicit
2356 withdraw. */
2357 for (rib = rn->info; rib; rib = rib->next)
2358 {
Paul Jakma6d691122006-07-27 21:49:00 +00002359 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2360 continue;
2361
hassoebf1ead2005-09-21 14:58:20 +00002362 if (rib->type != type)
2363 continue;
2364 if (rib->type != ZEBRA_ROUTE_CONNECT)
paul718e3742002-12-13 20:15:29 +00002365 {
2366 same = rib;
paul718e3742002-12-13 20:15:29 +00002367 break;
2368 }
hassoebf1ead2005-09-21 14:58:20 +00002369 else if ((nexthop = rib->nexthop) &&
2370 nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2371 nexthop->ifindex == ifindex)
2372 {
2373 rib->refcnt++;
2374 return 0;
2375 }
paul718e3742002-12-13 20:15:29 +00002376 }
2377
2378 /* Allocate new rib structure. */
paul4d38fdb2005-04-28 17:35:14 +00002379 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2380
paul718e3742002-12-13 20:15:29 +00002381 rib->type = type;
2382 rib->distance = distance;
2383 rib->flags = flags;
2384 rib->metric = metric;
paulb5f45022003-11-02 07:28:05 +00002385 rib->table = vrf_id;
paul718e3742002-12-13 20:15:29 +00002386 rib->nexthop_num = 0;
2387 rib->uptime = time (NULL);
2388
2389 /* Nexthop settings. */
2390 if (gate)
2391 {
2392 if (ifindex)
2393 nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2394 else
2395 nexthop_ipv6_add (rib, gate);
2396 }
2397 else
2398 nexthop_ifindex_add (rib, ifindex);
2399
2400 /* If this route is kernel route, set FIB flag to the route. */
2401 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2402 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2403 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2404
2405 /* Link new rib to node.*/
2406 rib_addnode (rn, rib);
2407
paul718e3742002-12-13 20:15:29 +00002408 /* Free implicit route.*/
2409 if (same)
paul4d38fdb2005-04-28 17:35:14 +00002410 rib_delnode (rn, same);
2411
2412 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002413 return 0;
2414}
2415
hassoebf1ead2005-09-21 14:58:20 +00002416/* XXX factor with rib_delete_ipv6 */
paul718e3742002-12-13 20:15:29 +00002417int
2418rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
G.Balajif768f362011-11-26 22:10:39 +04002419 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
paul718e3742002-12-13 20:15:29 +00002420{
2421 struct route_table *table;
2422 struct route_node *rn;
2423 struct rib *rib;
2424 struct rib *fib = NULL;
2425 struct rib *same = NULL;
2426 struct nexthop *nexthop;
Stephen Hemminger81cce012009-04-28 14:28:00 -07002427 char buf1[INET6_ADDRSTRLEN];
2428 char buf2[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002429
2430 /* Apply mask. */
2431 apply_mask_ipv6 (p);
2432
2433 /* Lookup table. */
G.Balajif768f362011-11-26 22:10:39 +04002434 table = vrf_table (AFI_IP6, safi, 0);
paul718e3742002-12-13 20:15:29 +00002435 if (! table)
2436 return 0;
paul4d38fdb2005-04-28 17:35:14 +00002437
paul718e3742002-12-13 20:15:29 +00002438 /* Lookup route node. */
2439 rn = route_node_lookup (table, (struct prefix *) p);
2440 if (! rn)
2441 {
2442 if (IS_ZEBRA_DEBUG_KERNEL)
2443 {
2444 if (gate)
ajsb6178002004-12-07 21:12:56 +00002445 zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002446 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002447 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002448 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002449 ifindex);
2450 else
ajsb6178002004-12-07 21:12:56 +00002451 zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002452 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002453 p->prefixlen,
2454 ifindex);
2455 }
2456 return ZEBRA_ERR_RTNOEXIST;
2457 }
2458
2459 /* Lookup same type route. */
2460 for (rib = rn->info; rib; rib = rib->next)
2461 {
Paul Jakma6d691122006-07-27 21:49:00 +00002462 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2463 continue;
2464
paul718e3742002-12-13 20:15:29 +00002465 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2466 fib = rib;
2467
hassoebf1ead2005-09-21 14:58:20 +00002468 if (rib->type != type)
2469 continue;
2470 if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002471 nexthop->type == NEXTHOP_TYPE_IFINDEX)
paul718e3742002-12-13 20:15:29 +00002472 {
Matthias Ferdinand4f1735f2011-12-26 16:35:30 +04002473 if (nexthop->ifindex != ifindex)
2474 continue;
hassoebf1ead2005-09-21 14:58:20 +00002475 if (rib->refcnt)
paul718e3742002-12-13 20:15:29 +00002476 {
hassoebf1ead2005-09-21 14:58:20 +00002477 rib->refcnt--;
2478 route_unlock_node (rn);
2479 route_unlock_node (rn);
2480 return 0;
paul718e3742002-12-13 20:15:29 +00002481 }
hassoebf1ead2005-09-21 14:58:20 +00002482 same = rib;
2483 break;
paul718e3742002-12-13 20:15:29 +00002484 }
hassoebf1ead2005-09-21 14:58:20 +00002485 /* Make sure that the route found has the same gateway. */
2486 else if (gate == NULL ||
2487 ((nexthop = rib->nexthop) &&
2488 (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate) ||
2489 IPV6_ADDR_SAME (&nexthop->rgate.ipv6, gate))))
paul718e3742002-12-13 20:15:29 +00002490 {
hassoebf1ead2005-09-21 14:58:20 +00002491 same = rib;
2492 break;
paul718e3742002-12-13 20:15:29 +00002493 }
2494 }
2495
2496 /* If same type of route can't be found and this message is from
2497 kernel. */
2498 if (! same)
2499 {
2500 if (fib && type == ZEBRA_ROUTE_KERNEL)
2501 {
2502 /* Unset flags. */
2503 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2504 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2505
2506 UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2507 }
2508 else
2509 {
2510 if (IS_ZEBRA_DEBUG_KERNEL)
2511 {
2512 if (gate)
ajsb6178002004-12-07 21:12:56 +00002513 zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002514 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002515 p->prefixlen,
Stephen Hemminger81cce012009-04-28 14:28:00 -07002516 inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002517 ifindex,
2518 type);
2519 else
ajsb6178002004-12-07 21:12:56 +00002520 zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
Stephen Hemminger81cce012009-04-28 14:28:00 -07002521 inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +00002522 p->prefixlen,
2523 ifindex,
2524 type);
2525 }
2526 route_unlock_node (rn);
2527 return ZEBRA_ERR_RTNOEXIST;
2528 }
2529 }
2530
2531 if (same)
2532 rib_delnode (rn, same);
paul4d38fdb2005-04-28 17:35:14 +00002533
paul718e3742002-12-13 20:15:29 +00002534 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002535 return 0;
2536}
2537
2538/* Install static route into rib. */
paula1ac18c2005-06-28 17:17:12 +00002539static void
paul718e3742002-12-13 20:15:29 +00002540static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2541{
2542 struct rib *rib;
2543 struct route_table *table;
2544 struct route_node *rn;
2545
2546 /* Lookup table. */
2547 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2548 if (! table)
2549 return;
2550
2551 /* Lookup existing route */
2552 rn = route_node_get (table, p);
2553 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002554 {
2555 if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2556 continue;
2557
2558 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2559 break;
2560 }
paul718e3742002-12-13 20:15:29 +00002561
2562 if (rib)
2563 {
2564 /* Same distance static route is there. Update it with new
2565 nexthop. */
paul718e3742002-12-13 20:15:29 +00002566 route_unlock_node (rn);
2567
2568 switch (si->type)
2569 {
2570 case STATIC_IPV6_GATEWAY:
2571 nexthop_ipv6_add (rib, &si->ipv6);
2572 break;
2573 case STATIC_IPV6_IFNAME:
2574 nexthop_ifname_add (rib, si->ifname);
2575 break;
2576 case STATIC_IPV6_GATEWAY_IFNAME:
2577 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2578 break;
2579 }
Paul Jakma3c0755d2006-12-08 00:53:14 +00002580 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002581 }
2582 else
2583 {
2584 /* This is new static route. */
paul4d38fdb2005-04-28 17:35:14 +00002585 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2586
paul718e3742002-12-13 20:15:29 +00002587 rib->type = ZEBRA_ROUTE_STATIC;
2588 rib->distance = si->distance;
2589 rib->metric = 0;
2590 rib->nexthop_num = 0;
2591
2592 switch (si->type)
2593 {
2594 case STATIC_IPV6_GATEWAY:
2595 nexthop_ipv6_add (rib, &si->ipv6);
2596 break;
2597 case STATIC_IPV6_IFNAME:
2598 nexthop_ifname_add (rib, si->ifname);
2599 break;
2600 case STATIC_IPV6_GATEWAY_IFNAME:
2601 nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2602 break;
2603 }
2604
hasso81dfcaa2003-05-25 19:21:25 +00002605 /* Save the flags of this static routes (reject, blackhole) */
2606 rib->flags = si->flags;
2607
paul718e3742002-12-13 20:15:29 +00002608 /* Link this rib to the tree. */
2609 rib_addnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002610 }
2611}
2612
paula1ac18c2005-06-28 17:17:12 +00002613static int
paul718e3742002-12-13 20:15:29 +00002614static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2615{
2616 if (nexthop->type == NEXTHOP_TYPE_IPV6
2617 && si->type == STATIC_IPV6_GATEWAY
2618 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2619 return 1;
2620 if (nexthop->type == NEXTHOP_TYPE_IFNAME
2621 && si->type == STATIC_IPV6_IFNAME
2622 && strcmp (nexthop->ifname, si->ifname) == 0)
2623 return 1;
2624 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2625 && si->type == STATIC_IPV6_GATEWAY_IFNAME
2626 && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2627 && strcmp (nexthop->ifname, si->ifname) == 0)
2628 return 1;
paule8e19462006-01-19 20:16:55 +00002629 return 0;
paul718e3742002-12-13 20:15:29 +00002630}
2631
paula1ac18c2005-06-28 17:17:12 +00002632static void
paul718e3742002-12-13 20:15:29 +00002633static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2634{
2635 struct route_table *table;
2636 struct route_node *rn;
2637 struct rib *rib;
2638 struct nexthop *nexthop;
2639
2640 /* Lookup table. */
2641 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2642 if (! table)
2643 return;
2644
2645 /* Lookup existing route with type and distance. */
2646 rn = route_node_lookup (table, (struct prefix *) p);
2647 if (! rn)
2648 return;
2649
2650 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002651 {
2652 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2653 continue;
2654
2655 if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2656 break;
2657 }
2658
paul718e3742002-12-13 20:15:29 +00002659 if (! rib)
2660 {
2661 route_unlock_node (rn);
2662 return;
2663 }
2664
2665 /* Lookup nexthop. */
2666 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2667 if (static_ipv6_nexthop_same (nexthop, si))
2668 break;
2669
2670 /* Can't find nexthop. */
2671 if (! nexthop)
2672 {
2673 route_unlock_node (rn);
2674 return;
2675 }
2676
2677 /* Check nexthop. */
2678 if (rib->nexthop_num == 1)
2679 {
2680 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002681 }
2682 else
2683 {
paul6baeb982003-10-28 03:47:15 +00002684 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2685 rib_uninstall (rn, rib);
paul319572c2005-09-21 12:30:08 +00002686 nexthop_delete (rib, nexthop);
2687 nexthop_free (nexthop);
Paul Jakma6d691122006-07-27 21:49:00 +00002688 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002689 }
paul718e3742002-12-13 20:15:29 +00002690 /* Unlock node. */
2691 route_unlock_node (rn);
2692}
2693
2694/* Add static route into static route configuration. */
2695int
2696static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002697 const char *ifname, u_char flags, u_char distance,
2698 u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002699{
2700 struct route_node *rn;
2701 struct static_ipv6 *si;
2702 struct static_ipv6 *pp;
2703 struct static_ipv6 *cp;
2704 struct route_table *stable;
2705
2706 /* Lookup table. */
2707 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2708 if (! stable)
2709 return -1;
Paul Jakma27b47252006-07-02 16:38:54 +00002710
2711 if (!gate &&
2712 (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
2713 return -1;
2714
2715 if (!ifname &&
2716 (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
2717 return -1;
paul718e3742002-12-13 20:15:29 +00002718
2719 /* Lookup static route prefix. */
2720 rn = route_node_get (stable, p);
2721
2722 /* Do nothing if there is a same static route. */
2723 for (si = rn->info; si; si = si->next)
2724 {
2725 if (distance == si->distance
2726 && type == si->type
2727 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2728 && (! ifname || strcmp (ifname, si->ifname) == 0))
2729 {
2730 route_unlock_node (rn);
2731 return 0;
2732 }
2733 }
2734
2735 /* Make new static route structure. */
Stephen Hemminger393deb92008-08-18 14:13:29 -07002736 si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
paul718e3742002-12-13 20:15:29 +00002737
2738 si->type = type;
2739 si->distance = distance;
hasso81dfcaa2003-05-25 19:21:25 +00002740 si->flags = flags;
paul718e3742002-12-13 20:15:29 +00002741
2742 switch (type)
2743 {
2744 case STATIC_IPV6_GATEWAY:
2745 si->ipv6 = *gate;
2746 break;
2747 case STATIC_IPV6_IFNAME:
2748 si->ifname = XSTRDUP (0, ifname);
2749 break;
2750 case STATIC_IPV6_GATEWAY_IFNAME:
2751 si->ipv6 = *gate;
2752 si->ifname = XSTRDUP (0, ifname);
2753 break;
2754 }
2755
2756 /* Add new static route information to the tree with sort by
2757 distance value and gateway address. */
2758 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2759 {
2760 if (si->distance < cp->distance)
2761 break;
2762 if (si->distance > cp->distance)
2763 continue;
2764 }
2765
2766 /* Make linked list. */
2767 if (pp)
2768 pp->next = si;
2769 else
2770 rn->info = si;
2771 if (cp)
2772 cp->prev = si;
2773 si->prev = pp;
2774 si->next = cp;
2775
2776 /* Install into rib. */
2777 static_install_ipv6 (p, si);
2778
2779 return 1;
2780}
2781
2782/* Delete static route from static route configuration. */
2783int
2784static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
hasso39db97e2004-10-12 20:50:58 +00002785 const char *ifname, u_char distance, u_int32_t vrf_id)
paul718e3742002-12-13 20:15:29 +00002786{
2787 struct route_node *rn;
2788 struct static_ipv6 *si;
2789 struct route_table *stable;
2790
2791 /* Lookup table. */
2792 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2793 if (! stable)
2794 return -1;
2795
2796 /* Lookup static route prefix. */
2797 rn = route_node_lookup (stable, p);
2798 if (! rn)
2799 return 0;
2800
2801 /* Find same static route is the tree */
2802 for (si = rn->info; si; si = si->next)
2803 if (distance == si->distance
2804 && type == si->type
2805 && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2806 && (! ifname || strcmp (ifname, si->ifname) == 0))
2807 break;
2808
2809 /* Can't find static route. */
2810 if (! si)
2811 {
2812 route_unlock_node (rn);
2813 return 0;
2814 }
2815
2816 /* Install into rib. */
2817 static_uninstall_ipv6 (p, si);
2818
2819 /* Unlink static route from linked list. */
2820 if (si->prev)
2821 si->prev->next = si->next;
2822 else
2823 rn->info = si->next;
2824 if (si->next)
2825 si->next->prev = si->prev;
2826
2827 /* Free static route configuration. */
paula0f6acd2003-05-14 18:29:13 +00002828 if (ifname)
2829 XFREE (0, si->ifname);
paul718e3742002-12-13 20:15:29 +00002830 XFREE (MTYPE_STATIC_IPV6, si);
2831
2832 return 1;
2833}
2834#endif /* HAVE_IPV6 */
2835
2836/* RIB update function. */
2837void
paula1ac18c2005-06-28 17:17:12 +00002838rib_update (void)
paul718e3742002-12-13 20:15:29 +00002839{
2840 struct route_node *rn;
2841 struct route_table *table;
paul4d38fdb2005-04-28 17:35:14 +00002842
paul718e3742002-12-13 20:15:29 +00002843 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2844 if (table)
2845 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002846 if (rn->info)
Paul Jakma6d691122006-07-27 21:49:00 +00002847 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002848
2849 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2850 if (table)
2851 for (rn = route_top (table); rn; rn = route_next (rn))
paul4d38fdb2005-04-28 17:35:14 +00002852 if (rn->info)
Paul Jakma6d691122006-07-27 21:49:00 +00002853 rib_queue_add (&zebrad, rn);
paul718e3742002-12-13 20:15:29 +00002854}
2855
paul718e3742002-12-13 20:15:29 +00002856
2857/* Remove all routes which comes from non main table. */
paula1ac18c2005-06-28 17:17:12 +00002858static void
paul718e3742002-12-13 20:15:29 +00002859rib_weed_table (struct route_table *table)
2860{
2861 struct route_node *rn;
2862 struct rib *rib;
2863 struct rib *next;
2864
2865 if (table)
2866 for (rn = route_top (table); rn; rn = route_next (rn))
2867 for (rib = rn->info; rib; rib = next)
2868 {
2869 next = rib->next;
2870
Paul Jakma6d691122006-07-27 21:49:00 +00002871 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2872 continue;
2873
paulb21b19c2003-06-15 01:28:29 +00002874 if (rib->table != zebrad.rtm_table_default &&
paul718e3742002-12-13 20:15:29 +00002875 rib->table != RT_TABLE_MAIN)
paul4d38fdb2005-04-28 17:35:14 +00002876 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002877 }
2878}
2879
2880/* Delete all routes from non main table. */
2881void
paula1ac18c2005-06-28 17:17:12 +00002882rib_weed_tables (void)
paul718e3742002-12-13 20:15:29 +00002883{
2884 rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2885 rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2886}
2887
2888/* Delete self installed routes after zebra is relaunched. */
paula1ac18c2005-06-28 17:17:12 +00002889static void
paul718e3742002-12-13 20:15:29 +00002890rib_sweep_table (struct route_table *table)
2891{
2892 struct route_node *rn;
2893 struct rib *rib;
2894 struct rib *next;
2895 int ret = 0;
2896
2897 if (table)
2898 for (rn = route_top (table); rn; rn = route_next (rn))
2899 for (rib = rn->info; rib; rib = next)
2900 {
2901 next = rib->next;
2902
Paul Jakma6d691122006-07-27 21:49:00 +00002903 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2904 continue;
2905
paul718e3742002-12-13 20:15:29 +00002906 if (rib->type == ZEBRA_ROUTE_KERNEL &&
2907 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
2908 {
2909 ret = rib_uninstall_kernel (rn, rib);
2910 if (! ret)
paul4d38fdb2005-04-28 17:35:14 +00002911 rib_delnode (rn, rib);
paul718e3742002-12-13 20:15:29 +00002912 }
2913 }
2914}
2915
2916/* Sweep all RIB tables. */
2917void
paula1ac18c2005-06-28 17:17:12 +00002918rib_sweep_route (void)
paul718e3742002-12-13 20:15:29 +00002919{
2920 rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2921 rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2922}
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04002923
2924/* Remove specific by protocol routes from 'table'. */
2925static unsigned long
2926rib_score_proto_table (u_char proto, struct route_table *table)
2927{
2928 struct route_node *rn;
2929 struct rib *rib;
2930 struct rib *next;
2931 unsigned long n = 0;
2932
2933 if (table)
2934 for (rn = route_top (table); rn; rn = route_next (rn))
2935 for (rib = rn->info; rib; rib = next)
2936 {
2937 next = rib->next;
2938 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2939 continue;
2940 if (rib->type == proto)
2941 {
2942 rib_delnode (rn, rib);
2943 n++;
2944 }
2945 }
2946
2947 return n;
2948}
2949
2950/* Remove specific by protocol routes. */
2951unsigned long
2952rib_score_proto (u_char proto)
2953{
2954 return rib_score_proto_table (proto, vrf_table (AFI_IP, SAFI_UNICAST, 0))
2955 +rib_score_proto_table (proto, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2956}
2957
paul718e3742002-12-13 20:15:29 +00002958/* Close RIB and clean up kernel routes. */
paula1ac18c2005-06-28 17:17:12 +00002959static void
paul718e3742002-12-13 20:15:29 +00002960rib_close_table (struct route_table *table)
2961{
2962 struct route_node *rn;
2963 struct rib *rib;
2964
2965 if (table)
2966 for (rn = route_top (table); rn; rn = route_next (rn))
2967 for (rib = rn->info; rib; rib = rib->next)
Paul Jakma6d691122006-07-27 21:49:00 +00002968 {
2969 if (! RIB_SYSTEM_ROUTE (rib)
2970 && CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2971 rib_uninstall_kernel (rn, rib);
2972 }
paul718e3742002-12-13 20:15:29 +00002973}
2974
2975/* Close all RIB tables. */
2976void
paula1ac18c2005-06-28 17:17:12 +00002977rib_close (void)
paul718e3742002-12-13 20:15:29 +00002978{
2979 rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
2980 rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
2981}
2982
2983/* Routing information base initialize. */
2984void
paula1ac18c2005-06-28 17:17:12 +00002985rib_init (void)
paul718e3742002-12-13 20:15:29 +00002986{
paul4d38fdb2005-04-28 17:35:14 +00002987 rib_queue_init (&zebrad);
paul718e3742002-12-13 20:15:29 +00002988 /* VRF initialization. */
2989 vrf_init ();
2990}