diff --git a/sys/net/route/nhop.h b/sys/net/route/nhop.h --- a/sys/net/route/nhop.h +++ b/sys/net/route/nhop.h @@ -179,6 +179,9 @@ int nhop_get_rtflags(const struct nhop_object *nh); struct vnet *nhop_get_vnet(const struct nhop_object *nh); struct nhop_object *nhop_select_func(struct nhop_object *nh, uint32_t flowid); +int nhop_get_upper_family(const struct nhop_object *nh); +int nhop_get_neigh_family(const struct nhop_object *nh); +uint32_t nhop_get_fibnum(const struct nhop_object *nh); #endif /* _KERNEL */ diff --git a/sys/net/route/nhop_ctl.c b/sys/net/route/nhop_ctl.c --- a/sys/net/route/nhop_ctl.c +++ b/sys/net/route/nhop_ctl.c @@ -28,6 +28,7 @@ #include __FBSDID("$FreeBSD$"); #include "opt_inet.h" +#include "opt_inet6.h" #include "opt_route.h" #include @@ -58,7 +59,7 @@ * Nexthops in the original sense are the objects containing all the necessary * information to forward the packet to the selected destination. * In particular, nexthop is defined by a combination of - * ifp, ifa, aifp, mtu, gw addr(if set), nh_type, nh_family, mask of rt_flags and + * ifp, ifa, aifp, mtu, gw addr(if set), nh_type, nh_upper_family, mask of rt_flags and * NHF_DEFAULT * * Additionally, each nexthop gets assigned its unique index (nexthop index). @@ -278,13 +279,17 @@ rt_flags = info->rti_flags & NHOP_RT_FLAG_MASK; nh->nh_priv->rt_flags = rt_flags; - nh_priv->nh_family = info->rti_info[RTAX_DST]->sa_family; + nh_priv->nh_upper_family = info->rti_info[RTAX_DST]->sa_family; nh_priv->nh_type = 0; // hook responsibility to set nhop type - nh->nh_flags = convert_rt_to_nh_flags(rt_flags); + set_nhop_mtu_from_info(nh, info); if ((error = set_nhop_gw_from_info(nh, info)) != 0) return (error); + if (nh->gw_sa.sa_family == AF_LINK) + nh_priv->nh_neigh_family = nh_priv->nh_upper_family; + else + nh_priv->nh_neigh_family = nh->gw_sa.sa_family; nh->nh_ifp = (info->rti_ifp != NULL) ? info->rti_ifp : info->rti_ifa->ifa_ifp; nh->nh_ifa = info->rti_ifa; @@ -401,6 +406,7 @@ static int alter_nhop_from_info(struct nhop_object *nh, struct rt_addrinfo *info) { + struct nhop_priv *nh_priv = nh->nh_priv; struct sockaddr *info_gw; int error; @@ -410,8 +416,8 @@ /* XXX: allow only one of BLACKHOLE,REJECT,GATEWAY */ /* Allow some flags (FLAG1,STATIC,BLACKHOLE,REJECT) to be toggled on change. */ - nh->nh_priv->rt_flags &= ~RTF_FMASK; - nh->nh_priv->rt_flags |= info->rti_flags & RTF_FMASK; + nh_priv->rt_flags &= ~RTF_FMASK; + nh_priv->rt_flags |= info->rti_flags & RTF_FMASK; /* Consider gateway change */ info_gw = info->rti_info[RTAX_GATEWAY]; @@ -419,12 +425,16 @@ error = set_nhop_gw_from_info(nh, info); if (error != 0) return (error); + if (nh->gw_sa.sa_family == AF_LINK) + nh_priv->nh_neigh_family = nh_priv->nh_upper_family; + else + nh_priv->nh_neigh_family = nh->gw_sa.sa_family; /* Update RTF_GATEWAY flag status */ - nh->nh_priv->rt_flags &= ~RTF_GATEWAY; - nh->nh_priv->rt_flags |= (RTF_GATEWAY & info->rti_flags); + nh_priv->rt_flags &= ~RTF_GATEWAY; + nh_priv->rt_flags |= (RTF_GATEWAY & info->rti_flags); } /* Update datapath flags */ - nh->nh_flags = convert_rt_to_nh_flags(nh->nh_priv->rt_flags); + nh->nh_flags = convert_rt_to_nh_flags(nh_priv->rt_flags); if (info->rti_ifa != NULL) nh->nh_ifa = info->rti_ifa; @@ -458,7 +468,8 @@ nh = nh_priv->nh; /* Start with copying data from original nexthop */ - nh_priv->nh_family = nh_orig->nh_priv->nh_family; + nh_priv->nh_upper_family = nh_orig->nh_priv->nh_upper_family; + nh_priv->nh_neigh_family = nh_orig->nh_priv->nh_neigh_family; nh_priv->rt_flags = nh_orig->nh_priv->rt_flags; nh_priv->nh_type = nh_orig->nh_priv->nh_type; @@ -561,6 +572,8 @@ /* Please see nhop_free() comments on the initial value */ refcount_init(&nh_priv->nh_linked, 2); + nh_priv->nh_fibnum = ctl->ctl_rh->rib_fibnum; + print_nhop("FINALIZE", nh); if (link_nhop(ctl, nh_priv) == 0) { @@ -608,7 +621,7 @@ print_nhop_sa(addr_buf, sizeof(addr_buf), &nh->gw_sa); DPRINTF("%s nhop priv %p: AF %d ifp %p %s addr %s src %p %s aifp %p %s mtu %d nh_flags %X", - prefix, nh->nh_priv, nh->nh_priv->nh_family, nh->nh_ifp, + prefix, nh->nh_priv, nh->nh_priv->nh_upper_family, nh->nh_ifp, if_name(nh->nh_ifp), addr_buf, nh->nh_ifa, src_buf, nh->nh_aifp, if_name(nh->nh_aifp), nh->nh_mtu, nh->nh_flags); } @@ -782,6 +795,31 @@ return (nhop_select(nh, flowid)); } +/* + * Returns address family of the traffic uses the nexthop. + */ +int +nhop_get_upper_family(const struct nhop_object *nh) +{ + return (nh->nh_priv->nh_upper_family); +} + +/* + * Returns address family of the LLE or gateway that is used + * to forward the traffic to. + */ +int +nhop_get_neigh_family(const struct nhop_object *nh) +{ + return (nh->nh_priv->nh_neigh_family); +} + +uint32_t +nhop_get_fibnum(const struct nhop_object *nh) +{ + return (nh->nh_priv->nh_fibnum); +} + void nhops_update_ifmtu(struct rib_head *rh, struct ifnet *ifp, uint32_t mtu) { @@ -845,7 +883,7 @@ pnhe->nh_fib = rh->rib_fibnum; pnhe->ifindex = nh->nh_ifp->if_index; pnhe->aifindex = nh->nh_aifp->if_index; - pnhe->nh_family = nh->nh_priv->nh_family; + pnhe->nh_family = nh->nh_priv->nh_upper_family; pnhe->nh_type = nh->nh_priv->nh_type; pnhe->nh_mtu = nh->nh_mtu; pnhe->nh_flags = nh->nh_flags; diff --git a/sys/net/route/nhop_var.h b/sys/net/route/nhop_var.h --- a/sys/net/route/nhop_var.h +++ b/sys/net/route/nhop_var.h @@ -74,12 +74,13 @@ struct nhop_object; struct nhop_priv { /* nhop lookup comparison start */ - uint8_t nh_family; /* address family of the lookup */ - uint8_t spare; + uint8_t nh_upper_family;/* address family of the lookup */ + uint8_t nh_neigh_family;/* neighbor address family */ uint16_t nh_type; /* nexthop type */ uint32_t rt_flags; /* routing flags for the control plane */ /* nhop lookup comparison end */ uint32_t nh_idx; /* nexthop index */ + uint32_t nh_fibnum; /* nexthop fib */ void *cb_func; /* function handling additional rewrite caps */ u_int nh_refcnt; /* number of references, refcount(9) */ u_int nh_linked; /* refcount(9), == 2 if linked to the list */