Index: sys/netinet/toecore.c =================================================================== --- sys/netinet/toecore.c (revision 293281) +++ sys/netinet/toecore.c (working copy) @@ -74,7 +74,7 @@ static eventhandler_tag route_redirect_eh; static int toedev_connect(struct toedev *tod __unused, struct socket *so __unused, - struct rtentry *rt __unused, struct sockaddr *nam __unused) + struct toe_nhop *nh __unused, struct sockaddr *nam __unused) { return (ENOTSUP); Index: sys/netinet/toecore.h =================================================================== --- sys/netinet/toecore.h (revision 293281) +++ sys/netinet/toecore.h (working copy) @@ -37,6 +37,11 @@ struct tcpopt; struct tcphdr; struct in_conninfo; +struct toe_nhop { + struct ifnet *tnh_ifp; + struct sockaddr *tnh_dst; +}; + struct toedev { TAILQ_ENTRY(toedev) link; /* glue for toedev_list */ void *tod_softc; /* TOE driver private data */ @@ -45,7 +50,7 @@ struct toedev { * Active open. If a failure occurs, it is reported back by the driver * via toe_connect_failed. */ - int (*tod_connect)(struct toedev *, struct socket *, struct rtentry *, + int (*tod_connect)(struct toedev *, struct socket *, struct toe_nhop *, struct sockaddr *); /* Passive open. */ Index: sys/netinet/tcp_offload.c =================================================================== --- sys/netinet/tcp_offload.c (revision 293281) +++ sys/netinet/tcp_offload.c (working copy) @@ -28,6 +28,7 @@ __FBSDID("$FreeBSD$"); #include "opt_inet.h" +#include "opt_inet6.h" #include #include @@ -40,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -47,6 +49,8 @@ __FBSDID("$FreeBSD$"); #define TCPOUTFLAGS #include #include +#include +#include int registered_toedevs; @@ -58,7 +62,9 @@ tcp_offload_connect(struct socket *so, struct sock { struct ifnet *ifp; struct toedev *tod; - struct rtentry *rt; + struct sockaddr_in6 xdst; + struct toe_nhop tnh; + int error = EOPNOTSUPP; INP_WLOCK_ASSERT(sotoinpcb(so)); @@ -68,24 +74,83 @@ tcp_offload_connect(struct socket *so, struct sock if (registered_toedevs == 0) return (error); - rt = rtalloc1(nam, 0, 0); - if (rt) - RT_UNLOCK(rt); - else - return (EHOSTUNREACH); + if (nam->sa_family == AF_INET) { +#ifdef INET + struct nhop4_extended nh4; + struct sockaddr_in *sin; - ifp = rt->rt_ifp; + sin = (struct sockaddr_in *)nam; - if (nam->sa_family == AF_INET && !(ifp->if_capenable & IFCAP_TOE4)) - goto done; - if (nam->sa_family == AF_INET6 && !(ifp->if_capenable & IFCAP_TOE6)) - goto done; + error = fib4_lookup_nh_ext(RT_DEFAULT_FIB, sin->sin_addr, + NHR_REF, 0, &nh4); + if (error != 0) + return (error); - tod = TOEDEV(ifp); - if (tod != NULL) - error = tod->tod_connect(tod, so, rt, nam); -done: - RTFREE(rt); + ifp = nh4.nh_ifp; + if (!(ifp->if_capenable & IFCAP_TOE4) || + (tod = TOEDEV(ifp)) == NULL) { + fib4_free_nh_ext(RT_DEFAULT_FIB, &nh4); + return (EOPNOTSUPP); + } + + tnh.tnh_ifp = nh4.nh_ifp; + tnh.tnh_dst = nam; + + if (nh4.nh_flags & NHF_GATEWAY) { + /* Make sockaddr for GW */ + sin = (struct sockaddr_in *)&xdst; + sin->sin_family = AF_INET; + sin->sin_len = sizeof(*sin); + sin->sin_addr = nh4.nh_addr; + tnh.tnh_dst = (struct sockaddr *)sin; + } + + error = tod->tod_connect(tod, so, &tnh, nam); + fib4_free_nh_ext(RT_DEFAULT_FIB, &nh4); +#endif + return (error); + } else if (nam->sa_family == AF_INET6) { +#ifdef INET6 + struct nhop6_extended nh6; + struct sockaddr_in6 *sin6; + struct in6_addr kdst; + uint32_t scopeid; + + sin6 = (struct sockaddr_in6 *)nam; + + in6_splitscope(&sin6->sin6_addr, &kdst, &scopeid); + + error = fib6_lookup_nh_ext(RT_DEFAULT_FIB, &kdst, scopeid, + NHR_REF, 0, &nh6); + if (error != 0) + return (error); + + ifp = nh6.nh_ifp; + if (!(ifp->if_capenable & IFCAP_TOE6) || + (tod = TOEDEV(ifp)) == NULL) { + fib6_free_nh_ext(RT_DEFAULT_FIB, &nh6); + return (EOPNOTSUPP); + } + + tnh.tnh_ifp = nh6.nh_ifp; + tnh.tnh_dst = nam; + + if (nh6.nh_flags & NHF_GATEWAY) { + /* Make sockaddr for GW */ + sin6 = (struct sockaddr_in6 *)&xdst; + bzero(&sin6, sizeof(*sin6)); + sin6->sin6_family = AF_INET6; + sin6->sin6_len = sizeof(*sin6); + sin6->sin6_addr = nh6.nh_addr; + tnh.tnh_dst = (struct sockaddr *)sin6; + } + + error = tod->tod_connect(tod, so, &tnh, nam); + fib6_free_nh_ext(RT_DEFAULT_FIB, &nh6); + return (error); +#endif + } + return (error); } Index: sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c =================================================================== --- sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c (revision 293281) +++ sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c (working copy) @@ -944,11 +944,10 @@ do_act_open_rpl(struct sge_qset *qs, struct rsp_de * tcbinfo not locked (this has changed - used to be WLOCKed) * inp WLOCKed * tp->t_state = TCPS_SYN_SENT - * rtalloc1, RT_UNLOCK on rt. */ int t3_connect(struct toedev *tod, struct socket *so, - struct rtentry *rt, struct sockaddr *nam) + struct toe_nhop *nh, struct sockaddr *nam) { struct mbuf *m = NULL; struct l2t_entry *e = NULL; @@ -959,8 +958,7 @@ t3_connect(struct toedev *tod, struct socket *so, struct tcpcb *tp = intotcpcb(inp); struct toepcb *toep; int atid = -1, mtu_idx, rscale, cpu_idx, qset; - struct sockaddr *gw; - struct ifnet *ifp = rt->rt_ifp; + struct ifnet *ifp = nh->tnh_ifp; struct port_info *pi = ifp->if_softc; /* XXX wrong for VLAN etc. */ INP_WLOCK_ASSERT(inp); @@ -979,8 +977,7 @@ t3_connect(struct toedev *tod, struct socket *so, if (m == NULL) goto failed; - gw = rt->rt_flags & RTF_GATEWAY ? rt->rt_gateway : nam; - e = t3_l2t_get(pi, ifp, gw); + e = t3_l2t_get(pi, ifp, nh->tnh_dst); if (e == NULL) goto failed; Index: sys/dev/cxgb/ulp/tom/cxgb_tom.h =================================================================== --- sys/dev/cxgb/ulp/tom/cxgb_tom.h (revision 293281) +++ sys/dev/cxgb/ulp/tom/cxgb_tom.h (working copy) @@ -245,7 +245,7 @@ void toepcb_free(struct toepcb *); /* cxgb_cpl_io.c */ void t3_init_cpl_io(struct adapter *); int t3_push_frames(struct socket *, int); -int t3_connect(struct toedev *, struct socket *, struct rtentry *, +int t3_connect(struct toedev *, struct socket *, struct toe_nhop *, struct sockaddr *); int t3_tod_output(struct toedev *, struct tcpcb *); int t3_send_rst(struct toedev *, struct tcpcb *); Index: sys/dev/cxgbe/tom/t4_connect.c =================================================================== --- sys/dev/cxgbe/tom/t4_connect.c (revision 293281) +++ sys/dev/cxgbe/tom/t4_connect.c (working copy) @@ -45,7 +45,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -310,10 +309,9 @@ act_open_cpl_size(struct adapter *sc, int isipv6) * tcbinfo not locked (This has changed - used to be WLOCKed) * inp WLOCKed * tp->t_state = TCPS_SYN_SENT - * rtalloc1, RT_UNLOCK on rt. */ int -t4_connect(struct toedev *tod, struct socket *so, struct rtentry *rt, +t4_connect(struct toedev *tod, struct socket *so, struct toe_nhop *nh, struct sockaddr *nam) { struct adapter *sc = tod->tod_softc; @@ -320,7 +318,7 @@ int struct tom_data *td = tod_td(tod); struct toepcb *toep = NULL; struct wrqe *wr = NULL; - struct ifnet *rt_ifp = rt->rt_ifp; + struct ifnet *ifp = nh->tnh_ifp; struct vi_info *vi; int mtu_idx, rscale, qid_atid, rc, isipv6; struct inpcb *inp = sotoinpcb(so); @@ -331,13 +329,13 @@ int KASSERT(nam->sa_family == AF_INET || nam->sa_family == AF_INET6, ("%s: dest addr %p has family %u", __func__, nam, nam->sa_family)); - if (rt_ifp->if_type == IFT_ETHER) - vi = rt_ifp->if_softc; - else if (rt_ifp->if_type == IFT_L2VLAN) { - struct ifnet *ifp = VLAN_COOKIE(rt_ifp); + if (ifp->if_type == IFT_ETHER) + vi = ifp->if_softc; + else if (ifp->if_type == IFT_L2VLAN) { + struct ifnet *v_ifp = VLAN_COOKIE(ifp); - vi = ifp->if_softc; - } else if (rt_ifp->if_type == IFT_IEEE8023ADLAG) + vi = v_ifp->if_softc; + } else if (ifp->if_type == IFT_IEEE8023ADLAG) DONT_OFFLOAD_ACTIVE_OPEN(ENOSYS); /* XXX: implement lagg+TOE */ else DONT_OFFLOAD_ACTIVE_OPEN(ENOTSUP); @@ -350,8 +348,7 @@ int if (toep->tid < 0) DONT_OFFLOAD_ACTIVE_OPEN(ENOMEM); - toep->l2te = t4_l2t_get(vi->pi, rt_ifp, - rt->rt_flags & RTF_GATEWAY ? rt->rt_gateway : nam); + toep->l2te = t4_l2t_get(vi->pi, ifp, nh->tnh_dst); if (toep->l2te == NULL) DONT_OFFLOAD_ACTIVE_OPEN(ENOMEM); Index: sys/dev/cxgbe/tom/t4_tom.h =================================================================== --- sys/dev/cxgbe/tom/t4_tom.h (revision 293281) +++ sys/dev/cxgbe/tom/t4_tom.h (working copy) @@ -264,7 +264,7 @@ void release_lip(struct tom_data *, struct clip_en /* t4_connect.c */ void t4_init_connect_cpl_handlers(struct adapter *); -int t4_connect(struct toedev *, struct socket *, struct rtentry *, +int t4_connect(struct toedev *, struct socket *, struct toe_nhop *, struct sockaddr *); void act_open_failure_cleanup(struct adapter *, u_int, u_int);