Annotation of embedaddon/quagga/zebra/zebra_rib.c, revision 1.1.1.3
1.1 misho 1: /* 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"
32: #include "linklist.h"
33: #include "thread.h"
34: #include "workqueue.h"
35: #include "prefix.h"
36: #include "routemap.h"
37:
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"
1.1.1.3 ! misho 43: #include "zebra/zebra_fpm.h"
1.1 misho 44:
45: /* Default rtm_table for all clients */
46: extern struct zebra_t zebrad;
47:
48: /* Hold time for RIB process, should be very minimal.
49: * it is useful to able to set it otherwise for testing, hence exported
50: * as global here for test-rig code.
51: */
52: int rib_process_hold_time = 10;
53:
54: /* Each route type's string and default distance value. */
55: static const struct
56: {
57: int key;
58: int distance;
1.1.1.2 misho 59: } route_info[ZEBRA_ROUTE_MAX] =
1.1 misho 60: {
1.1.1.2 misho 61: [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0},
62: [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0},
63: [ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0},
64: [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1},
65: [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120},
66: [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120},
67: [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110},
68: [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110},
69: [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115},
70: [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */},
71: [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 95},
72: /* no entry/default: 150 */
1.1 misho 73: };
74:
75: /* Vector for routing table. */
76: static vector vrf_vector;
77:
1.1.1.3 ! misho 78: /*
! 79: * vrf_table_create
! 80: */
! 81: static void
! 82: vrf_table_create (struct vrf *vrf, afi_t afi, safi_t safi)
! 83: {
! 84: rib_table_info_t *info;
! 85: struct route_table *table;
! 86:
! 87: assert (!vrf->table[afi][safi]);
! 88:
! 89: table = route_table_init ();
! 90: vrf->table[afi][safi] = table;
! 91:
! 92: info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
! 93: info->vrf = vrf;
! 94: info->afi = afi;
! 95: info->safi = safi;
! 96: table->info = info;
! 97: }
! 98:
1.1 misho 99: /* Allocate new VRF. */
100: static struct vrf *
101: vrf_alloc (const char *name)
102: {
103: struct vrf *vrf;
104:
105: vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
106:
107: /* Put name. */
108: if (name)
109: vrf->name = XSTRDUP (MTYPE_VRF_NAME, name);
110:
111: /* Allocate routing table and static table. */
1.1.1.3 ! misho 112: vrf_table_create (vrf, AFI_IP, SAFI_UNICAST);
! 113: vrf_table_create (vrf, AFI_IP6, SAFI_UNICAST);
1.1 misho 114: vrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
115: vrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
1.1.1.3 ! misho 116: vrf_table_create (vrf, AFI_IP, SAFI_MULTICAST);
! 117: vrf_table_create (vrf, AFI_IP6, SAFI_MULTICAST);
1.1.1.2 misho 118: vrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
119: vrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
120:
1.1 misho 121:
122: return vrf;
123: }
124:
125: /* Lookup VRF by identifier. */
126: struct vrf *
127: vrf_lookup (u_int32_t id)
128: {
129: return vector_lookup (vrf_vector, id);
130: }
131:
132: /* Initialize VRF. */
133: static void
134: vrf_init (void)
135: {
136: struct vrf *default_table;
137:
138: /* Allocate VRF vector. */
139: vrf_vector = vector_init (1);
140:
141: /* Allocate default main table. */
142: default_table = vrf_alloc ("Default-IP-Routing-Table");
143:
144: /* Default table index must be 0. */
145: vector_set_index (vrf_vector, 0, default_table);
146: }
147:
148: /* Lookup route table. */
149: struct route_table *
150: vrf_table (afi_t afi, safi_t safi, u_int32_t id)
151: {
152: struct vrf *vrf;
153:
154: vrf = vrf_lookup (id);
155: if (! vrf)
156: return NULL;
157:
1.1.1.3 ! misho 158: if( afi >= AFI_MAX || safi >= SAFI_MAX )
! 159: return NULL;
! 160:
1.1 misho 161: return vrf->table[afi][safi];
162: }
163:
164: /* Lookup static route table. */
165: struct route_table *
166: vrf_static_table (afi_t afi, safi_t safi, u_int32_t id)
167: {
168: struct vrf *vrf;
169:
170: vrf = vrf_lookup (id);
171: if (! vrf)
172: return NULL;
173:
1.1.1.3 ! misho 174: if( afi >= AFI_MAX || safi >= SAFI_MAX )
! 175: return NULL;
! 176:
1.1 misho 177: return vrf->stable[afi][safi];
178: }
179:
1.1.1.3 ! misho 180: /*
! 181: * nexthop_type_to_str
! 182: */
! 183: const char *
! 184: nexthop_type_to_str (enum nexthop_types_t nh_type)
! 185: {
! 186: static const char *desc[] = {
! 187: "none",
! 188: "Directly connected",
! 189: "Interface route",
! 190: "IPv4 nexthop",
! 191: "IPv4 nexthop with ifindex",
! 192: "IPv4 nexthop with ifname",
! 193: "IPv6 nexthop",
! 194: "IPv6 nexthop with ifindex",
! 195: "IPv6 nexthop with ifname",
! 196: "Null0 nexthop",
! 197: };
! 198:
! 199: if (nh_type >= ZEBRA_NUM_OF (desc))
! 200: return "<Invalid nh type>";
! 201:
! 202: return desc[nh_type];
! 203: }
! 204:
1.1 misho 205: /* Add nexthop to the end of the list. */
206: static void
207: nexthop_add (struct rib *rib, struct nexthop *nexthop)
208: {
209: struct nexthop *last;
210:
211: for (last = rib->nexthop; last && last->next; last = last->next)
212: ;
213: if (last)
214: last->next = nexthop;
215: else
216: rib->nexthop = nexthop;
217: nexthop->prev = last;
218:
219: rib->nexthop_num++;
220: }
221:
222: /* Delete specified nexthop from the list. */
223: static void
224: nexthop_delete (struct rib *rib, struct nexthop *nexthop)
225: {
226: if (nexthop->next)
227: nexthop->next->prev = nexthop->prev;
228: if (nexthop->prev)
229: nexthop->prev->next = nexthop->next;
230: else
231: rib->nexthop = nexthop->next;
232: rib->nexthop_num--;
233: }
234:
235: /* Free nexthop. */
236: static void
237: nexthop_free (struct nexthop *nexthop)
238: {
239: if (nexthop->ifname)
240: XFREE (0, nexthop->ifname);
241: XFREE (MTYPE_NEXTHOP, nexthop);
242: }
243:
244: struct nexthop *
245: nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
246: {
247: struct nexthop *nexthop;
248:
249: nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
250: nexthop->type = NEXTHOP_TYPE_IFINDEX;
251: nexthop->ifindex = ifindex;
252:
253: nexthop_add (rib, nexthop);
254:
255: return nexthop;
256: }
257:
258: struct nexthop *
259: nexthop_ifname_add (struct rib *rib, char *ifname)
260: {
261: struct nexthop *nexthop;
262:
263: nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
264: nexthop->type = NEXTHOP_TYPE_IFNAME;
265: nexthop->ifname = XSTRDUP (0, ifname);
266:
267: nexthop_add (rib, nexthop);
268:
269: return nexthop;
270: }
271:
272: struct nexthop *
273: nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src)
274: {
275: struct nexthop *nexthop;
276:
277: nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
278: nexthop->type = NEXTHOP_TYPE_IPV4;
279: nexthop->gate.ipv4 = *ipv4;
280: if (src)
281: nexthop->src.ipv4 = *src;
282:
283: nexthop_add (rib, nexthop);
284:
285: return nexthop;
286: }
287:
1.1.1.2 misho 288: struct nexthop *
1.1 misho 289: nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
290: struct in_addr *src, unsigned int ifindex)
291: {
292: struct nexthop *nexthop;
293:
294: nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
295: nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
296: nexthop->gate.ipv4 = *ipv4;
297: if (src)
298: nexthop->src.ipv4 = *src;
299: nexthop->ifindex = ifindex;
300:
301: nexthop_add (rib, nexthop);
302:
303: return nexthop;
304: }
305:
306: #ifdef HAVE_IPV6
307: struct nexthop *
308: nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
309: {
310: struct nexthop *nexthop;
311:
312: nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
313: nexthop->type = NEXTHOP_TYPE_IPV6;
314: nexthop->gate.ipv6 = *ipv6;
315:
316: nexthop_add (rib, nexthop);
317:
318: return nexthop;
319: }
320:
321: static struct nexthop *
322: nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
323: char *ifname)
324: {
325: struct nexthop *nexthop;
326:
327: nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
328: nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
329: nexthop->gate.ipv6 = *ipv6;
330: nexthop->ifname = XSTRDUP (0, ifname);
331:
332: nexthop_add (rib, nexthop);
333:
334: return nexthop;
335: }
336:
337: static struct nexthop *
338: nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
339: unsigned int ifindex)
340: {
341: struct nexthop *nexthop;
342:
343: nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
344: nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
345: nexthop->gate.ipv6 = *ipv6;
346: nexthop->ifindex = ifindex;
347:
348: nexthop_add (rib, nexthop);
349:
350: return nexthop;
351: }
352: #endif /* HAVE_IPV6 */
353:
354: struct nexthop *
355: nexthop_blackhole_add (struct rib *rib)
356: {
357: struct nexthop *nexthop;
358:
359: nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
360: nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
361: SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
362:
363: nexthop_add (rib, nexthop);
364:
365: return nexthop;
366: }
367:
368: /* If force flag is not set, do not modify falgs at all for uninstall
369: the route from FIB. */
370: static int
371: nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
372: struct route_node *top)
373: {
374: struct prefix_ipv4 p;
375: struct route_table *table;
376: struct route_node *rn;
377: struct rib *match;
378: struct nexthop *newhop;
379:
380: if (nexthop->type == NEXTHOP_TYPE_IPV4)
381: nexthop->ifindex = 0;
382:
383: if (set)
384: UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
385:
386: /* Make lookup prefix. */
387: memset (&p, 0, sizeof (struct prefix_ipv4));
388: p.family = AF_INET;
389: p.prefixlen = IPV4_MAX_PREFIXLEN;
390: p.prefix = nexthop->gate.ipv4;
391:
392: /* Lookup table. */
393: table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
394: if (! table)
395: return 0;
396:
397: rn = route_node_match (table, (struct prefix *) &p);
398: while (rn)
399: {
400: route_unlock_node (rn);
401:
402: /* If lookup self prefix return immediately. */
403: if (rn == top)
404: return 0;
405:
406: /* Pick up selected route. */
1.1.1.3 ! misho 407: RNODE_FOREACH_RIB (rn, match)
1.1 misho 408: {
409: if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
410: continue;
411: if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
412: break;
413: }
414:
415: /* If there is no selected route or matched route is EGP, go up
416: tree. */
417: if (! match
418: || match->type == ZEBRA_ROUTE_BGP)
419: {
420: do {
421: rn = rn->parent;
422: } while (rn && rn->info == NULL);
423: if (rn)
424: route_lock_node (rn);
425: }
426: else
427: {
428: if (match->type == ZEBRA_ROUTE_CONNECT)
429: {
430: /* Directly point connected route. */
431: newhop = match->nexthop;
432: if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
433: nexthop->ifindex = newhop->ifindex;
434:
435: return 1;
436: }
437: else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
438: {
439: for (newhop = match->nexthop; newhop; newhop = newhop->next)
440: if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
441: && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
442: {
443: if (set)
444: {
445: SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
446: nexthop->rtype = newhop->type;
447: if (newhop->type == NEXTHOP_TYPE_IPV4 ||
448: newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
449: nexthop->rgate.ipv4 = newhop->gate.ipv4;
450: if (newhop->type == NEXTHOP_TYPE_IFINDEX
451: || newhop->type == NEXTHOP_TYPE_IFNAME
452: || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
453: nexthop->rifindex = newhop->ifindex;
454: }
455: return 1;
456: }
457: return 0;
458: }
459: else
460: {
461: return 0;
462: }
463: }
464: }
465: return 0;
466: }
467:
468: #ifdef HAVE_IPV6
469: /* If force flag is not set, do not modify falgs at all for uninstall
470: the route from FIB. */
471: static int
472: nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
473: struct route_node *top)
474: {
475: struct prefix_ipv6 p;
476: struct route_table *table;
477: struct route_node *rn;
478: struct rib *match;
479: struct nexthop *newhop;
480:
481: if (nexthop->type == NEXTHOP_TYPE_IPV6)
482: nexthop->ifindex = 0;
483:
484: if (set)
485: UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
486:
487: /* Make lookup prefix. */
488: memset (&p, 0, sizeof (struct prefix_ipv6));
489: p.family = AF_INET6;
490: p.prefixlen = IPV6_MAX_PREFIXLEN;
491: p.prefix = nexthop->gate.ipv6;
492:
493: /* Lookup table. */
494: table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
495: if (! table)
496: return 0;
497:
498: rn = route_node_match (table, (struct prefix *) &p);
499: while (rn)
500: {
501: route_unlock_node (rn);
502:
503: /* If lookup self prefix return immediately. */
504: if (rn == top)
505: return 0;
506:
507: /* Pick up selected route. */
1.1.1.3 ! misho 508: RNODE_FOREACH_RIB (rn, match)
1.1 misho 509: {
510: if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
511: continue;
512: if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
513: break;
514: }
515:
516: /* If there is no selected route or matched route is EGP, go up
517: tree. */
518: if (! match
519: || match->type == ZEBRA_ROUTE_BGP)
520: {
521: do {
522: rn = rn->parent;
523: } while (rn && rn->info == NULL);
524: if (rn)
525: route_lock_node (rn);
526: }
527: else
528: {
529: if (match->type == ZEBRA_ROUTE_CONNECT)
530: {
531: /* Directly point connected route. */
532: newhop = match->nexthop;
533:
534: if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
535: nexthop->ifindex = newhop->ifindex;
536:
537: return 1;
538: }
539: else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
540: {
541: for (newhop = match->nexthop; newhop; newhop = newhop->next)
542: if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
543: && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
544: {
545: if (set)
546: {
547: SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
548: nexthop->rtype = newhop->type;
549: if (newhop->type == NEXTHOP_TYPE_IPV6
550: || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
551: || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
552: nexthop->rgate.ipv6 = newhop->gate.ipv6;
553: if (newhop->type == NEXTHOP_TYPE_IFINDEX
554: || newhop->type == NEXTHOP_TYPE_IFNAME
555: || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
556: || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
557: nexthop->rifindex = newhop->ifindex;
558: }
559: return 1;
560: }
561: return 0;
562: }
563: else
564: {
565: return 0;
566: }
567: }
568: }
569: return 0;
570: }
571: #endif /* HAVE_IPV6 */
572:
573: struct rib *
574: rib_match_ipv4 (struct in_addr addr)
575: {
576: struct prefix_ipv4 p;
577: struct route_table *table;
578: struct route_node *rn;
579: struct rib *match;
580: struct nexthop *newhop;
581:
582: /* Lookup table. */
583: table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
584: if (! table)
585: return 0;
586:
587: memset (&p, 0, sizeof (struct prefix_ipv4));
588: p.family = AF_INET;
589: p.prefixlen = IPV4_MAX_PREFIXLEN;
590: p.prefix = addr;
591:
592: rn = route_node_match (table, (struct prefix *) &p);
593:
594: while (rn)
595: {
596: route_unlock_node (rn);
597:
598: /* Pick up selected route. */
1.1.1.3 ! misho 599: RNODE_FOREACH_RIB (rn, match)
1.1 misho 600: {
601: if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
602: continue;
603: if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
604: break;
605: }
606:
607: /* If there is no selected route or matched route is EGP, go up
608: tree. */
609: if (! match
610: || match->type == ZEBRA_ROUTE_BGP)
611: {
612: do {
613: rn = rn->parent;
614: } while (rn && rn->info == NULL);
615: if (rn)
616: route_lock_node (rn);
617: }
618: else
619: {
620: if (match->type == ZEBRA_ROUTE_CONNECT)
621: /* Directly point connected route. */
622: return match;
623: else
624: {
625: for (newhop = match->nexthop; newhop; newhop = newhop->next)
626: if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
627: return match;
628: return NULL;
629: }
630: }
631: }
632: return NULL;
633: }
634:
635: struct rib *
636: rib_lookup_ipv4 (struct prefix_ipv4 *p)
637: {
638: struct route_table *table;
639: struct route_node *rn;
640: struct rib *match;
641: struct nexthop *nexthop;
642:
643: /* Lookup table. */
644: table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
645: if (! table)
646: return 0;
647:
648: rn = route_node_lookup (table, (struct prefix *) p);
649:
650: /* No route for this prefix. */
651: if (! rn)
652: return NULL;
653:
654: /* Unlock node. */
655: route_unlock_node (rn);
656:
1.1.1.3 ! misho 657: RNODE_FOREACH_RIB (rn, match)
1.1 misho 658: {
659: if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
660: continue;
661: if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
662: break;
663: }
664:
665: if (! match || match->type == ZEBRA_ROUTE_BGP)
666: return NULL;
667:
668: if (match->type == ZEBRA_ROUTE_CONNECT)
669: return match;
670:
671: for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
672: if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
673: return match;
674:
675: return NULL;
676: }
677:
678: /*
679: * This clone function, unlike its original rib_lookup_ipv4(), checks
680: * if specified IPv4 route record (prefix/mask -> gate) exists in
681: * the whole RIB and has ZEBRA_FLAG_SELECTED set.
682: *
683: * Return values:
684: * -1: error
685: * 0: exact match found
686: * 1: a match was found with a different gate
687: * 2: connected route found
688: * 3: no matches found
689: */
690: int
691: rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
692: {
693: struct route_table *table;
694: struct route_node *rn;
695: struct rib *match;
696: struct nexthop *nexthop;
697:
698: /* Lookup table. */
699: table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
700: if (! table)
701: return ZEBRA_RIB_LOOKUP_ERROR;
702:
703: /* Scan the RIB table for exactly matching RIB entry. */
704: rn = route_node_lookup (table, (struct prefix *) p);
705:
706: /* No route for this prefix. */
707: if (! rn)
708: return ZEBRA_RIB_NOTFOUND;
709:
710: /* Unlock node. */
711: route_unlock_node (rn);
712:
713: /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
1.1.1.3 ! misho 714: RNODE_FOREACH_RIB (rn, match)
1.1 misho 715: {
716: if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
717: continue;
718: if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
719: break;
720: }
721:
722: /* None such found :( */
723: if (!match)
724: return ZEBRA_RIB_NOTFOUND;
725:
726: if (match->type == ZEBRA_ROUTE_CONNECT)
727: return ZEBRA_RIB_FOUND_CONNECTED;
728:
729: /* Ok, we have a cood candidate, let's check it's nexthop list... */
730: for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
731: if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
732: {
733: /* We are happy with either direct or recursive hexthop */
1.1.1.3 ! misho 734: if (nexthop->gate.ipv4.s_addr == sockunion2ip (qgate) ||
! 735: nexthop->rgate.ipv4.s_addr == sockunion2ip (qgate))
1.1 misho 736: return ZEBRA_RIB_FOUND_EXACT;
737: else
738: {
739: if (IS_ZEBRA_DEBUG_RIB)
740: {
741: char gate_buf[INET_ADDRSTRLEN], rgate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
742: inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
743: inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, rgate_buf, INET_ADDRSTRLEN);
1.1.1.3 ! misho 744: inet_ntop (AF_INET, &sockunion2ip (qgate), qgate_buf, INET_ADDRSTRLEN);
1.1 misho 745: zlog_debug ("%s: qgate == %s, gate == %s, rgate == %s", __func__, qgate_buf, gate_buf, rgate_buf);
746: }
747: return ZEBRA_RIB_FOUND_NOGATE;
748: }
749: }
750:
751: return ZEBRA_RIB_NOTFOUND;
752: }
753:
754: #ifdef HAVE_IPV6
755: struct rib *
756: rib_match_ipv6 (struct in6_addr *addr)
757: {
758: struct prefix_ipv6 p;
759: struct route_table *table;
760: struct route_node *rn;
761: struct rib *match;
762: struct nexthop *newhop;
763:
764: /* Lookup table. */
765: table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
766: if (! table)
767: return 0;
768:
769: memset (&p, 0, sizeof (struct prefix_ipv6));
770: p.family = AF_INET6;
771: p.prefixlen = IPV6_MAX_PREFIXLEN;
772: IPV6_ADDR_COPY (&p.prefix, addr);
773:
774: rn = route_node_match (table, (struct prefix *) &p);
775:
776: while (rn)
777: {
778: route_unlock_node (rn);
779:
780: /* Pick up selected route. */
1.1.1.3 ! misho 781: RNODE_FOREACH_RIB (rn, match)
1.1 misho 782: {
783: if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
784: continue;
785: if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
786: break;
787: }
788:
789: /* If there is no selected route or matched route is EGP, go up
790: tree. */
791: if (! match
792: || match->type == ZEBRA_ROUTE_BGP)
793: {
794: do {
795: rn = rn->parent;
796: } while (rn && rn->info == NULL);
797: if (rn)
798: route_lock_node (rn);
799: }
800: else
801: {
802: if (match->type == ZEBRA_ROUTE_CONNECT)
803: /* Directly point connected route. */
804: return match;
805: else
806: {
807: for (newhop = match->nexthop; newhop; newhop = newhop->next)
808: if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
809: return match;
810: return NULL;
811: }
812: }
813: }
814: return NULL;
815: }
816: #endif /* HAVE_IPV6 */
817:
818: #define RIB_SYSTEM_ROUTE(R) \
819: ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
820:
821: /* This function verifies reachability of one given nexthop, which can be
822: * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
823: * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
824: * nexthop->ifindex will be updated appropriately as well.
825: * An existing route map can turn (otherwise active) nexthop into inactive, but
826: * not vice versa.
827: *
828: * The return value is the final value of 'ACTIVE' flag.
829: */
830:
831: static unsigned
832: nexthop_active_check (struct route_node *rn, struct rib *rib,
833: struct nexthop *nexthop, int set)
834: {
835: struct interface *ifp;
836: route_map_result_t ret = RMAP_MATCH;
837: extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
838: struct route_map *rmap;
839: int family;
840:
841: family = 0;
842: switch (nexthop->type)
843: {
844: case NEXTHOP_TYPE_IFINDEX:
845: ifp = if_lookup_by_index (nexthop->ifindex);
846: if (ifp && if_is_operative(ifp))
847: SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
848: else
849: UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
850: break;
851: case NEXTHOP_TYPE_IPV6_IFNAME:
852: family = AFI_IP6;
853: case NEXTHOP_TYPE_IFNAME:
854: ifp = if_lookup_by_name (nexthop->ifname);
855: if (ifp && if_is_operative(ifp))
856: {
857: if (set)
858: nexthop->ifindex = ifp->ifindex;
859: SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
860: }
861: else
862: {
863: if (set)
864: nexthop->ifindex = 0;
865: UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
866: }
867: break;
868: case NEXTHOP_TYPE_IPV4:
869: case NEXTHOP_TYPE_IPV4_IFINDEX:
870: family = AFI_IP;
871: if (nexthop_active_ipv4 (rib, nexthop, set, rn))
872: SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
873: else
874: UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
875: break;
876: #ifdef HAVE_IPV6
877: case NEXTHOP_TYPE_IPV6:
878: family = AFI_IP6;
879: if (nexthop_active_ipv6 (rib, nexthop, set, rn))
880: SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
881: else
882: UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
883: break;
884: case NEXTHOP_TYPE_IPV6_IFINDEX:
885: family = AFI_IP6;
886: if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
887: {
888: ifp = if_lookup_by_index (nexthop->ifindex);
889: if (ifp && if_is_operative(ifp))
890: SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
891: else
892: UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
893: }
894: else
895: {
896: if (nexthop_active_ipv6 (rib, nexthop, set, rn))
897: SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
898: else
899: UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
900: }
901: break;
902: #endif /* HAVE_IPV6 */
903: case NEXTHOP_TYPE_BLACKHOLE:
904: SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
905: break;
906: default:
907: break;
908: }
909: if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
910: return 0;
911:
912: if (RIB_SYSTEM_ROUTE(rib) ||
913: (family == AFI_IP && rn->p.family != AF_INET) ||
914: (family == AFI_IP6 && rn->p.family != AF_INET6))
915: return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
916:
917: rmap = 0;
918: if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
919: proto_rm[family][rib->type])
920: rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
921: if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
922: rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
923: if (rmap) {
924: ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, nexthop);
925: }
926:
927: if (ret == RMAP_DENYMATCH)
928: UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
929: return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
930: }
931:
932: /* Iterate over all nexthops of the given RIB entry and refresh their
933: * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
934: * nexthop is found to toggle the ACTIVE flag, the whole rib structure
935: * is flagged with ZEBRA_FLAG_CHANGED. The 4th 'set' argument is
936: * transparently passed to nexthop_active_check().
937: *
938: * Return value is the new number of active nexthops.
939: */
940:
941: static int
942: nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
943: {
944: struct nexthop *nexthop;
945: unsigned int prev_active, prev_index, new_active;
946:
947: rib->nexthop_active_num = 0;
948: UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
949:
950: for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
951: {
952: prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
953: prev_index = nexthop->ifindex;
954: if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
955: rib->nexthop_active_num++;
956: if (prev_active != new_active ||
957: prev_index != nexthop->ifindex)
958: SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
959: }
960: return rib->nexthop_active_num;
961: }
962:
963:
964:
965: static void
966: rib_install_kernel (struct route_node *rn, struct rib *rib)
967: {
968: int ret = 0;
969: struct nexthop *nexthop;
970:
1.1.1.3 ! misho 971: /*
! 972: * Make sure we update the FPM any time we send new information to
! 973: * the kernel.
! 974: */
! 975: zfpm_trigger_update (rn, "installing in kernel");
1.1 misho 976: switch (PREFIX_FAMILY (&rn->p))
977: {
978: case AF_INET:
979: ret = kernel_add_ipv4 (&rn->p, rib);
980: break;
981: #ifdef HAVE_IPV6
982: case AF_INET6:
983: ret = kernel_add_ipv6 (&rn->p, rib);
984: break;
985: #endif /* HAVE_IPV6 */
986: }
987:
988: /* This condition is never met, if we are using rt_socket.c */
989: if (ret < 0)
990: {
991: for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
992: UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
993: }
994: }
995:
996: /* Uninstall the route from kernel. */
997: static int
998: rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
999: {
1000: int ret = 0;
1001: struct nexthop *nexthop;
1002:
1.1.1.3 ! misho 1003: /*
! 1004: * Make sure we update the FPM any time we send new information to
! 1005: * the kernel.
! 1006: */
! 1007: zfpm_trigger_update (rn, "uninstalling from kernel");
! 1008:
1.1 misho 1009: switch (PREFIX_FAMILY (&rn->p))
1010: {
1011: case AF_INET:
1012: ret = kernel_delete_ipv4 (&rn->p, rib);
1013: break;
1014: #ifdef HAVE_IPV6
1015: case AF_INET6:
1016: ret = kernel_delete_ipv6 (&rn->p, rib);
1017: break;
1018: #endif /* HAVE_IPV6 */
1019: }
1020:
1021: for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1022: UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1023:
1024: return ret;
1025: }
1026:
1027: /* Uninstall the route from kernel. */
1028: static void
1029: rib_uninstall (struct route_node *rn, struct rib *rib)
1030: {
1031: if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1032: {
1.1.1.3 ! misho 1033: zfpm_trigger_update (rn, "rib_uninstall");
! 1034:
1.1 misho 1035: redistribute_delete (&rn->p, rib);
1036: if (! RIB_SYSTEM_ROUTE (rib))
1037: rib_uninstall_kernel (rn, rib);
1038: UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
1039: }
1040: }
1041:
1042: static void rib_unlink (struct route_node *, struct rib *);
1043:
1.1.1.3 ! misho 1044: /*
! 1045: * rib_can_delete_dest
! 1046: *
! 1047: * Returns TRUE if the given dest can be deleted from the table.
! 1048: */
! 1049: static int
! 1050: rib_can_delete_dest (rib_dest_t *dest)
! 1051: {
! 1052: if (dest->routes)
! 1053: {
! 1054: return 0;
! 1055: }
! 1056:
! 1057: /*
! 1058: * Don't delete the dest if we have to update the FPM about this
! 1059: * prefix.
! 1060: */
! 1061: if (CHECK_FLAG (dest->flags, RIB_DEST_UPDATE_FPM) ||
! 1062: CHECK_FLAG (dest->flags, RIB_DEST_SENT_TO_FPM))
! 1063: return 0;
! 1064:
! 1065: return 1;
! 1066: }
! 1067:
! 1068: /*
! 1069: * rib_gc_dest
! 1070: *
! 1071: * Garbage collect the rib dest corresponding to the given route node
! 1072: * if appropriate.
! 1073: *
! 1074: * Returns TRUE if the dest was deleted, FALSE otherwise.
! 1075: */
! 1076: int
! 1077: rib_gc_dest (struct route_node *rn)
! 1078: {
! 1079: rib_dest_t *dest;
! 1080: char buf[INET6_ADDRSTRLEN];
! 1081:
! 1082: dest = rib_dest_from_rnode (rn);
! 1083: if (!dest)
! 1084: return 0;
! 1085:
! 1086: if (!rib_can_delete_dest (dest))
! 1087: return 0;
! 1088:
! 1089: if (IS_ZEBRA_DEBUG_RIB)
! 1090: {
! 1091: inet_ntop (rn->p.family, &rn->p.u.prefix, buf, sizeof (buf));
! 1092: zlog_debug ("%s: %s/%d: removing dest from table", __func__,
! 1093: buf, rn->p.prefixlen);
! 1094: }
! 1095:
! 1096: dest->rnode = NULL;
! 1097: XFREE (MTYPE_RIB_DEST, dest);
! 1098: rn->info = NULL;
! 1099:
! 1100: /*
! 1101: * Release the one reference that we keep on the route node.
! 1102: */
! 1103: route_unlock_node (rn);
! 1104: return 1;
! 1105: }
! 1106:
1.1 misho 1107: /* Core function for processing routing information base. */
1108: static void
1109: rib_process (struct route_node *rn)
1110: {
1111: struct rib *rib;
1112: struct rib *next;
1113: struct rib *fib = NULL;
1114: struct rib *select = NULL;
1115: struct rib *del = NULL;
1116: int installed = 0;
1117: struct nexthop *nexthop = NULL;
1118: char buf[INET6_ADDRSTRLEN];
1119:
1120: assert (rn);
1121:
1122: if (IS_ZEBRA_DEBUG_RIB || IS_ZEBRA_DEBUG_RIB_Q)
1123: inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
1124:
1.1.1.3 ! misho 1125: RNODE_FOREACH_RIB_SAFE (rn, rib, next)
1.1 misho 1126: {
1127: /* Currently installed rib. */
1128: if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1129: {
1130: assert (fib == NULL);
1131: fib = rib;
1132: }
1133:
1134: /* Unlock removed routes, so they'll be freed, bar the FIB entry,
1135: * which we need to do do further work with below.
1136: */
1137: if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1138: {
1139: if (rib != fib)
1140: {
1141: if (IS_ZEBRA_DEBUG_RIB)
1142: zlog_debug ("%s: %s/%d: rn %p, removing rib %p", __func__,
1143: buf, rn->p.prefixlen, rn, rib);
1.1.1.3 ! misho 1144: rib_unlink (rn, rib);
1.1 misho 1145: }
1146: else
1147: del = rib;
1148:
1149: continue;
1150: }
1151:
1152: /* Skip unreachable nexthop. */
1153: if (! nexthop_active_update (rn, rib, 0))
1154: continue;
1155:
1156: /* Infinit distance. */
1157: if (rib->distance == DISTANCE_INFINITY)
1158: continue;
1159:
1160: /* Newly selected rib, the common case. */
1161: if (!select)
1162: {
1163: select = rib;
1164: continue;
1165: }
1166:
1167: /* filter route selection in following order:
1168: * - connected beats other types
1169: * - lower distance beats higher
1170: * - lower metric beats higher for equal distance
1171: * - last, hence oldest, route wins tie break.
1172: */
1173:
1174: /* Connected routes. Pick the last connected
1175: * route of the set of lowest metric connected routes.
1176: */
1177: if (rib->type == ZEBRA_ROUTE_CONNECT)
1178: {
1179: if (select->type != ZEBRA_ROUTE_CONNECT
1180: || rib->metric <= select->metric)
1181: select = rib;
1182: continue;
1183: }
1184: else if (select->type == ZEBRA_ROUTE_CONNECT)
1185: continue;
1186:
1187: /* higher distance loses */
1188: if (rib->distance > select->distance)
1189: continue;
1190:
1191: /* lower wins */
1192: if (rib->distance < select->distance)
1193: {
1194: select = rib;
1195: continue;
1196: }
1197:
1198: /* metric tie-breaks equal distance */
1199: if (rib->metric <= select->metric)
1200: select = rib;
1.1.1.3 ! misho 1201: } /* RNODE_FOREACH_RIB_SAFE */
1.1 misho 1202:
1203: /* After the cycle is finished, the following pointers will be set:
1204: * select --- the winner RIB entry, if any was found, otherwise NULL
1205: * fib --- the SELECTED RIB entry, if any, otherwise NULL
1206: * del --- equal to fib, if fib is queued for deletion, NULL otherwise
1207: * rib --- NULL
1208: */
1209:
1210: /* Same RIB entry is selected. Update FIB and finish. */
1211: if (select && select == fib)
1212: {
1213: if (IS_ZEBRA_DEBUG_RIB)
1214: zlog_debug ("%s: %s/%d: Updating existing route, select %p, fib %p",
1215: __func__, buf, rn->p.prefixlen, select, fib);
1216: if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
1217: {
1.1.1.3 ! misho 1218: zfpm_trigger_update (rn, "updating existing route");
! 1219:
1.1 misho 1220: redistribute_delete (&rn->p, select);
1221: if (! RIB_SYSTEM_ROUTE (select))
1222: rib_uninstall_kernel (rn, select);
1223:
1224: /* Set real nexthop. */
1225: nexthop_active_update (rn, select, 1);
1226:
1227: if (! RIB_SYSTEM_ROUTE (select))
1228: rib_install_kernel (rn, select);
1229: redistribute_add (&rn->p, select);
1230: }
1231: else if (! RIB_SYSTEM_ROUTE (select))
1232: {
1233: /* Housekeeping code to deal with
1234: race conditions in kernel with linux
1235: netlink reporting interface up before IPv4 or IPv6 protocol
1236: is ready to add routes.
1237: This makes sure the routes are IN the kernel.
1238: */
1239:
1240: for (nexthop = select->nexthop; nexthop; nexthop = nexthop->next)
1241: if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1242: {
1243: installed = 1;
1244: break;
1245: }
1246: if (! installed)
1247: rib_install_kernel (rn, select);
1248: }
1249: goto end;
1250: }
1251:
1252: /* At this point we either haven't found the best RIB entry or it is
1253: * different from what we currently intend to flag with SELECTED. In both
1254: * cases, if a RIB block is present in FIB, it should be withdrawn.
1255: */
1256: if (fib)
1257: {
1258: if (IS_ZEBRA_DEBUG_RIB)
1259: zlog_debug ("%s: %s/%d: Removing existing route, fib %p", __func__,
1260: buf, rn->p.prefixlen, fib);
1.1.1.3 ! misho 1261:
! 1262: zfpm_trigger_update (rn, "removing existing route");
! 1263:
1.1 misho 1264: redistribute_delete (&rn->p, fib);
1265: if (! RIB_SYSTEM_ROUTE (fib))
1266: rib_uninstall_kernel (rn, fib);
1267: UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
1268:
1269: /* Set real nexthop. */
1270: nexthop_active_update (rn, fib, 1);
1271: }
1272:
1273: /* Regardless of some RIB entry being SELECTED or not before, now we can
1274: * tell, that if a new winner exists, FIB is still not updated with this
1275: * data, but ready to be.
1276: */
1277: if (select)
1278: {
1279: if (IS_ZEBRA_DEBUG_RIB)
1280: zlog_debug ("%s: %s/%d: Adding route, select %p", __func__, buf,
1281: rn->p.prefixlen, select);
1.1.1.3 ! misho 1282:
! 1283: zfpm_trigger_update (rn, "new route selected");
! 1284:
1.1 misho 1285: /* Set real nexthop. */
1286: nexthop_active_update (rn, select, 1);
1287:
1288: if (! RIB_SYSTEM_ROUTE (select))
1289: rib_install_kernel (rn, select);
1290: SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
1291: redistribute_add (&rn->p, select);
1292: }
1293:
1294: /* FIB route was removed, should be deleted */
1295: if (del)
1296: {
1297: if (IS_ZEBRA_DEBUG_RIB)
1298: zlog_debug ("%s: %s/%d: Deleting fib %p, rn %p", __func__, buf,
1299: rn->p.prefixlen, del, rn);
1300: rib_unlink (rn, del);
1301: }
1302:
1303: end:
1304: if (IS_ZEBRA_DEBUG_RIB_Q)
1305: zlog_debug ("%s: %s/%d: rn %p dequeued", __func__, buf, rn->p.prefixlen, rn);
1.1.1.3 ! misho 1306:
! 1307: /*
! 1308: * Check if the dest can be deleted now.
! 1309: */
! 1310: rib_gc_dest (rn);
1.1 misho 1311: }
1312:
1313: /* Take a list of route_node structs and return 1, if there was a record
1314: * picked from it and processed by rib_process(). Don't process more,
1315: * than one RN record; operate only in the specified sub-queue.
1316: */
1317: static unsigned int
1318: process_subq (struct list * subq, u_char qindex)
1319: {
1320: struct listnode *lnode = listhead (subq);
1321: struct route_node *rnode;
1322:
1323: if (!lnode)
1324: return 0;
1325:
1326: rnode = listgetdata (lnode);
1327: rib_process (rnode);
1328:
1.1.1.3 ! misho 1329: if (rnode->info)
! 1330: UNSET_FLAG (rib_dest_from_rnode (rnode)->flags, RIB_ROUTE_QUEUED (qindex));
! 1331:
1.1 misho 1332: #if 0
1333: else
1334: {
1335: zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1336: __func__, rnode, rnode->lock);
1337: zlog_backtrace(LOG_DEBUG);
1338: }
1339: #endif
1340: route_unlock_node (rnode);
1341: list_delete_node (subq, lnode);
1342: return 1;
1343: }
1344:
1345: /* Dispatch the meta queue by picking, processing and unlocking the next RN from
1346: * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
1347: * is pointed to the meta queue structure.
1348: */
1349: static wq_item_status
1350: meta_queue_process (struct work_queue *dummy, void *data)
1351: {
1352: struct meta_queue * mq = data;
1353: unsigned i;
1354:
1355: for (i = 0; i < MQ_SIZE; i++)
1356: if (process_subq (mq->subq[i], i))
1357: {
1358: mq->size--;
1359: break;
1360: }
1361: return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
1362: }
1363:
1.1.1.3 ! misho 1364: /*
! 1365: * Map from rib types to queue type (priority) in meta queue
! 1366: */
1.1 misho 1367: static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
1368: [ZEBRA_ROUTE_SYSTEM] = 4,
1369: [ZEBRA_ROUTE_KERNEL] = 0,
1370: [ZEBRA_ROUTE_CONNECT] = 0,
1371: [ZEBRA_ROUTE_STATIC] = 1,
1372: [ZEBRA_ROUTE_RIP] = 2,
1373: [ZEBRA_ROUTE_RIPNG] = 2,
1374: [ZEBRA_ROUTE_OSPF] = 2,
1375: [ZEBRA_ROUTE_OSPF6] = 2,
1376: [ZEBRA_ROUTE_ISIS] = 2,
1377: [ZEBRA_ROUTE_BGP] = 3,
1378: [ZEBRA_ROUTE_HSLS] = 4,
1.1.1.2 misho 1379: [ZEBRA_ROUTE_BABEL] = 2,
1.1 misho 1380: };
1381:
1382: /* Look into the RN and queue it into one or more priority queues,
1383: * increasing the size for each data push done.
1384: */
1385: static void
1386: rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
1387: {
1388: struct rib *rib;
1389: char buf[INET6_ADDRSTRLEN];
1390:
1391: if (IS_ZEBRA_DEBUG_RIB_Q)
1392: inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
1393:
1.1.1.3 ! misho 1394: RNODE_FOREACH_RIB (rn, rib)
1.1 misho 1395: {
1396: u_char qindex = meta_queue_map[rib->type];
1397:
1398: /* Invariant: at this point we always have rn->info set. */
1.1.1.3 ! misho 1399: if (CHECK_FLAG (rib_dest_from_rnode (rn)->flags,
! 1400: RIB_ROUTE_QUEUED (qindex)))
1.1 misho 1401: {
1402: if (IS_ZEBRA_DEBUG_RIB_Q)
1403: zlog_debug ("%s: %s/%d: rn %p is already queued in sub-queue %u",
1404: __func__, buf, rn->p.prefixlen, rn, qindex);
1405: continue;
1406: }
1407:
1.1.1.3 ! misho 1408: SET_FLAG (rib_dest_from_rnode (rn)->flags, RIB_ROUTE_QUEUED (qindex));
1.1 misho 1409: listnode_add (mq->subq[qindex], rn);
1410: route_lock_node (rn);
1411: mq->size++;
1412:
1413: if (IS_ZEBRA_DEBUG_RIB_Q)
1414: zlog_debug ("%s: %s/%d: queued rn %p into sub-queue %u",
1415: __func__, buf, rn->p.prefixlen, rn, qindex);
1416: }
1417: }
1418:
1419: /* Add route_node to work queue and schedule processing */
1420: static void
1421: rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
1422: {
1.1.1.2 misho 1423: char buf[INET_ADDRSTRLEN];
1424: assert (zebra && rn);
1.1 misho 1425:
1426: if (IS_ZEBRA_DEBUG_RIB_Q)
1.1.1.2 misho 1427: inet_ntop (AF_INET, &rn->p.u.prefix, buf, INET_ADDRSTRLEN);
1428:
1429: /* Pointless to queue a route_node with no RIB entries to add or remove */
1.1.1.3 ! misho 1430: if (!rnode_to_ribs (rn))
1.1 misho 1431: {
1.1.1.2 misho 1432: zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
1433: __func__, rn, rn->lock);
1434: zlog_backtrace(LOG_DEBUG);
1435: return;
1436: }
1437:
1438: if (IS_ZEBRA_DEBUG_RIB_Q)
1439: zlog_info ("%s: %s/%d: work queue added", __func__, buf, rn->p.prefixlen);
1.1 misho 1440:
1.1.1.2 misho 1441: assert (zebra);
1442:
1443: if (zebra->ribq == NULL)
1444: {
1445: zlog_err ("%s: work_queue does not exist!", __func__);
1446: return;
1.1 misho 1447: }
1448:
1449: /*
1450: * The RIB queue should normally be either empty or holding the only
1451: * work_queue_item element. In the latter case this element would
1452: * hold a pointer to the meta queue structure, which must be used to
1453: * actually queue the route nodes to process. So create the MQ
1454: * holder, if necessary, then push the work into it in any case.
1455: * This semantics was introduced after 0.99.9 release.
1456: */
1457: if (!zebra->ribq->items->count)
1458: work_queue_add (zebra->ribq, zebra->mq);
1459:
1460: rib_meta_queue_add (zebra->mq, rn);
1.1.1.2 misho 1461:
1462: if (IS_ZEBRA_DEBUG_RIB_Q)
1463: zlog_debug ("%s: %s/%d: rn %p queued", __func__, buf, rn->p.prefixlen, rn);
1464:
1465: return;
1.1 misho 1466: }
1467:
1468: /* Create new meta queue.
1469: A destructor function doesn't seem to be necessary here.
1470: */
1471: static struct meta_queue *
1472: meta_queue_new (void)
1473: {
1474: struct meta_queue *new;
1475: unsigned i;
1476:
1477: new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
1478: assert(new);
1479:
1480: for (i = 0; i < MQ_SIZE; i++)
1481: {
1482: new->subq[i] = list_new ();
1483: assert(new->subq[i]);
1484: }
1485:
1486: return new;
1487: }
1488:
1489: /* initialise zebra rib work queue */
1490: static void
1491: rib_queue_init (struct zebra_t *zebra)
1492: {
1.1.1.2 misho 1493: assert (zebra);
1494:
1.1 misho 1495: if (! (zebra->ribq = work_queue_new (zebra->master,
1496: "route_node processing")))
1497: {
1498: zlog_err ("%s: could not initialise work queue!", __func__);
1499: return;
1500: }
1501:
1502: /* fill in the work queue spec */
1503: zebra->ribq->spec.workfunc = &meta_queue_process;
1504: zebra->ribq->spec.errorfunc = NULL;
1505: /* XXX: TODO: These should be runtime configurable via vty */
1506: zebra->ribq->spec.max_retries = 3;
1507: zebra->ribq->spec.hold = rib_process_hold_time;
1508:
1509: if (!(zebra->mq = meta_queue_new ()))
1.1.1.2 misho 1510: {
1.1 misho 1511: zlog_err ("%s: could not initialise meta queue!", __func__);
1.1.1.2 misho 1512: return;
1513: }
1514: return;
1.1 misho 1515: }
1516:
1517: /* RIB updates are processed via a queue of pointers to route_nodes.
1518: *
1519: * The queue length is bounded by the maximal size of the routing table,
1520: * as a route_node will not be requeued, if already queued.
1521: *
1522: * RIBs are submitted via rib_addnode or rib_delnode which set minimal
1523: * state, or static_install_ipv{4,6} (when an existing RIB is updated)
1524: * and then submit route_node to queue for best-path selection later.
1525: * Order of add/delete state changes are preserved for any given RIB.
1526: *
1527: * Deleted RIBs are reaped during best-path selection.
1528: *
1529: * rib_addnode
1530: * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with
1531: * |-------->| | best RIB, if required
1532: * | |
1533: * static_install->|->rib_addqueue...... -> rib_process
1534: * | |
1535: * |-------->| |-> rib_unlink
1536: * |-> set RIB_ENTRY_REMOVE |
1537: * rib_delnode (RIB freed)
1538: *
1.1.1.3 ! misho 1539: * The 'info' pointer of a route_node points to a rib_dest_t
! 1540: * ('dest'). Queueing state for a route_node is kept on the dest. The
! 1541: * dest is created on-demand by rib_link() and is kept around at least
! 1542: * as long as there are ribs hanging off it (@see rib_gc_dest()).
1.1 misho 1543: *
1544: * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
1545: *
1546: * - route_nodes: refcounted by:
1.1.1.3 ! misho 1547: * - dest attached to route_node:
! 1548: * - managed by: rib_link/rib_gc_dest
1.1 misho 1549: * - route_node processing queue
1550: * - managed by: rib_addqueue, rib_process.
1551: *
1552: */
1553:
1554: /* Add RIB to head of the route node. */
1555: static void
1556: rib_link (struct route_node *rn, struct rib *rib)
1557: {
1558: struct rib *head;
1.1.1.3 ! misho 1559: rib_dest_t *dest;
1.1 misho 1560: char buf[INET6_ADDRSTRLEN];
1.1.1.3 ! misho 1561:
1.1 misho 1562: assert (rib && rn);
1563:
1564: if (IS_ZEBRA_DEBUG_RIB)
1565: {
1566: inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
1567: zlog_debug ("%s: %s/%d: rn %p, rib %p", __func__,
1568: buf, rn->p.prefixlen, rn, rib);
1569: }
1570:
1.1.1.3 ! misho 1571: dest = rib_dest_from_rnode (rn);
! 1572: if (!dest)
1.1 misho 1573: {
1574: if (IS_ZEBRA_DEBUG_RIB)
1.1.1.3 ! misho 1575: {
! 1576: zlog_debug ("%s: %s/%d: adding dest to table", __func__,
! 1577: buf, rn->p.prefixlen);
! 1578: }
! 1579:
! 1580: dest = XCALLOC (MTYPE_RIB_DEST, sizeof (rib_dest_t));
! 1581: route_lock_node (rn); /* rn route table reference */
! 1582: rn->info = dest;
! 1583: dest->rnode = rn;
! 1584: }
! 1585:
! 1586: head = dest->routes;
! 1587: if (head)
! 1588: {
1.1 misho 1589: head->prev = rib;
1590: }
1591: rib->next = head;
1.1.1.3 ! misho 1592: dest->routes = rib;
1.1 misho 1593: rib_queue_add (&zebrad, rn);
1594: }
1595:
1596: static void
1597: rib_addnode (struct route_node *rn, struct rib *rib)
1598: {
1599: /* RIB node has been un-removed before route-node is processed.
1600: * route_node must hence already be on the queue for processing..
1601: */
1602: if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1603: {
1604: if (IS_ZEBRA_DEBUG_RIB)
1605: {
1606: char buf[INET6_ADDRSTRLEN];
1607: inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
1608: zlog_debug ("%s: %s/%d: rn %p, un-removed rib %p",
1609: __func__, buf, rn->p.prefixlen, rn, rib);
1610: }
1611: UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1612: return;
1613: }
1614: rib_link (rn, rib);
1615: }
1616:
1.1.1.3 ! misho 1617: /*
! 1618: * rib_unlink
! 1619: *
! 1620: * Detach a rib structure from a route_node.
! 1621: *
! 1622: * Note that a call to rib_unlink() should be followed by a call to
! 1623: * rib_gc_dest() at some point. This allows a rib_dest_t that is no
! 1624: * longer required to be deleted.
! 1625: */
1.1 misho 1626: static void
1627: rib_unlink (struct route_node *rn, struct rib *rib)
1628: {
1629: struct nexthop *nexthop, *next;
1630: char buf[INET6_ADDRSTRLEN];
1.1.1.3 ! misho 1631: rib_dest_t *dest;
1.1 misho 1632:
1633: assert (rn && rib);
1634:
1635: if (IS_ZEBRA_DEBUG_RIB)
1636: {
1637: inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
1638: zlog_debug ("%s: %s/%d: rn %p, rib %p",
1639: __func__, buf, rn->p.prefixlen, rn, rib);
1640: }
1641:
1.1.1.3 ! misho 1642: dest = rib_dest_from_rnode (rn);
! 1643:
1.1 misho 1644: if (rib->next)
1645: rib->next->prev = rib->prev;
1646:
1647: if (rib->prev)
1648: rib->prev->next = rib->next;
1649: else
1650: {
1.1.1.3 ! misho 1651: dest->routes = rib->next;
1.1 misho 1652: }
1653:
1654: /* free RIB and nexthops */
1655: for (nexthop = rib->nexthop; nexthop; nexthop = next)
1656: {
1657: next = nexthop->next;
1658: nexthop_free (nexthop);
1659: }
1660: XFREE (MTYPE_RIB, rib);
1661:
1662: }
1663:
1664: static void
1665: rib_delnode (struct route_node *rn, struct rib *rib)
1666: {
1667: if (IS_ZEBRA_DEBUG_RIB)
1668: {
1669: char buf[INET6_ADDRSTRLEN];
1670: inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
1671: zlog_debug ("%s: %s/%d: rn %p, rib %p, removing", __func__,
1672: buf, rn->p.prefixlen, rn, rib);
1673: }
1674: SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
1675: rib_queue_add (&zebrad, rn);
1676: }
1677:
1678: int
1679: rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
1680: struct in_addr *gate, struct in_addr *src,
1681: unsigned int ifindex, u_int32_t vrf_id,
1.1.1.2 misho 1682: u_int32_t metric, u_char distance, safi_t safi)
1.1 misho 1683: {
1684: struct rib *rib;
1685: struct rib *same = NULL;
1686: struct route_table *table;
1687: struct route_node *rn;
1688: struct nexthop *nexthop;
1689:
1690: /* Lookup table. */
1.1.1.2 misho 1691: table = vrf_table (AFI_IP, safi, 0);
1.1 misho 1692: if (! table)
1693: return 0;
1694:
1695: /* Make it sure prefixlen is applied to the prefix. */
1696: apply_mask_ipv4 (p);
1697:
1698: /* Set default distance by route type. */
1699: if (distance == 0)
1700: {
1.1.1.3 ! misho 1701: if ((unsigned)type >= array_size(route_info))
1.1.1.2 misho 1702: distance = 150;
1703: else
1704: distance = route_info[type].distance;
1.1 misho 1705:
1706: /* iBGP distance is 200. */
1707: if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
1708: distance = 200;
1709: }
1710:
1711: /* Lookup route node.*/
1712: rn = route_node_get (table, (struct prefix *) p);
1713:
1714: /* If same type of route are installed, treat it as a implicit
1715: withdraw. */
1.1.1.3 ! misho 1716: RNODE_FOREACH_RIB (rn, rib)
1.1 misho 1717: {
1718: if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1719: continue;
1720:
1721: if (rib->type != type)
1722: continue;
1723: if (rib->type != ZEBRA_ROUTE_CONNECT)
1724: {
1725: same = rib;
1726: break;
1727: }
1728: /* Duplicate connected route comes in. */
1729: else if ((nexthop = rib->nexthop) &&
1730: nexthop->type == NEXTHOP_TYPE_IFINDEX &&
1731: nexthop->ifindex == ifindex &&
1732: !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
1733: {
1734: rib->refcnt++;
1735: return 0 ;
1736: }
1737: }
1738:
1739: /* Allocate new rib structure. */
1740: rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
1741: rib->type = type;
1742: rib->distance = distance;
1743: rib->flags = flags;
1744: rib->metric = metric;
1745: rib->table = vrf_id;
1746: rib->nexthop_num = 0;
1747: rib->uptime = time (NULL);
1748:
1749: /* Nexthop settings. */
1750: if (gate)
1751: {
1752: if (ifindex)
1753: nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
1754: else
1755: nexthop_ipv4_add (rib, gate, src);
1756: }
1757: else
1758: nexthop_ifindex_add (rib, ifindex);
1759:
1760: /* If this route is kernel route, set FIB flag to the route. */
1761: if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
1762: for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1763: SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1764:
1765: /* Link new rib to node.*/
1766: if (IS_ZEBRA_DEBUG_RIB)
1767: zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
1768: rib_addnode (rn, rib);
1769:
1770: /* Free implicit route.*/
1771: if (same)
1772: {
1773: if (IS_ZEBRA_DEBUG_RIB)
1774: zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
1775: rib_delnode (rn, same);
1776: }
1777:
1778: route_unlock_node (rn);
1779: return 0;
1780: }
1781:
1782: /* This function dumps the contents of a given RIB entry into
1783: * standard debug log. Calling function name and IP prefix in
1784: * question are passed as 1st and 2nd arguments.
1785: */
1786:
1787: void rib_dump (const char * func, const struct prefix_ipv4 * p, const struct rib * rib)
1788: {
1789: char straddr1[INET_ADDRSTRLEN], straddr2[INET_ADDRSTRLEN];
1790: struct nexthop *nexthop;
1791:
1792: inet_ntop (AF_INET, &p->prefix, straddr1, INET_ADDRSTRLEN);
1793: zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr1, p->prefixlen);
1794: zlog_debug
1795: (
1796: "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
1797: func,
1798: rib->refcnt,
1799: (unsigned long) rib->uptime,
1800: rib->type,
1801: rib->table
1802: );
1803: zlog_debug
1804: (
1805: "%s: metric == %u, distance == %u, flags == %u, status == %u",
1806: func,
1807: rib->metric,
1808: rib->distance,
1809: rib->flags,
1810: rib->status
1811: );
1812: zlog_debug
1813: (
1814: "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
1815: func,
1816: rib->nexthop_num,
1817: rib->nexthop_active_num,
1818: rib->nexthop_fib_num
1819: );
1820: for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1821: {
1822: inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, straddr1, INET_ADDRSTRLEN);
1823: inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, straddr2, INET_ADDRSTRLEN);
1824: zlog_debug
1825: (
1826: "%s: NH %s (%s) with flags %s%s%s",
1827: func,
1828: straddr1,
1829: straddr2,
1830: (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
1831: (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
1832: (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
1833: );
1834: }
1835: zlog_debug ("%s: dump complete", func);
1836: }
1837:
1838: /* This is an exported helper to rtm_read() to dump the strange
1839: * RIB entry found by rib_lookup_ipv4_route()
1840: */
1841:
1842: void rib_lookup_and_dump (struct prefix_ipv4 * p)
1843: {
1844: struct route_table *table;
1845: struct route_node *rn;
1846: struct rib *rib;
1847: char prefix_buf[INET_ADDRSTRLEN];
1848:
1849: /* Lookup table. */
1850: table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1851: if (! table)
1852: {
1853: zlog_err ("%s: vrf_table() returned NULL", __func__);
1854: return;
1855: }
1856:
1857: inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
1858: /* Scan the RIB table for exactly matching RIB entry. */
1859: rn = route_node_lookup (table, (struct prefix *) p);
1860:
1861: /* No route for this prefix. */
1862: if (! rn)
1863: {
1864: zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
1865: return;
1866: }
1867:
1868: /* Unlock node. */
1869: route_unlock_node (rn);
1870:
1871: /* let's go */
1.1.1.3 ! misho 1872: RNODE_FOREACH_RIB (rn, rib)
1.1 misho 1873: {
1874: zlog_debug
1875: (
1876: "%s: rn %p, rib %p: %s, %s",
1877: __func__,
1878: rn,
1879: rib,
1880: (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
1881: (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
1882: );
1883: rib_dump (__func__, p, rib);
1884: }
1885: }
1886:
1887: /* Check if requested address assignment will fail due to another
1888: * route being installed by zebra in FIB already. Take necessary
1889: * actions, if needed: remove such a route from FIB and deSELECT
1890: * corresponding RIB entry. Then put affected RN into RIBQ head.
1891: */
1892: void rib_lookup_and_pushup (struct prefix_ipv4 * p)
1893: {
1894: struct route_table *table;
1895: struct route_node *rn;
1896: struct rib *rib;
1897: unsigned changed = 0;
1898:
1899: if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
1900: {
1901: zlog_err ("%s: vrf_table() returned NULL", __func__);
1902: return;
1903: }
1904:
1905: /* No matches would be the simplest case. */
1906: if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
1907: return;
1908:
1909: /* Unlock node. */
1910: route_unlock_node (rn);
1911:
1912: /* Check all RIB entries. In case any changes have to be done, requeue
1913: * the RN into RIBQ head. If the routing message about the new connected
1914: * route (generated by the IP address we are going to assign very soon)
1915: * comes before the RIBQ is processed, the new RIB entry will join
1916: * RIBQ record already on head. This is necessary for proper revalidation
1917: * of the rest of the RIB.
1918: */
1.1.1.3 ! misho 1919: RNODE_FOREACH_RIB (rn, rib)
1.1 misho 1920: {
1921: if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
1922: ! RIB_SYSTEM_ROUTE (rib))
1923: {
1924: changed = 1;
1925: if (IS_ZEBRA_DEBUG_RIB)
1926: {
1927: char buf[INET_ADDRSTRLEN];
1928: inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
1929: zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
1930: rib_dump (__func__, (struct prefix_ipv4 *)&rn->p, rib);
1931: }
1932: rib_uninstall (rn, rib);
1933: }
1934: }
1935: if (changed)
1936: rib_queue_add (&zebrad, rn);
1937: }
1938:
1939: int
1.1.1.2 misho 1940: rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
1.1 misho 1941: {
1942: struct route_table *table;
1943: struct route_node *rn;
1944: struct rib *same;
1945: struct nexthop *nexthop;
1946:
1947: /* Lookup table. */
1.1.1.2 misho 1948: table = vrf_table (AFI_IP, safi, 0);
1.1 misho 1949: if (! table)
1950: return 0;
1.1.1.2 misho 1951:
1.1 misho 1952: /* Make it sure prefixlen is applied to the prefix. */
1953: apply_mask_ipv4 (p);
1954:
1955: /* Set default distance by route type. */
1956: if (rib->distance == 0)
1957: {
1958: rib->distance = route_info[rib->type].distance;
1959:
1960: /* iBGP distance is 200. */
1961: if (rib->type == ZEBRA_ROUTE_BGP
1962: && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1963: rib->distance = 200;
1964: }
1965:
1966: /* Lookup route node.*/
1967: rn = route_node_get (table, (struct prefix *) p);
1968:
1969: /* If same type of route are installed, treat it as a implicit
1970: withdraw. */
1.1.1.3 ! misho 1971: RNODE_FOREACH_RIB (rn, same)
1.1 misho 1972: {
1973: if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
1974: continue;
1975:
1976: if (same->type == rib->type && same->table == rib->table
1977: && same->type != ZEBRA_ROUTE_CONNECT)
1978: break;
1979: }
1980:
1981: /* If this route is kernel route, set FIB flag to the route. */
1982: if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
1983: for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1984: SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1985:
1986: /* Link new rib to node.*/
1987: rib_addnode (rn, rib);
1988: if (IS_ZEBRA_DEBUG_RIB)
1989: {
1990: zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
1991: __func__, rn, rib);
1992: rib_dump (__func__, p, rib);
1993: }
1994:
1995: /* Free implicit route.*/
1996: if (same)
1997: {
1998: if (IS_ZEBRA_DEBUG_RIB)
1999: {
2000: zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
2001: __func__, rn, same);
2002: rib_dump (__func__, p, same);
2003: }
2004: rib_delnode (rn, same);
2005: }
2006:
2007: route_unlock_node (rn);
2008: return 0;
2009: }
2010:
2011: /* XXX factor with rib_delete_ipv6 */
2012: int
2013: rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
1.1.1.2 misho 2014: struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
1.1 misho 2015: {
2016: struct route_table *table;
2017: struct route_node *rn;
2018: struct rib *rib;
2019: struct rib *fib = NULL;
2020: struct rib *same = NULL;
2021: struct nexthop *nexthop;
2022: char buf1[INET_ADDRSTRLEN];
2023: char buf2[INET_ADDRSTRLEN];
2024:
2025: /* Lookup table. */
1.1.1.2 misho 2026: table = vrf_table (AFI_IP, safi, 0);
1.1 misho 2027: if (! table)
2028: return 0;
2029:
2030: /* Apply mask. */
2031: apply_mask_ipv4 (p);
2032:
2033: if (IS_ZEBRA_DEBUG_KERNEL && gate)
2034: zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
2035: inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
2036: p->prefixlen,
2037: inet_ntoa (*gate),
2038: ifindex);
2039:
2040: /* Lookup route node. */
2041: rn = route_node_lookup (table, (struct prefix *) p);
2042: if (! rn)
2043: {
2044: if (IS_ZEBRA_DEBUG_KERNEL)
2045: {
2046: if (gate)
2047: zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
2048: inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
2049: p->prefixlen,
2050: inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
2051: ifindex);
2052: else
2053: zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
2054: inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
2055: p->prefixlen,
2056: ifindex);
2057: }
2058: return ZEBRA_ERR_RTNOEXIST;
2059: }
2060:
2061: /* Lookup same type route. */
1.1.1.3 ! misho 2062: RNODE_FOREACH_RIB (rn, rib)
1.1 misho 2063: {
2064: if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2065: continue;
2066:
2067: if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2068: fib = rib;
2069:
2070: if (rib->type != type)
2071: continue;
2072: if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
1.1.1.2 misho 2073: nexthop->type == NEXTHOP_TYPE_IFINDEX)
1.1 misho 2074: {
1.1.1.2 misho 2075: if (nexthop->ifindex != ifindex)
2076: continue;
1.1 misho 2077: if (rib->refcnt)
2078: {
2079: rib->refcnt--;
2080: route_unlock_node (rn);
2081: route_unlock_node (rn);
2082: return 0;
2083: }
2084: same = rib;
2085: break;
2086: }
2087: /* Make sure that the route found has the same gateway. */
2088: else if (gate == NULL ||
2089: ((nexthop = rib->nexthop) &&
2090: (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
2091: IPV4_ADDR_SAME (&nexthop->rgate.ipv4, gate))))
2092: {
2093: same = rib;
2094: break;
2095: }
2096: }
2097:
2098: /* If same type of route can't be found and this message is from
2099: kernel. */
2100: if (! same)
2101: {
2102: if (fib && type == ZEBRA_ROUTE_KERNEL)
2103: {
2104: /* Unset flags. */
2105: for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2106: UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2107:
2108: UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2109: }
2110: else
2111: {
2112: if (IS_ZEBRA_DEBUG_KERNEL)
2113: {
2114: if (gate)
2115: zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
2116: inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
2117: p->prefixlen,
2118: inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
2119: ifindex,
2120: type);
2121: else
2122: zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
2123: inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
2124: p->prefixlen,
2125: ifindex,
2126: type);
2127: }
2128: route_unlock_node (rn);
2129: return ZEBRA_ERR_RTNOEXIST;
2130: }
2131: }
2132:
2133: if (same)
2134: rib_delnode (rn, same);
2135:
2136: route_unlock_node (rn);
2137: return 0;
2138: }
2139:
2140: /* Install static route into rib. */
2141: static void
2142: static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
2143: {
2144: struct rib *rib;
2145: struct route_node *rn;
2146: struct route_table *table;
2147:
2148: /* Lookup table. */
2149: table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2150: if (! table)
2151: return;
2152:
2153: /* Lookup existing route */
2154: rn = route_node_get (table, p);
1.1.1.3 ! misho 2155: RNODE_FOREACH_RIB (rn, rib)
1.1 misho 2156: {
2157: if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2158: continue;
2159:
2160: if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2161: break;
2162: }
2163:
2164: if (rib)
2165: {
2166: /* Same distance static route is there. Update it with new
2167: nexthop. */
2168: route_unlock_node (rn);
2169: switch (si->type)
2170: {
2171: case STATIC_IPV4_GATEWAY:
2172: nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
2173: break;
2174: case STATIC_IPV4_IFNAME:
2175: nexthop_ifname_add (rib, si->gate.ifname);
2176: break;
2177: case STATIC_IPV4_BLACKHOLE:
2178: nexthop_blackhole_add (rib);
2179: break;
2180: }
2181: rib_queue_add (&zebrad, rn);
2182: }
2183: else
2184: {
2185: /* This is new static route. */
2186: rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2187:
2188: rib->type = ZEBRA_ROUTE_STATIC;
2189: rib->distance = si->distance;
2190: rib->metric = 0;
1.1.1.3 ! misho 2191: rib->table = zebrad.rtm_table_default;
1.1 misho 2192: rib->nexthop_num = 0;
2193:
2194: switch (si->type)
2195: {
2196: case STATIC_IPV4_GATEWAY:
2197: nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
2198: break;
2199: case STATIC_IPV4_IFNAME:
2200: nexthop_ifname_add (rib, si->gate.ifname);
2201: break;
2202: case STATIC_IPV4_BLACKHOLE:
2203: nexthop_blackhole_add (rib);
2204: break;
2205: }
2206:
2207: /* Save the flags of this static routes (reject, blackhole) */
2208: rib->flags = si->flags;
2209:
2210: /* Link this rib to the tree. */
2211: rib_addnode (rn, rib);
2212: }
2213: }
2214:
2215: static int
2216: static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
2217: {
2218: if (nexthop->type == NEXTHOP_TYPE_IPV4
2219: && si->type == STATIC_IPV4_GATEWAY
2220: && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
2221: return 1;
2222: if (nexthop->type == NEXTHOP_TYPE_IFNAME
2223: && si->type == STATIC_IPV4_IFNAME
2224: && strcmp (nexthop->ifname, si->gate.ifname) == 0)
2225: return 1;
2226: if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
2227: && si->type == STATIC_IPV4_BLACKHOLE)
2228: return 1;
2229: return 0;
2230: }
2231:
2232: /* Uninstall static route from RIB. */
2233: static void
2234: static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
2235: {
2236: struct route_node *rn;
2237: struct rib *rib;
2238: struct nexthop *nexthop;
2239: struct route_table *table;
2240:
2241: /* Lookup table. */
2242: table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2243: if (! table)
2244: return;
2245:
2246: /* Lookup existing route with type and distance. */
2247: rn = route_node_lookup (table, p);
2248: if (! rn)
2249: return;
2250:
1.1.1.3 ! misho 2251: RNODE_FOREACH_RIB (rn, rib)
1.1 misho 2252: {
2253: if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2254: continue;
2255:
2256: if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2257: break;
2258: }
2259:
2260: if (! rib)
2261: {
2262: route_unlock_node (rn);
2263: return;
2264: }
2265:
2266: /* Lookup nexthop. */
2267: for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2268: if (static_ipv4_nexthop_same (nexthop, si))
2269: break;
2270:
2271: /* Can't find nexthop. */
2272: if (! nexthop)
2273: {
2274: route_unlock_node (rn);
2275: return;
2276: }
2277:
2278: /* Check nexthop. */
2279: if (rib->nexthop_num == 1)
2280: rib_delnode (rn, rib);
2281: else
2282: {
2283: if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2284: rib_uninstall (rn, rib);
2285: nexthop_delete (rib, nexthop);
2286: nexthop_free (nexthop);
2287: rib_queue_add (&zebrad, rn);
2288: }
2289: /* Unlock node. */
2290: route_unlock_node (rn);
2291: }
2292:
2293: /* Add static route into static route configuration. */
2294: int
2295: static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
2296: u_char flags, u_char distance, u_int32_t vrf_id)
2297: {
2298: u_char type = 0;
2299: struct route_node *rn;
2300: struct static_ipv4 *si;
2301: struct static_ipv4 *pp;
2302: struct static_ipv4 *cp;
2303: struct static_ipv4 *update = NULL;
2304: struct route_table *stable;
2305:
2306: /* Lookup table. */
2307: stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2308: if (! stable)
2309: return -1;
2310:
2311: /* Lookup static route prefix. */
2312: rn = route_node_get (stable, p);
2313:
2314: /* Make flags. */
2315: if (gate)
2316: type = STATIC_IPV4_GATEWAY;
2317: else if (ifname)
2318: type = STATIC_IPV4_IFNAME;
2319: else
2320: type = STATIC_IPV4_BLACKHOLE;
2321:
2322: /* Do nothing if there is a same static route. */
2323: for (si = rn->info; si; si = si->next)
2324: {
2325: if (type == si->type
2326: && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2327: && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2328: {
2329: if (distance == si->distance)
2330: {
2331: route_unlock_node (rn);
2332: return 0;
2333: }
2334: else
2335: update = si;
2336: }
2337: }
2338:
2339: /* Distance changed. */
2340: if (update)
2341: static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
2342:
2343: /* Make new static route structure. */
2344: si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
2345:
2346: si->type = type;
2347: si->distance = distance;
2348: si->flags = flags;
2349:
2350: if (gate)
2351: si->gate.ipv4 = *gate;
2352: if (ifname)
2353: si->gate.ifname = XSTRDUP (0, ifname);
2354:
2355: /* Add new static route information to the tree with sort by
2356: distance value and gateway address. */
2357: for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2358: {
2359: if (si->distance < cp->distance)
2360: break;
2361: if (si->distance > cp->distance)
2362: continue;
2363: if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
2364: {
2365: if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
2366: break;
2367: if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
2368: continue;
2369: }
2370: }
2371:
2372: /* Make linked list. */
2373: if (pp)
2374: pp->next = si;
2375: else
2376: rn->info = si;
2377: if (cp)
2378: cp->prev = si;
2379: si->prev = pp;
2380: si->next = cp;
2381:
2382: /* Install into rib. */
2383: static_install_ipv4 (p, si);
2384:
2385: return 1;
2386: }
2387:
2388: /* Delete static route from static route configuration. */
2389: int
2390: static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
2391: u_char distance, u_int32_t vrf_id)
2392: {
2393: u_char type = 0;
2394: struct route_node *rn;
2395: struct static_ipv4 *si;
2396: struct route_table *stable;
2397:
2398: /* Lookup table. */
2399: stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
2400: if (! stable)
2401: return -1;
2402:
2403: /* Lookup static route prefix. */
2404: rn = route_node_lookup (stable, p);
2405: if (! rn)
2406: return 0;
2407:
2408: /* Make flags. */
2409: if (gate)
2410: type = STATIC_IPV4_GATEWAY;
2411: else if (ifname)
2412: type = STATIC_IPV4_IFNAME;
2413: else
2414: type = STATIC_IPV4_BLACKHOLE;
2415:
2416: /* Find same static route is the tree */
2417: for (si = rn->info; si; si = si->next)
2418: if (type == si->type
2419: && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
2420: && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
2421: break;
2422:
2423: /* Can't find static route. */
2424: if (! si)
2425: {
2426: route_unlock_node (rn);
2427: return 0;
2428: }
2429:
2430: /* Install into rib. */
2431: static_uninstall_ipv4 (p, si);
2432:
2433: /* Unlink static route from linked list. */
2434: if (si->prev)
2435: si->prev->next = si->next;
2436: else
2437: rn->info = si->next;
2438: if (si->next)
2439: si->next->prev = si->prev;
2440: route_unlock_node (rn);
2441:
2442: /* Free static route configuration. */
2443: if (ifname)
2444: XFREE (0, si->gate.ifname);
2445: XFREE (MTYPE_STATIC_IPV4, si);
2446:
2447: route_unlock_node (rn);
2448:
2449: return 1;
2450: }
2451:
2452:
2453: #ifdef HAVE_IPV6
2454: static int
2455: rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
2456: struct in6_addr *gate, unsigned int ifindex, int table)
2457: {
2458: if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
2459: #if defined (MUSICA) || defined (LINUX)
2460: /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
2461: if (p->prefixlen == 96)
2462: return 0;
2463: #endif /* MUSICA */
2464: return 1;
2465: }
2466: if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
2467: && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
2468: {
2469: kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
2470: return 1;
2471: }
2472: return 0;
2473: }
2474:
2475: int
2476: rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
2477: struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
1.1.1.2 misho 2478: u_int32_t metric, u_char distance, safi_t safi)
1.1 misho 2479: {
2480: struct rib *rib;
2481: struct rib *same = NULL;
2482: struct route_table *table;
2483: struct route_node *rn;
2484: struct nexthop *nexthop;
2485:
2486: /* Lookup table. */
1.1.1.2 misho 2487: table = vrf_table (AFI_IP6, safi, 0);
1.1 misho 2488: if (! table)
2489: return 0;
2490:
2491: /* Make sure mask is applied. */
2492: apply_mask_ipv6 (p);
2493:
2494: /* Set default distance by route type. */
2495: if (!distance)
2496: distance = route_info[type].distance;
2497:
2498: if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
2499: distance = 200;
2500:
2501: /* Filter bogus route. */
2502: if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
2503: return 0;
2504:
2505: /* Lookup route node.*/
2506: rn = route_node_get (table, (struct prefix *) p);
2507:
2508: /* If same type of route are installed, treat it as a implicit
2509: withdraw. */
1.1.1.3 ! misho 2510: RNODE_FOREACH_RIB (rn, rib)
1.1 misho 2511: {
2512: if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2513: continue;
2514:
2515: if (rib->type != type)
2516: continue;
2517: if (rib->type != ZEBRA_ROUTE_CONNECT)
2518: {
2519: same = rib;
2520: break;
2521: }
2522: else if ((nexthop = rib->nexthop) &&
2523: nexthop->type == NEXTHOP_TYPE_IFINDEX &&
2524: nexthop->ifindex == ifindex)
2525: {
2526: rib->refcnt++;
2527: return 0;
2528: }
2529: }
2530:
2531: /* Allocate new rib structure. */
2532: rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2533:
2534: rib->type = type;
2535: rib->distance = distance;
2536: rib->flags = flags;
2537: rib->metric = metric;
2538: rib->table = vrf_id;
2539: rib->nexthop_num = 0;
2540: rib->uptime = time (NULL);
2541:
2542: /* Nexthop settings. */
2543: if (gate)
2544: {
2545: if (ifindex)
2546: nexthop_ipv6_ifindex_add (rib, gate, ifindex);
2547: else
2548: nexthop_ipv6_add (rib, gate);
2549: }
2550: else
2551: nexthop_ifindex_add (rib, ifindex);
2552:
2553: /* If this route is kernel route, set FIB flag to the route. */
2554: if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
2555: for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2556: SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2557:
2558: /* Link new rib to node.*/
2559: rib_addnode (rn, rib);
2560:
2561: /* Free implicit route.*/
2562: if (same)
2563: rib_delnode (rn, same);
2564:
2565: route_unlock_node (rn);
2566: return 0;
2567: }
2568:
2569: /* XXX factor with rib_delete_ipv6 */
2570: int
2571: rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
1.1.1.2 misho 2572: struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
1.1 misho 2573: {
2574: struct route_table *table;
2575: struct route_node *rn;
2576: struct rib *rib;
2577: struct rib *fib = NULL;
2578: struct rib *same = NULL;
2579: struct nexthop *nexthop;
2580: char buf1[INET6_ADDRSTRLEN];
2581: char buf2[INET6_ADDRSTRLEN];
2582:
2583: /* Apply mask. */
2584: apply_mask_ipv6 (p);
2585:
2586: /* Lookup table. */
1.1.1.2 misho 2587: table = vrf_table (AFI_IP6, safi, 0);
1.1 misho 2588: if (! table)
2589: return 0;
2590:
2591: /* Lookup route node. */
2592: rn = route_node_lookup (table, (struct prefix *) p);
2593: if (! rn)
2594: {
2595: if (IS_ZEBRA_DEBUG_KERNEL)
2596: {
2597: if (gate)
2598: zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
2599: inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
2600: p->prefixlen,
2601: inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
2602: ifindex);
2603: else
2604: zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
2605: inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
2606: p->prefixlen,
2607: ifindex);
2608: }
2609: return ZEBRA_ERR_RTNOEXIST;
2610: }
2611:
2612: /* Lookup same type route. */
1.1.1.3 ! misho 2613: RNODE_FOREACH_RIB (rn, rib)
1.1 misho 2614: {
2615: if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2616: continue;
2617:
2618: if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
2619: fib = rib;
2620:
2621: if (rib->type != type)
2622: continue;
2623: if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
1.1.1.2 misho 2624: nexthop->type == NEXTHOP_TYPE_IFINDEX)
1.1 misho 2625: {
1.1.1.2 misho 2626: if (nexthop->ifindex != ifindex)
2627: continue;
1.1 misho 2628: if (rib->refcnt)
2629: {
2630: rib->refcnt--;
2631: route_unlock_node (rn);
2632: route_unlock_node (rn);
2633: return 0;
2634: }
2635: same = rib;
2636: break;
2637: }
2638: /* Make sure that the route found has the same gateway. */
2639: else if (gate == NULL ||
2640: ((nexthop = rib->nexthop) &&
2641: (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate) ||
2642: IPV6_ADDR_SAME (&nexthop->rgate.ipv6, gate))))
2643: {
2644: same = rib;
2645: break;
2646: }
2647: }
2648:
2649: /* If same type of route can't be found and this message is from
2650: kernel. */
2651: if (! same)
2652: {
2653: if (fib && type == ZEBRA_ROUTE_KERNEL)
2654: {
2655: /* Unset flags. */
2656: for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
2657: UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
2658:
2659: UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
2660: }
2661: else
2662: {
2663: if (IS_ZEBRA_DEBUG_KERNEL)
2664: {
2665: if (gate)
2666: zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
2667: inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
2668: p->prefixlen,
2669: inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
2670: ifindex,
2671: type);
2672: else
2673: zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
2674: inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
2675: p->prefixlen,
2676: ifindex,
2677: type);
2678: }
2679: route_unlock_node (rn);
2680: return ZEBRA_ERR_RTNOEXIST;
2681: }
2682: }
2683:
2684: if (same)
2685: rib_delnode (rn, same);
2686:
2687: route_unlock_node (rn);
2688: return 0;
2689: }
2690:
2691: /* Install static route into rib. */
2692: static void
2693: static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
2694: {
2695: struct rib *rib;
2696: struct route_table *table;
2697: struct route_node *rn;
2698:
2699: /* Lookup table. */
2700: table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2701: if (! table)
2702: return;
2703:
2704: /* Lookup existing route */
2705: rn = route_node_get (table, p);
1.1.1.3 ! misho 2706: RNODE_FOREACH_RIB (rn, rib)
1.1 misho 2707: {
2708: if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
2709: continue;
2710:
2711: if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2712: break;
2713: }
2714:
2715: if (rib)
2716: {
2717: /* Same distance static route is there. Update it with new
2718: nexthop. */
2719: route_unlock_node (rn);
2720:
2721: switch (si->type)
2722: {
2723: case STATIC_IPV6_GATEWAY:
2724: nexthop_ipv6_add (rib, &si->ipv6);
2725: break;
2726: case STATIC_IPV6_IFNAME:
2727: nexthop_ifname_add (rib, si->ifname);
2728: break;
2729: case STATIC_IPV6_GATEWAY_IFNAME:
2730: nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2731: break;
2732: }
2733: rib_queue_add (&zebrad, rn);
2734: }
2735: else
2736: {
2737: /* This is new static route. */
2738: rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2739:
2740: rib->type = ZEBRA_ROUTE_STATIC;
2741: rib->distance = si->distance;
2742: rib->metric = 0;
2743: rib->nexthop_num = 0;
2744:
2745: switch (si->type)
2746: {
2747: case STATIC_IPV6_GATEWAY:
2748: nexthop_ipv6_add (rib, &si->ipv6);
2749: break;
2750: case STATIC_IPV6_IFNAME:
2751: nexthop_ifname_add (rib, si->ifname);
2752: break;
2753: case STATIC_IPV6_GATEWAY_IFNAME:
2754: nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
2755: break;
2756: }
2757:
2758: /* Save the flags of this static routes (reject, blackhole) */
2759: rib->flags = si->flags;
2760:
2761: /* Link this rib to the tree. */
2762: rib_addnode (rn, rib);
2763: }
2764: }
2765:
2766: static int
2767: static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
2768: {
2769: if (nexthop->type == NEXTHOP_TYPE_IPV6
2770: && si->type == STATIC_IPV6_GATEWAY
2771: && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
2772: return 1;
2773: if (nexthop->type == NEXTHOP_TYPE_IFNAME
2774: && si->type == STATIC_IPV6_IFNAME
2775: && strcmp (nexthop->ifname, si->ifname) == 0)
2776: return 1;
2777: if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
2778: && si->type == STATIC_IPV6_GATEWAY_IFNAME
2779: && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
2780: && strcmp (nexthop->ifname, si->ifname) == 0)
2781: return 1;
2782: return 0;
2783: }
2784:
2785: static void
2786: static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
2787: {
2788: struct route_table *table;
2789: struct route_node *rn;
2790: struct rib *rib;
2791: struct nexthop *nexthop;
2792:
2793: /* Lookup table. */
2794: table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
2795: if (! table)
2796: return;
2797:
2798: /* Lookup existing route with type and distance. */
2799: rn = route_node_lookup (table, (struct prefix *) p);
2800: if (! rn)
2801: return;
2802:
1.1.1.3 ! misho 2803: RNODE_FOREACH_RIB (rn, rib)
1.1 misho 2804: {
2805: if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
2806: continue;
2807:
2808: if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
2809: break;
2810: }
2811:
2812: if (! rib)
2813: {
2814: route_unlock_node (rn);
2815: return;
2816: }
2817:
2818: /* Lookup nexthop. */
2819: for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
2820: if (static_ipv6_nexthop_same (nexthop, si))
2821: break;
2822:
2823: /* Can't find nexthop. */
2824: if (! nexthop)
2825: {
2826: route_unlock_node (rn);
2827: return;
2828: }
2829:
2830: /* Check nexthop. */
2831: if (rib->nexthop_num == 1)
2832: {
2833: rib_delnode (rn, rib);
2834: }
2835: else
2836: {
2837: if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
2838: rib_uninstall (rn, rib);
2839: nexthop_delete (rib, nexthop);
2840: nexthop_free (nexthop);
2841: rib_queue_add (&zebrad, rn);
2842: }
2843: /* Unlock node. */
2844: route_unlock_node (rn);
2845: }
2846:
2847: /* Add static route into static route configuration. */
2848: int
2849: static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
2850: const char *ifname, u_char flags, u_char distance,
2851: u_int32_t vrf_id)
2852: {
2853: struct route_node *rn;
2854: struct static_ipv6 *si;
2855: struct static_ipv6 *pp;
2856: struct static_ipv6 *cp;
2857: struct route_table *stable;
2858:
2859: /* Lookup table. */
2860: stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2861: if (! stable)
2862: return -1;
2863:
2864: if (!gate &&
2865: (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
2866: return -1;
2867:
2868: if (!ifname &&
2869: (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
2870: return -1;
2871:
2872: /* Lookup static route prefix. */
2873: rn = route_node_get (stable, p);
2874:
2875: /* Do nothing if there is a same static route. */
2876: for (si = rn->info; si; si = si->next)
2877: {
2878: if (distance == si->distance
2879: && type == si->type
2880: && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2881: && (! ifname || strcmp (ifname, si->ifname) == 0))
2882: {
2883: route_unlock_node (rn);
2884: return 0;
2885: }
2886: }
2887:
2888: /* Make new static route structure. */
2889: si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
2890:
2891: si->type = type;
2892: si->distance = distance;
2893: si->flags = flags;
2894:
2895: switch (type)
2896: {
2897: case STATIC_IPV6_GATEWAY:
2898: si->ipv6 = *gate;
2899: break;
2900: case STATIC_IPV6_IFNAME:
2901: si->ifname = XSTRDUP (0, ifname);
2902: break;
2903: case STATIC_IPV6_GATEWAY_IFNAME:
2904: si->ipv6 = *gate;
2905: si->ifname = XSTRDUP (0, ifname);
2906: break;
2907: }
2908:
2909: /* Add new static route information to the tree with sort by
2910: distance value and gateway address. */
2911: for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
2912: {
2913: if (si->distance < cp->distance)
2914: break;
2915: if (si->distance > cp->distance)
2916: continue;
2917: }
2918:
2919: /* Make linked list. */
2920: if (pp)
2921: pp->next = si;
2922: else
2923: rn->info = si;
2924: if (cp)
2925: cp->prev = si;
2926: si->prev = pp;
2927: si->next = cp;
2928:
2929: /* Install into rib. */
2930: static_install_ipv6 (p, si);
2931:
2932: return 1;
2933: }
2934:
2935: /* Delete static route from static route configuration. */
2936: int
2937: static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
2938: const char *ifname, u_char distance, u_int32_t vrf_id)
2939: {
2940: struct route_node *rn;
2941: struct static_ipv6 *si;
2942: struct route_table *stable;
2943:
2944: /* Lookup table. */
2945: stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2946: if (! stable)
2947: return -1;
2948:
2949: /* Lookup static route prefix. */
2950: rn = route_node_lookup (stable, p);
2951: if (! rn)
2952: return 0;
2953:
2954: /* Find same static route is the tree */
2955: for (si = rn->info; si; si = si->next)
2956: if (distance == si->distance
2957: && type == si->type
2958: && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
2959: && (! ifname || strcmp (ifname, si->ifname) == 0))
2960: break;
2961:
2962: /* Can't find static route. */
2963: if (! si)
2964: {
2965: route_unlock_node (rn);
2966: return 0;
2967: }
2968:
2969: /* Install into rib. */
2970: static_uninstall_ipv6 (p, si);
2971:
2972: /* Unlink static route from linked list. */
2973: if (si->prev)
2974: si->prev->next = si->next;
2975: else
2976: rn->info = si->next;
2977: if (si->next)
2978: si->next->prev = si->prev;
2979:
2980: /* Free static route configuration. */
2981: if (ifname)
2982: XFREE (0, si->ifname);
2983: XFREE (MTYPE_STATIC_IPV6, si);
2984:
2985: return 1;
2986: }
2987: #endif /* HAVE_IPV6 */
2988:
2989: /* RIB update function. */
2990: void
2991: rib_update (void)
2992: {
2993: struct route_node *rn;
2994: struct route_table *table;
2995:
2996: table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
2997: if (table)
2998: for (rn = route_top (table); rn; rn = route_next (rn))
1.1.1.3 ! misho 2999: if (rnode_to_ribs (rn))
1.1 misho 3000: rib_queue_add (&zebrad, rn);
3001:
3002: table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
3003: if (table)
3004: for (rn = route_top (table); rn; rn = route_next (rn))
1.1.1.3 ! misho 3005: if (rnode_to_ribs (rn))
1.1 misho 3006: rib_queue_add (&zebrad, rn);
3007: }
3008:
3009:
3010: /* Remove all routes which comes from non main table. */
3011: static void
3012: rib_weed_table (struct route_table *table)
3013: {
3014: struct route_node *rn;
3015: struct rib *rib;
3016: struct rib *next;
3017:
3018: if (table)
3019: for (rn = route_top (table); rn; rn = route_next (rn))
1.1.1.3 ! misho 3020: RNODE_FOREACH_RIB_SAFE (rn, rib, next)
1.1 misho 3021: {
3022: if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3023: continue;
3024:
3025: if (rib->table != zebrad.rtm_table_default &&
3026: rib->table != RT_TABLE_MAIN)
3027: rib_delnode (rn, rib);
3028: }
3029: }
3030:
3031: /* Delete all routes from non main table. */
3032: void
3033: rib_weed_tables (void)
3034: {
3035: rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3036: rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3037: }
3038:
3039: /* Delete self installed routes after zebra is relaunched. */
3040: static void
3041: rib_sweep_table (struct route_table *table)
3042: {
3043: struct route_node *rn;
3044: struct rib *rib;
3045: struct rib *next;
3046: int ret = 0;
3047:
3048: if (table)
3049: for (rn = route_top (table); rn; rn = route_next (rn))
1.1.1.3 ! misho 3050: RNODE_FOREACH_RIB_SAFE (rn, rib, next)
1.1 misho 3051: {
3052: if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3053: continue;
3054:
3055: if (rib->type == ZEBRA_ROUTE_KERNEL &&
3056: CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
3057: {
3058: ret = rib_uninstall_kernel (rn, rib);
3059: if (! ret)
3060: rib_delnode (rn, rib);
3061: }
3062: }
3063: }
3064:
3065: /* Sweep all RIB tables. */
3066: void
3067: rib_sweep_route (void)
3068: {
3069: rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3070: rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3071: }
1.1.1.2 misho 3072:
3073: /* Remove specific by protocol routes from 'table'. */
3074: static unsigned long
3075: rib_score_proto_table (u_char proto, struct route_table *table)
3076: {
3077: struct route_node *rn;
3078: struct rib *rib;
3079: struct rib *next;
3080: unsigned long n = 0;
3081:
3082: if (table)
3083: for (rn = route_top (table); rn; rn = route_next (rn))
1.1.1.3 ! misho 3084: RNODE_FOREACH_RIB_SAFE (rn, rib, next)
1.1.1.2 misho 3085: {
3086: if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
3087: continue;
3088: if (rib->type == proto)
3089: {
3090: rib_delnode (rn, rib);
3091: n++;
3092: }
3093: }
3094:
3095: return n;
3096: }
3097:
3098: /* Remove specific by protocol routes. */
3099: unsigned long
3100: rib_score_proto (u_char proto)
3101: {
3102: return rib_score_proto_table (proto, vrf_table (AFI_IP, SAFI_UNICAST, 0))
3103: +rib_score_proto_table (proto, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3104: }
3105:
1.1 misho 3106: /* Close RIB and clean up kernel routes. */
3107: static void
3108: rib_close_table (struct route_table *table)
3109: {
3110: struct route_node *rn;
3111: struct rib *rib;
3112:
3113: if (table)
3114: for (rn = route_top (table); rn; rn = route_next (rn))
1.1.1.3 ! misho 3115: RNODE_FOREACH_RIB (rn, rib)
1.1 misho 3116: {
1.1.1.3 ! misho 3117: if (!CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
! 3118: continue;
! 3119:
! 3120: zfpm_trigger_update (rn, NULL);
! 3121:
! 3122: if (! RIB_SYSTEM_ROUTE (rib))
! 3123: rib_uninstall_kernel (rn, rib);
1.1 misho 3124: }
3125: }
3126:
3127: /* Close all RIB tables. */
3128: void
3129: rib_close (void)
3130: {
3131: rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
3132: rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
3133: }
3134:
3135: /* Routing information base initialize. */
3136: void
3137: rib_init (void)
3138: {
3139: rib_queue_init (&zebrad);
3140: /* VRF initialization. */
3141: vrf_init ();
3142: }
1.1.1.3 ! misho 3143:
! 3144: /*
! 3145: * vrf_id_get_next
! 3146: *
! 3147: * Get the first vrf id that is greater than the given vrf id if any.
! 3148: *
! 3149: * Returns TRUE if a vrf id was found, FALSE otherwise.
! 3150: */
! 3151: static inline int
! 3152: vrf_id_get_next (uint32_t id, uint32_t *next_id_p)
! 3153: {
! 3154: while (++id < vector_active (vrf_vector))
! 3155: {
! 3156: if (vrf_lookup (id))
! 3157: {
! 3158: *next_id_p = id;
! 3159: return 1;
! 3160: }
! 3161: }
! 3162:
! 3163: return 0;
! 3164: }
! 3165:
! 3166: /*
! 3167: * rib_tables_iter_next
! 3168: *
! 3169: * Returns the next table in the iteration.
! 3170: */
! 3171: struct route_table *
! 3172: rib_tables_iter_next (rib_tables_iter_t *iter)
! 3173: {
! 3174: struct route_table *table;
! 3175:
! 3176: /*
! 3177: * Array that helps us go over all AFI/SAFI combinations via one
! 3178: * index.
! 3179: */
! 3180: static struct {
! 3181: afi_t afi;
! 3182: safi_t safi;
! 3183: } afi_safis[] = {
! 3184: { AFI_IP, SAFI_UNICAST },
! 3185: { AFI_IP, SAFI_MULTICAST },
! 3186: { AFI_IP6, SAFI_UNICAST },
! 3187: { AFI_IP6, SAFI_MULTICAST },
! 3188: };
! 3189:
! 3190: table = NULL;
! 3191:
! 3192: switch (iter->state)
! 3193: {
! 3194:
! 3195: case RIB_TABLES_ITER_S_INIT:
! 3196: iter->vrf_id = 0;
! 3197: iter->afi_safi_ix = -1;
! 3198:
! 3199: /* Fall through */
! 3200:
! 3201: case RIB_TABLES_ITER_S_ITERATING:
! 3202: iter->afi_safi_ix++;
! 3203: while (1)
! 3204: {
! 3205:
! 3206: while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
! 3207: {
! 3208: table = vrf_table (afi_safis[iter->afi_safi_ix].afi,
! 3209: afi_safis[iter->afi_safi_ix].safi,
! 3210: iter->vrf_id);
! 3211: if (table)
! 3212: break;
! 3213:
! 3214: iter->afi_safi_ix++;
! 3215: }
! 3216:
! 3217: /*
! 3218: * Found another table in this vrf.
! 3219: */
! 3220: if (table)
! 3221: break;
! 3222:
! 3223: /*
! 3224: * Done with all tables in the current vrf, go to the next
! 3225: * one.
! 3226: */
! 3227: if (!vrf_id_get_next (iter->vrf_id, &iter->vrf_id))
! 3228: break;
! 3229:
! 3230: iter->afi_safi_ix = 0;
! 3231: }
! 3232:
! 3233: break;
! 3234:
! 3235: case RIB_TABLES_ITER_S_DONE:
! 3236: return NULL;
! 3237: }
! 3238:
! 3239: if (table)
! 3240: iter->state = RIB_TABLES_ITER_S_ITERATING;
! 3241: else
! 3242: iter->state = RIB_TABLES_ITER_S_DONE;
! 3243:
! 3244: return table;
! 3245: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>