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