diff options
| -rw-r--r-- | lib/memtypes.c | 3 | ||||
| -rw-r--r-- | lib/nexthop.h | 2 | ||||
| -rw-r--r-- | zebra/rib.h | 79 | ||||
| -rw-r--r-- | zebra/zebra_rib.c | 444 | ||||
| -rw-r--r-- | zebra/zebra_vty.c | 36 |
5 files changed, 192 insertions, 372 deletions
diff --git a/lib/memtypes.c b/lib/memtypes.c index fc50443600..828820f309 100644 --- a/lib/memtypes.c +++ b/lib/memtypes.c @@ -85,8 +85,7 @@ struct memory_list memory_list_zebra[] = { MTYPE_NEXTHOP, "Nexthop" }, { MTYPE_RIB, "RIB" }, { MTYPE_RIB_QUEUE, "RIB process work queue" }, - { MTYPE_STATIC_IPV4, "Static IPv4 route" }, - { MTYPE_STATIC_IPV6, "Static IPv6 route" }, + { MTYPE_STATIC_ROUTE, "Static route" }, { MTYPE_RIB_DEST, "RIB destination" }, { MTYPE_RIB_TABLE_INFO, "RIB table info" }, { MTYPE_RNH, "Nexthop tracking object" }, diff --git a/lib/nexthop.h b/lib/nexthop.h index e92d97262c..6909775a06 100644 --- a/lib/nexthop.h +++ b/lib/nexthop.h @@ -27,9 +27,7 @@ union g_addr { struct in_addr ipv4; -#ifdef HAVE_IPV6 struct in6_addr ipv6; -#endif /* HAVE_IPV6 */ }; enum nexthop_types_t diff --git a/zebra/rib.h b/zebra/rib.h index 25ab68df13..cd77db4df1 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -169,11 +169,11 @@ typedef struct rib_dest_t_ RIB_DEST_FOREACH_ROUTE_SAFE (rib_dest_from_rnode (rn), rib, next) /* Static route information. */ -struct static_ipv4 +struct static_route { /* For linked list. */ - struct static_ipv4 *prev; - struct static_ipv4 *next; + struct static_route *prev; + struct static_route *next; /* VRF identifier. */ vrf_id_t vrf_id; @@ -186,50 +186,22 @@ struct static_ipv4 /* Flag for this static route's type. */ u_char type; -#define STATIC_IPV4_GATEWAY 1 -#define STATIC_IPV4_IFNAME 2 -#define STATIC_IPV4_BLACKHOLE 3 +#define STATIC_IPV4_GATEWAY 1 +#define STATIC_IPV4_IFNAME 2 +#define STATIC_IPV4_BLACKHOLE 3 +#define STATIC_IPV6_GATEWAY 4 +#define STATIC_IPV6_GATEWAY_IFNAME 5 +#define STATIC_IPV6_IFNAME 6 - /* Nexthop value. */ - union - { - struct in_addr ipv4; - char *ifname; - } gate; - - /* bit flags */ - u_char flags; -/* - see ZEBRA_FLAG_REJECT - ZEBRA_FLAG_BLACKHOLE - */ -}; - -#ifdef HAVE_IPV6 -/* Static route information. */ -struct static_ipv6 -{ - /* For linked list. */ - struct static_ipv6 *prev; - struct static_ipv6 *next; - - /* VRF identifier. */ - vrf_id_t vrf_id; - - /* Administrative distance. */ - u_char distance; - - /* Tag */ - u_short tag; - - /* Flag for this static route's type. */ - u_char type; -#define STATIC_IPV6_GATEWAY 1 -#define STATIC_IPV6_GATEWAY_IFNAME 2 -#define STATIC_IPV6_IFNAME 3 - - /* Nexthop value. */ - struct in6_addr ipv6; + /* + * Nexthop value. + * + * Under IPv4 addr and ifname are + * used independentyly. + * STATIC_IPV4_GATEWAY uses addr + * STATIC_IPV4_IFNAME uses ifname + */ + union g_addr addr; char *ifname; /* bit flags */ @@ -239,7 +211,7 @@ struct static_ipv6 ZEBRA_FLAG_BLACKHOLE */ }; -#endif /* HAVE_IPV6 */ + /* The following for loop allows to iterate over the nexthop * structure of routes. @@ -296,7 +268,7 @@ struct static_ipv6 #endif #endif -#if defined (HAVE_IPV6) && defined (RTADV) +#if defined (RTADV) /* Structure which hold status of router advertisement. */ struct rtadv { @@ -308,7 +280,7 @@ struct rtadv struct thread *ra_read; struct thread *ra_timer; }; -#endif /* RTADV && HAVE_IPV6 */ +#endif /* RTADV */ #ifdef HAVE_NETLINK /* Socket interface to kernel */ @@ -366,9 +338,9 @@ struct zebra_vrf struct list *rid_lo_sorted_list; struct prefix rid_user_assigned; -#if defined (HAVE_IPV6) && defined (RTADV) +#if defined (RTADV) struct rtadv rtadv; -#endif /* RTADV && HAVE_IPV6 */ +#endif /* RTADV */ }; /* @@ -438,7 +410,6 @@ extern int rib_lookup_ipv4_route (struct prefix_ipv4 *, union sockunion *, #define ZEBRA_RIB_FOUND_CONNECTED 2 #define ZEBRA_RIB_NOTFOUND 3 -#ifdef HAVE_IPV6 extern struct nexthop *nexthop_ipv6_add (struct rib *, struct in6_addr *); extern struct nexthop *nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6, unsigned int ifindex); @@ -448,7 +419,6 @@ extern struct nexthop *nexthop_ipv6_ifname_add (struct rib *rib, extern int rib_bogus_ipv6 (int type, struct prefix_ipv6 *p, struct in6_addr *gate, unsigned int ifindex, int table); -#endif /* HAVE_IPV6 */ extern struct zebra_vrf *zebra_vrf_lookup (vrf_id_t vrf_id); extern struct zebra_vrf *zebra_vrf_alloc (vrf_id_t); @@ -498,7 +468,6 @@ extern int static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, u_short tag, u_char distance, vrf_id_t vrf_id); -#ifdef HAVE_IPV6 extern int rib_add_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p, struct in6_addr *gate, unsigned int ifindex, vrf_id_t vrf_id, @@ -529,8 +498,6 @@ static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, const char *ifname, u_short tag, u_char distance, vrf_id_t vrf_id); -#endif /* HAVE_IPV6 */ - extern int rib_gc_dest (struct route_node *rn); extern struct route_table *rib_tables_iter_next (rib_tables_iter_t *iter); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index ffa3161f2b..0bb9b58118 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -139,7 +139,6 @@ zebra_check_addr (struct prefix *p) || IPV4_LINKLOCAL(addr)) return 0; } -#ifdef HAVE_IPV6 if (p->family == AF_INET6) { if (IN6_IS_ADDR_LOOPBACK (&p->u.prefix6)) @@ -147,7 +146,6 @@ zebra_check_addr (struct prefix *p) if (IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6)) return 0; } -#endif /* HAVE_IPV6 */ return 1; } @@ -348,7 +346,6 @@ nexthop_ipv4_ifindex_ol_add (struct rib *rib, const struct in_addr *ipv4, return nexthop; } -#ifdef HAVE_IPV6 struct nexthop * nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6) { @@ -394,7 +391,6 @@ nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6, return nexthop; } -#endif /* HAVE_IPV6 */ struct nexthop * nexthop_blackhole_add (struct rib *rib) @@ -650,7 +646,6 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set, return 0; } -#ifdef HAVE_IPV6 /* If force flag is not set, do not modify falgs at all for uninstall the route from FIB. */ static int @@ -840,7 +835,6 @@ nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set, } return 0; } -#endif /* HAVE_IPV6 */ struct rib * rib_match_ipv4 (struct in_addr addr, vrf_id_t vrf_id) @@ -1026,7 +1020,6 @@ rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate, return ZEBRA_RIB_NOTFOUND; } -#ifdef HAVE_IPV6 struct rib * rib_match_ipv6 (struct in6_addr *addr, vrf_id_t vrf_id) { @@ -1088,7 +1081,6 @@ rib_match_ipv6 (struct in6_addr *addr, vrf_id_t vrf_id) } return NULL; } -#endif /* HAVE_IPV6 */ #define RIB_SYSTEM_ROUTE(R) \ ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT) @@ -1153,7 +1145,6 @@ nexthop_active_check (struct route_node *rn, struct rib *rib, else UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); break; -#ifdef HAVE_IPV6 case NEXTHOP_TYPE_IPV6: family = AFI_IP6; if (nexthop_active_ipv6 (rib, nexthop, set, rn)) @@ -1181,7 +1172,6 @@ nexthop_active_check (struct route_node *rn, struct rib *rib, UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); } break; -#endif /* HAVE_IPV6 */ case NEXTHOP_TYPE_BLACKHOLE: SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); break; @@ -1305,11 +1295,9 @@ rib_install_kernel (struct route_node *rn, struct rib *rib, int update) else ret = kernel_add_ipv4 (&rn->p, rib); break; -#ifdef HAVE_IPV6 case AF_INET6: ret = kernel_add_ipv6 (&rn->p, rib); break; -#endif /* HAVE_IPV6 */ } /* This condition is never met, if we are using rt_socket.c */ @@ -1339,11 +1327,9 @@ rib_uninstall_kernel (struct route_node *rn, struct rib *rib) case AF_INET: ret = kernel_delete_ipv4 (&rn->p, rib); break; -#ifdef HAVE_IPV6 case AF_INET6: ret = kernel_delete_ipv6 (&rn->p, rib); break; -#endif /* HAVE_IPV6 */ } for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) @@ -1781,10 +1767,8 @@ meta_queue_process_complete (struct work_queue *dummy) { zebra_evaluate_rnh(0, AF_INET, 0, RNH_NEXTHOP_TYPE, NULL); zebra_evaluate_rnh(0, AF_INET, 0, RNH_IMPORT_CHECK_TYPE, NULL); -#ifdef HAVE_IPV6 zebra_evaluate_rnh(0, AF_INET6, 0, RNH_NEXTHOP_TYPE, NULL); zebra_evaluate_rnh(0, AF_INET6, 0, RNH_IMPORT_CHECK_TYPE, NULL); -#endif /* HAVE_IPV6 */ } /* Dispatch the meta queue by picking, processing and unlocking the next RN from @@ -1967,7 +1951,7 @@ rib_queue_init (struct zebra_t *zebra) * as a route_node will not be requeued, if already queued. * * RIBs are submitted via rib_addnode or rib_delnode which set minimal - * state, or static_install_ipv{4,6} (when an existing RIB is updated) + * state, or static_install_route (when an existing RIB is updated) * and then submit route_node to queue for best-path selection later. * Order of add/delete state changes are preserved for any given RIB. * @@ -2678,7 +2662,7 @@ rib_delete_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p, /* Install static route into rib. */ static void -static_install_ipv4 (struct prefix *p, struct static_ipv4 *si) +static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si) { struct rib *rib; struct route_node *rn; @@ -2686,7 +2670,7 @@ static_install_ipv4 (struct prefix *p, struct static_ipv4 *si) struct prefix nh_p; /* Lookup table. */ - table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, si->vrf_id); + table = zebra_vrf_table (afi, safi, si->vrf_id); if (! table) return; @@ -2712,19 +2696,32 @@ static_install_ipv4 (struct prefix *p, struct static_ipv4 *si) route_unlock_node (rn); switch (si->type) { - case STATIC_IPV4_GATEWAY: - nexthop_ipv4_add (rib, &si->gate.ipv4, NULL); - nh_p.family = AF_INET; - nh_p.prefixlen = IPV4_MAX_BITLEN; - nh_p.u.prefix4 = si->gate.ipv4; - zebra_register_rnh_static_nh(&nh_p, rn); - break; - case STATIC_IPV4_IFNAME: - nexthop_ifname_add (rib, si->gate.ifname); - break; - case STATIC_IPV4_BLACKHOLE: - nexthop_blackhole_add (rib); - break; + case STATIC_IPV4_GATEWAY: + nexthop_ipv4_add (rib, &si->addr.ipv4, NULL); + nh_p.family = AF_INET; + nh_p.prefixlen = IPV4_MAX_BITLEN; + nh_p.u.prefix4 = si->addr.ipv4; + zebra_register_rnh_static_nh(&nh_p, rn); + break; + case STATIC_IPV4_IFNAME: + nexthop_ifname_add (rib, si->ifname); + break; + case STATIC_IPV4_BLACKHOLE: + nexthop_blackhole_add (rib); + break; + case STATIC_IPV6_GATEWAY: + nexthop_ipv6_add (rib, &si->addr.ipv6); + nh_p.family = AF_INET6; + nh_p.prefixlen = IPV6_MAX_BITLEN; + nh_p.u.prefix6 = si->addr.ipv6; + zebra_register_rnh_static_nh(&nh_p, rn); + break; + case STATIC_IPV6_IFNAME: + nexthop_ifname_add (rib, si->ifname); + break; + case STATIC_IPV6_GATEWAY_IFNAME: + nexthop_ipv6_ifname_add (rib, &si->addr.ipv6, si->ifname); + break; } rib_queue_add (&zebrad, rn); } @@ -2744,19 +2741,32 @@ static_install_ipv4 (struct prefix *p, struct static_ipv4 *si) switch (si->type) { - case STATIC_IPV4_GATEWAY: - nexthop_ipv4_add (rib, &si->gate.ipv4, NULL); - nh_p.family = AF_INET; - nh_p.prefixlen = IPV4_MAX_BITLEN; - nh_p.u.prefix4 = si->gate.ipv4; - zebra_register_rnh_static_nh(&nh_p, rn); - break; - case STATIC_IPV4_IFNAME: - nexthop_ifname_add (rib, si->gate.ifname); - break; - case STATIC_IPV4_BLACKHOLE: - nexthop_blackhole_add (rib); - break; + case STATIC_IPV4_GATEWAY: + nexthop_ipv4_add (rib, &si->addr.ipv4, NULL); + nh_p.family = AF_INET; + nh_p.prefixlen = IPV4_MAX_BITLEN; + nh_p.u.prefix4 = si->addr.ipv4; + zebra_register_rnh_static_nh(&nh_p, rn); + break; + case STATIC_IPV4_IFNAME: + nexthop_ifname_add (rib, si->ifname); + break; + case STATIC_IPV4_BLACKHOLE: + nexthop_blackhole_add (rib); + break; + case STATIC_IPV6_GATEWAY: + nexthop_ipv6_add (rib, &si->addr.ipv6); + nh_p.family = AF_INET6; + nh_p.prefixlen = IPV6_MAX_BITLEN; + nh_p.u.prefix6 = si->addr.ipv6; + zebra_register_rnh_static_nh(&nh_p, rn); + break; + case STATIC_IPV6_IFNAME: + nexthop_ifname_add (rib, si->ifname); + break; + case STATIC_IPV6_GATEWAY_IFNAME: + nexthop_ipv6_ifname_add (rib, &si->addr.ipv6, si->ifname); + break; } /* Save the flags of this static routes (reject, blackhole) */ @@ -2768,25 +2778,38 @@ static_install_ipv4 (struct prefix *p, struct static_ipv4 *si) } static int -static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si) +static_nexthop_same (struct nexthop *nexthop, struct static_route *si) { if (nexthop->type == NEXTHOP_TYPE_IPV4 && si->type == STATIC_IPV4_GATEWAY - && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4)) + && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->addr.ipv4)) return 1; if (nexthop->type == NEXTHOP_TYPE_IFNAME && si->type == STATIC_IPV4_IFNAME - && strcmp (nexthop->ifname, si->gate.ifname) == 0) + && strcmp (nexthop->ifname, si->ifname) == 0) return 1; if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE && si->type == STATIC_IPV4_BLACKHOLE) return 1; + if (nexthop->type == NEXTHOP_TYPE_IPV6 + && si->type == STATIC_IPV6_GATEWAY + && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6)) + return 1; + if (nexthop->type == NEXTHOP_TYPE_IFNAME + && si->type == STATIC_IPV6_IFNAME + && strcmp (nexthop->ifname, si->ifname) == 0) + return 1; + if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME + && si->type == STATIC_IPV6_GATEWAY_IFNAME + && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6) + && strcmp (nexthop->ifname, si->ifname) == 0) + return 1; return 0; } /* Uninstall static route from RIB. */ static void -static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si) +static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si) { struct route_node *rn; struct rib *rib; @@ -2795,7 +2818,7 @@ static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si) struct prefix nh_p; /* Lookup table. */ - table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, si->vrf_id); + table = zebra_vrf_table (afi, safi, si->vrf_id); if (! table) return; @@ -2822,7 +2845,7 @@ static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si) /* Lookup nexthop. */ for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) - if (static_ipv4_nexthop_same (nexthop, si)) + if (static_nexthop_same (nexthop, si)) break; /* Can't find nexthop. */ @@ -2844,23 +2867,46 @@ static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si) UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) { - /* If there are other active nexthops, do an update. */ - if (rib->nexthop_active_num > 1) - { - rib_install_kernel (rn, rib, 1); - redistribute_update (&rn->p, rib, NULL); - } - else + if (afi == AFI_IP) + { + /* If there are other active nexthops, do an update. */ + if (rib->nexthop_active_num > 1) + { + rib_install_kernel (rn, rib, 1); + redistribute_update (&rn->p, rib, NULL); + } + else + { + redistribute_delete (&rn->p, rib); + rib_uninstall_kernel (rn, rib); + } + } + else { redistribute_delete (&rn->p, rib); rib_uninstall_kernel (rn, rib); + /* Are there other active nexthops? */ + if (rib->nexthop_active_num > 1) + { + rib_install_kernel (rn, rib, 0); + redistribute_update (&rn->p, rib, NULL); + } } } - /* Delete the nexthop and dereg from NHT */ - nh_p.family = AF_INET; - nh_p.prefixlen = IPV4_MAX_BITLEN; - nh_p.u.prefix4 = nexthop->gate.ipv4; + if (afi == AFI_IP) + { + /* Delete the nexthop and dereg from NHT */ + nh_p.family = AF_INET; + nh_p.prefixlen = IPV4_MAX_BITLEN; + nh_p.u.prefix4 = nexthop->gate.ipv4; + } + else + { + nh_p.family = AF_INET6; + nh_p.prefixlen = IPV6_MAX_BITLEN; + nh_p.u.prefix6 = nexthop->gate.ipv6; + } nexthop_delete (rib, nexthop); zebra_deregister_rnh_static_nh(&nh_p, rn); nexthop_free (nexthop, rn); @@ -2876,10 +2922,10 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, { u_char type = 0; struct route_node *rn; - struct static_ipv4 *si; - struct static_ipv4 *pp; - struct static_ipv4 *cp; - struct static_ipv4 *update = NULL; + struct static_route *si; + struct static_route *pp; + struct static_route *cp; + struct static_route *update = NULL; struct zebra_vrf *zvrf = vrf_info_get (vrf_id); struct route_table *stable = zvrf->stable[AFI_IP][SAFI_UNICAST]; @@ -2901,8 +2947,8 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, for (si = rn->info; si; si = si->next) { if (type == si->type - && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4)) - && (! ifname || strcmp (ifname, si->gate.ifname) == 0)) + && (! gate || IPV4_ADDR_SAME (gate, &si->addr.ipv4)) + && (! ifname || strcmp (ifname, si->ifname) == 0)) { if ((distance == si->distance) && (tag == si->tag)) { @@ -2919,7 +2965,7 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, static_delete_ipv4 (p, gate, ifname, update->tag, update->distance, vrf_id); /* Make new static route structure. */ - si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4)); + si = XCALLOC (MTYPE_STATIC_ROUTE, sizeof (struct static_route)); si->type = type; si->distance = distance; @@ -2928,9 +2974,9 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, si->vrf_id = vrf_id; if (gate) - si->gate.ipv4 = *gate; + si->addr.ipv4 = *gate; if (ifname) - si->gate.ifname = XSTRDUP (0, ifname); + si->ifname = XSTRDUP (0, ifname); /* Add new static route information to the tree with sort by distance value and gateway address. */ @@ -2942,9 +2988,9 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, continue; if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY) { - if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr)) + if (ntohl (si->addr.ipv4.s_addr) < ntohl (cp->addr.ipv4.s_addr)) break; - if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr)) + if (ntohl (si->addr.ipv4.s_addr) > ntohl (cp->addr.ipv4.s_addr)) continue; } } @@ -2960,7 +3006,7 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, si->next = cp; /* Install into rib. */ - static_install_ipv4 (p, si); + static_install_route (AFI_IP, SAFI_UNICAST, p, si); return 1; } @@ -2972,7 +3018,7 @@ static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, { u_char type = 0; struct route_node *rn; - struct static_ipv4 *si; + struct static_route *si; struct route_table *stable; /* Lookup table. */ @@ -2996,8 +3042,8 @@ static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, /* Find same static route is the tree */ for (si = rn->info; si; si = si->next) if (type == si->type - && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4)) - && (! ifname || strcmp (ifname, si->gate.ifname) == 0) + && (! gate || IPV4_ADDR_SAME (gate, &si->addr.ipv4)) + && (! ifname || strcmp (ifname, si->ifname) == 0) && (! tag || (tag == si->tag))) break; @@ -3009,7 +3055,7 @@ static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, } /* Install into rib. */ - static_uninstall_ipv4 (p, si); + static_uninstall_route (AFI_IP, SAFI_UNICAST, p, si); /* Unlink static route from linked list. */ if (si->prev) @@ -3022,8 +3068,8 @@ static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, /* Free static route configuration. */ if (ifname) - XFREE (0, si->gate.ifname); - XFREE (MTYPE_STATIC_IPV4, si); + XFREE (0, si->ifname); + XFREE (MTYPE_STATIC_ROUTE, si); route_unlock_node (rn); @@ -3031,7 +3077,6 @@ static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, } -#ifdef HAVE_IPV6 int rib_bogus_ipv6 (int type, struct prefix_ipv6 *p, struct in6_addr *gate, unsigned int ifindex, int table) @@ -3442,200 +3487,6 @@ rib_delete_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p, return 0; } -/* Install static route into rib. */ -static void -static_install_ipv6 (struct prefix *p, struct static_ipv6 *si) -{ - struct rib *rib; - struct route_table *table; - struct route_node *rn; - struct prefix nh_p; - - /* Lookup table. */ - table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, si->vrf_id); - if (! table) - return; - - /* Lookup existing route */ - rn = route_node_get (table, p); - RNODE_FOREACH_RIB (rn, rib) - { - if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED)) - continue; - - if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance) - break; - } - - if (rib) - { - /* if tag value changed , update old value in RIB */ - if (rib->tag != si->tag) - rib->tag = si->tag; - - /* Same distance static route is there. Update it with new - nexthop. */ - route_unlock_node (rn); - - switch (si->type) - { - case STATIC_IPV6_GATEWAY: - nexthop_ipv6_add (rib, &si->ipv6); - nh_p.family = AF_INET6; - nh_p.prefixlen = IPV6_MAX_BITLEN; - nh_p.u.prefix6 = si->ipv6; - zebra_register_rnh_static_nh(&nh_p, rn); - break; - case STATIC_IPV6_IFNAME: - nexthop_ifname_add (rib, si->ifname); - break; - case STATIC_IPV6_GATEWAY_IFNAME: - nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname); - break; - } - rib_queue_add (&zebrad, rn); - } - else - { - /* This is new static route. */ - rib = XCALLOC (MTYPE_RIB, sizeof (struct rib)); - - rib->type = ZEBRA_ROUTE_STATIC; - rib->instance = 0; - rib->distance = si->distance; - rib->metric = 0; - rib->vrf_id = si->vrf_id; - rib->table = zebrad.rtm_table_default; - rib->nexthop_num = 0; - rib->tag = si->tag; - - switch (si->type) - { - case STATIC_IPV6_GATEWAY: - nexthop_ipv6_add (rib, &si->ipv6); - nh_p.family = AF_INET6; - nh_p.prefixlen = IPV6_MAX_BITLEN; - nh_p.u.prefix6 = si->ipv6; - zebra_register_rnh_static_nh(&nh_p, rn); - break; - case STATIC_IPV6_IFNAME: - nexthop_ifname_add (rib, si->ifname); - break; - case STATIC_IPV6_GATEWAY_IFNAME: - nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname); - break; - } - - /* Save the flags of this static routes (reject, blackhole) */ - rib->flags = si->flags; - - /* Link this rib to the tree. */ - rib_addnode (rn, rib); - } -} - -static int -static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si) -{ - if (nexthop->type == NEXTHOP_TYPE_IPV6 - && si->type == STATIC_IPV6_GATEWAY - && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)) - return 1; - if (nexthop->type == NEXTHOP_TYPE_IFNAME - && si->type == STATIC_IPV6_IFNAME - && strcmp (nexthop->ifname, si->ifname) == 0) - return 1; - if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME - && si->type == STATIC_IPV6_GATEWAY_IFNAME - && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6) - && strcmp (nexthop->ifname, si->ifname) == 0) - return 1; - return 0; -} - -static void -static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si) -{ - struct route_table *table; - struct route_node *rn; - struct rib *rib; - struct nexthop *nexthop; - struct prefix nh_p; - - /* Lookup table. */ - table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, si->vrf_id); - if (! table) - return; - - /* Lookup existing route with type and distance. */ - rn = route_node_lookup (table, (struct prefix *) p); - if (! rn) - return; - - RNODE_FOREACH_RIB (rn, rib) - { - if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) - continue; - - if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance && - rib->tag == si->tag) - break; - } - - if (! rib) - { - route_unlock_node (rn); - return; - } - - /* Lookup nexthop. */ - for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) - if (static_ipv6_nexthop_same (nexthop, si)) - break; - - /* Can't find nexthop. */ - if (! nexthop) - { - route_unlock_node (rn); - return; - } - - /* Check nexthop. */ - if (rib->nexthop_num == 1) - { - rib_delnode (rn, rib); - } - else - { - /* Mark this nexthop as inactive and reinstall the route. Then, delete - * the nexthop. There is no need to re-evaluate the route for this - * scenario. - */ - UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); - if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) - { - redistribute_delete (&rn->p, rib); - rib_uninstall_kernel (rn, rib); - /* Are there other active nexthops? */ - if (rib->nexthop_active_num > 1) - { - rib_install_kernel (rn, rib, 0); - redistribute_update (&rn->p, rib, NULL); - } - } - - /* Delete the nexthop and dereg from NHT */ - nh_p.family = AF_INET6; - nh_p.prefixlen = IPV6_MAX_BITLEN; - nh_p.u.prefix6 = nexthop->gate.ipv6; - nexthop_delete (rib, nexthop); - zebra_deregister_rnh_static_nh(&nh_p, rn); - nexthop_free (nexthop, rn); - } - /* Unlock node. */ - route_unlock_node (rn); -} - /* Add static route into static route configuration. */ int static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, @@ -3643,9 +3494,10 @@ static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, u_char distance, vrf_id_t vrf_id) { struct route_node *rn; - struct static_ipv6 *si; - struct static_ipv6 *pp; - struct static_ipv6 *cp; + struct static_route *si; + struct static_route *pp; + struct static_route *cp; + struct static_route *update = NULL; struct zebra_vrf *zvrf = vrf_info_get (vrf_id); struct route_table *stable = zvrf->stable[AFI_IP6][SAFI_UNICAST]; @@ -3666,19 +3518,26 @@ static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, /* Do nothing if there is a same static route. */ for (si = rn->info; si; si = si->next) { - if (distance == si->distance - && type == si->type - && tag == si->tag - && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6)) + if (type == si->type + && (! gate || IPV6_ADDR_SAME (gate, &si->addr.ipv6)) && (! ifname || strcmp (ifname, si->ifname) == 0)) { - route_unlock_node (rn); - return 0; + if ((distance == si->distance) && (tag == si->tag)) + { + route_unlock_node (rn); + return 0; + } + else + update = si; } } + /* Distance or tag changed. */ + if (update) + static_delete_ipv6 (p, type, gate, ifname, update->tag, update->distance, vrf_id); + /* Make new static route structure. */ - si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6)); + si = XCALLOC (MTYPE_STATIC_ROUTE, sizeof (struct static_route)); si->type = type; si->distance = distance; @@ -3689,13 +3548,13 @@ static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, switch (type) { case STATIC_IPV6_GATEWAY: - si->ipv6 = *gate; + si->addr.ipv6 = *gate; break; case STATIC_IPV6_IFNAME: si->ifname = XSTRDUP (0, ifname); break; case STATIC_IPV6_GATEWAY_IFNAME: - si->ipv6 = *gate; + si->addr.ipv6 = *gate; si->ifname = XSTRDUP (0, ifname); break; } @@ -3721,7 +3580,7 @@ static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, si->next = cp; /* Install into rib. */ - static_install_ipv6 (p, si); + static_install_route (AFI_IP6, SAFI_UNICAST, p, si); return 1; } @@ -3733,7 +3592,7 @@ static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, vrf_id_t vrf_id) { struct route_node *rn; - struct static_ipv6 *si; + struct static_route *si; struct route_table *stable; /* Lookup table. */ @@ -3750,7 +3609,7 @@ static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, for (si = rn->info; si; si = si->next) if (distance == si->distance && type == si->type - && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6)) + && (! gate || IPV6_ADDR_SAME (gate, &si->addr.ipv6)) && (! ifname || strcmp (ifname, si->ifname) == 0) && (! tag || (tag == si->tag))) break; @@ -3763,7 +3622,7 @@ static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, } /* Install into rib. */ - static_uninstall_ipv6 (p, si); + static_uninstall_route (AFI_IP6, SAFI_UNICAST, p, si); /* Unlink static route from linked list. */ if (si->prev) @@ -3776,11 +3635,10 @@ static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, /* Free static route configuration. */ if (ifname) XFREE (0, si->ifname); - XFREE (MTYPE_STATIC_IPV6, si); + XFREE (MTYPE_STATIC_ROUTE, si); return 1; } -#endif /* HAVE_IPV6 */ /* RIB update function. */ void diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 4341152e09..57c0e8265e 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -3006,7 +3006,7 @@ static int static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd) { struct route_node *rn; - struct static_ipv4 *si; + struct static_route *si; struct route_table *stable; struct zebra_vrf *zvrf; vrf_iter_t iter; @@ -3029,10 +3029,10 @@ static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd) switch (si->type) { case STATIC_IPV4_GATEWAY: - vty_out (vty, " %s", inet_ntoa (si->gate.ipv4)); + vty_out (vty, " %s", inet_ntoa (si->addr.ipv4)); break; case STATIC_IPV4_IFNAME: - vty_out (vty, " %s", si->gate.ifname); + vty_out (vty, " %s", si->ifname); break; case STATIC_IPV4_BLACKHOLE: vty_out (vty, " Null0"); @@ -5128,7 +5128,7 @@ static int static_config_ipv6 (struct vty *vty) { struct route_node *rn; - struct static_ipv6 *si; + struct static_route *si; int write; char buf[BUFSIZ]; struct route_table *stable; @@ -5148,21 +5148,19 @@ static_config_ipv6 (struct vty *vty) { vty_out (vty, "ipv6 route %s", prefix2str (&rn->p, buf, sizeof buf)); - switch (si->type) - { - case STATIC_IPV6_GATEWAY: - vty_out (vty, " %s", - inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ)); - break; - case STATIC_IPV6_IFNAME: - vty_out (vty, " %s", si->ifname); - break; - case STATIC_IPV6_GATEWAY_IFNAME: - vty_out (vty, " %s %s", - inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ), - si->ifname); - break; - } + switch (si->type) + { + case STATIC_IPV6_GATEWAY: + vty_out (vty, " %s", inet_ntop (AF_INET6, &si->addr.ipv6, buf, BUFSIZ)); + break; + case STATIC_IPV6_IFNAME: + vty_out (vty, " %s", si->ifname); + break; + case STATIC_IPV6_GATEWAY_IFNAME: + vty_out (vty, " %s %s", + inet_ntop (AF_INET6, &si->addr.ipv6, buf, BUFSIZ), si->ifname); + break; + } if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT)) vty_out (vty, " %s", "reject"); |
