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