From owner-svn-src-projects@FreeBSD.ORG Sat Oct 25 18:25:04 2014 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id A0010E1E; Sat, 25 Oct 2014 18:25:04 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 8942281B; Sat, 25 Oct 2014 18:25:04 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id s9PIP4pQ048487; Sat, 25 Oct 2014 18:25:04 GMT (envelope-from melifaro@FreeBSD.org) Received: (from melifaro@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id s9PIP055048452; Sat, 25 Oct 2014 18:25:00 GMT (envelope-from melifaro@FreeBSD.org) Message-Id: <201410251825.s9PIP055048452@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: melifaro set sender to melifaro@FreeBSD.org using -f From: "Alexander V. Chernikov" Date: Sat, 25 Oct 2014 18:25:00 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r273642 - in projects/routing/sys: contrib/ipfilter/netinet dev/cxgb/ulp/iw_cxgb dev/cxgb/ulp/tom dev/cxgbe/iw_cxgbe dev/cxgbe/tom net netinet netpfil/pf X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 25 Oct 2014 18:25:04 -0000 Author: melifaro Date: Sat Oct 25 18:25:00 2014 New Revision: 273642 URL: https://svnweb.freebsd.org/changeset/base/273642 Log: * Convert TOE framework to use new routing api. * Add fib6_lookup_nh_ext(). * Rename union structures: nhop64_basic -> nhopu_basic, nhop64_extended -> nhopu_extended Modified: projects/routing/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c projects/routing/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.c projects/routing/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c projects/routing/sys/dev/cxgb/ulp/tom/cxgb_listen.c projects/routing/sys/dev/cxgb/ulp/tom/cxgb_tom.h projects/routing/sys/dev/cxgbe/iw_cxgbe/cm.c projects/routing/sys/dev/cxgbe/tom/t4_connect.c projects/routing/sys/dev/cxgbe/tom/t4_listen.c projects/routing/sys/dev/cxgbe/tom/t4_tom.h projects/routing/sys/net/rt_nhops.c projects/routing/sys/net/rt_nhops.h projects/routing/sys/netinet/tcp_offload.c projects/routing/sys/netinet/toecore.c projects/routing/sys/netinet/toecore.h projects/routing/sys/netpfil/pf/pf.c Modified: projects/routing/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c ============================================================================== --- projects/routing/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c Sat Oct 25 17:42:44 2014 (r273641) +++ projects/routing/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c Sat Oct 25 18:25:00 2014 (r273642) @@ -711,7 +711,7 @@ ipf_fastroute(m0, mpp, fin, fdp) u_int fibnum; struct ifnet *ifp, *sifp; struct in_addr dst; - struct nhop_data nhd, *pnhd; + struct nhop_prepend nhd, *pnhd; u_short ip_off; frdest_t node; frentry_t *fr; @@ -934,7 +934,7 @@ done: ipfmain.ipf_frouteok[1]++; if (pnhd != NULL) - fib4_free_nh(fibnum, pnhd); + fib4_free_nh_prepend(fibnum, pnhd); return 0; bad: if (error == EMSGSIZE) { Modified: projects/routing/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.c ============================================================================== --- projects/routing/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.c Sat Oct 25 17:42:44 2014 (r273641) +++ projects/routing/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.c Sat Oct 25 18:25:00 2014 (r273642) @@ -68,6 +68,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include + #include #include #include @@ -264,22 +266,6 @@ void __free_ep(struct iwch_ep_common *ep free(epc, M_DEVBUF); } -static struct rtentry * -find_route(__be32 local_ip, __be32 peer_ip, __be16 local_port, - __be16 peer_port, u8 tos) -{ - struct route iproute; - struct sockaddr_in *dst = (struct sockaddr_in *)&iproute.ro_dst; - - bzero(&iproute, sizeof iproute); - dst->sin_family = AF_INET; - dst->sin_len = sizeof *dst; - dst->sin_addr.s_addr = peer_ip; - - rtalloc(&iproute); - return iproute.ro_rt; -} - static void close_socket(struct iwch_ep_common *epc, int close) { @@ -1293,7 +1279,7 @@ iwch_connect(struct iw_cm_id *cm_id, str int err = 0; struct iwch_dev *h = to_iwch_dev(cm_id->device); struct iwch_ep *ep; - struct rtentry *rt; + struct nhop4_extended nh_ext; struct toedev *tdev; if (is_loopback_dst(cm_id)) { @@ -1329,11 +1315,8 @@ iwch_connect(struct iw_cm_id *cm_id, str goto fail2; /* find a route */ - rt = find_route(cm_id->local_addr.sin_addr.s_addr, - cm_id->remote_addr.sin_addr.s_addr, - cm_id->local_addr.sin_port, - cm_id->remote_addr.sin_port, IPTOS_LOWDELAY); - if (!rt) { + if (fib4_lookup_nh_ext(RT_DEFAULT_FIB, cm_id->remote_addr.sin_addr, 0, + NHOP_LOOKUP_REF, &nh_ext) != 0) { printf("%s - cannot find route.\n", __FUNCTION__); err = EHOSTUNREACH; goto fail2; @@ -1341,16 +1324,16 @@ iwch_connect(struct iw_cm_id *cm_id, str if (!(rt->rt_ifp->if_flags & IFCAP_TOE)) { printf("%s - interface not TOE capable.\n", __FUNCTION__); - RTFREE(rt); + fib4_free_nh_ext(RT_DEFAULT_FIB, &nh_ext); goto fail2; } tdev = TOEDEV(rt->rt_ifp); if (tdev == NULL) { printf("%s - No toedev for interface.\n", __FUNCTION__); - RTFREE(rt); + fib4_free_nh_ext(RT_DEFAULT_FIB, &nh_ext); goto fail2; } - RTFREE(rt); + fib4_free_nh_ext(RT_DEFAULT_FIB, &nh_ext); state_set(&ep->com, CONNECTING); ep->com.local_addr = cm_id->local_addr; Modified: projects/routing/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c ============================================================================== --- projects/routing/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c Sat Oct 25 17:42:44 2014 (r273641) +++ projects/routing/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c Sat Oct 25 18:25:00 2014 (r273642) @@ -69,6 +69,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include "cxgb_include.h" #include "ulp/tom/cxgb_l2t.h" @@ -944,11 +945,11 @@ do_act_open_rpl(struct sge_qset *qs, str * tcbinfo not locked (this has changed - used to be WLOCKed) * inp WLOCKed * tp->t_state = TCPS_SYN_SENT - * rtalloc1, RT_UNLOCK on rt. + * fib4_lookup_nh_ext */ int t3_connect(struct toedev *tod, struct socket *so, - struct rtentry *rt, struct sockaddr *nam) + struct nhopu_extended *nhu_ext, struct sockaddr *nam) { struct mbuf *m = NULL; struct l2t_entry *e = NULL; @@ -959,8 +960,7 @@ t3_connect(struct toedev *tod, struct 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 = nhu_ext->u.nh4.nh_ifp; struct port_info *pi = ifp->if_softc; /* XXX wrong for VLAN etc. */ INP_WLOCK_ASSERT(inp); @@ -979,8 +979,22 @@ t3_connect(struct toedev *tod, struct so if (m == NULL) goto failed; - gw = rt->rt_flags & RTF_GATEWAY ? rt->rt_gateway : nam; - e = t3_l2t_get(pi, ifp, gw); + e = NULL; + if (nam->sa_family == AF_INET) { + struct sockaddr_in gw4; + memset(&gw4, 0, sizeof(gw4)); + gw4.sin_family = AF_INET; + gw4.sin_len = sizeof(gw4); + gw4.sin_addr = nhu_ext->u.nh4.nh_addr; + e = t3_l2t_get(pi, ifp, (struct sockaddr *)&gw4); + } else if (nam->sa_family == AF_INET6) { + struct sockaddr_in6 gw6; + memset(&gw6, 0, sizeof(gw6)); + gw6.sin6_family = AF_INET6; + gw6.sin6_len = sizeof(gw6); + gw6.sin6_addr = nhu_ext->u.nh6.nh_addr; + e = t3_l2t_get(pi, ifp, (struct sockaddr *)&gw6); + } if (e == NULL) goto failed; Modified: projects/routing/sys/dev/cxgb/ulp/tom/cxgb_listen.c ============================================================================== --- projects/routing/sys/dev/cxgb/ulp/tom/cxgb_listen.c Sat Oct 25 17:42:44 2014 (r273641) +++ projects/routing/sys/dev/cxgb/ulp/tom/cxgb_listen.c Sat Oct 25 18:25:00 2014 (r273642) @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$"); #define TCPSTATES #include #include +#include #include "cxgb_include.h" #include "ulp/tom/cxgb_tom.h" @@ -493,8 +494,7 @@ do_pass_accept_req(struct sge_qset *qs, unsigned int tid = GET_TID(req); struct listen_ctx *lctx = lookup_stid(&td->tid_maps, stid); struct l2t_entry *e = NULL; - struct sockaddr_in nam; - struct rtentry *rt; + struct nhop4_extended nh_ext; struct inpcb *inp; struct socket *so; struct port_info *pi; @@ -534,22 +534,17 @@ do_pass_accept_req(struct sge_qset *qs, * Don't offload if the outgoing interface for the route back to the * peer is not the same as the interface that received the SYN. */ - bzero(&nam, sizeof(nam)); - nam.sin_len = sizeof(nam); - nam.sin_family = AF_INET; - nam.sin_addr = inc.inc_faddr; - rt = rtalloc1((struct sockaddr *)&nam, 0, 0); - if (rt == NULL) + /* XXX: Multipath */ + if (fib4_lookup_nh_ext(RT_DEFAULT_FIB, inc.inc_faddr, 0, 0, + &nh_ext) != 0) REJECT_PASS_ACCEPT(); else { - struct sockaddr *nexthop; - - RT_UNLOCK(rt); - nexthop = rt->rt_flags & RTF_GATEWAY ? rt->rt_gateway : - (struct sockaddr *)&nam; - if (rt->rt_ifp == ifp) - e = t3_l2t_get(pi, rt->rt_ifp, nexthop); - RTFREE(rt); + struct sockaddr_in gw4; + memset(&gw4, 0, sizeof(gw4)); + gw4.sin_family = AF_INET; + gw4.sin_len = sizeof(gw4); + gw4.sin_addr = nh_ext.nh_addr; + e = t3_l2t_get(pi, ifp, (struct sockaddr *)&gw4); if (e == NULL) REJECT_PASS_ACCEPT(); /* no l2te, or ifp mismatch */ } Modified: projects/routing/sys/dev/cxgb/ulp/tom/cxgb_tom.h ============================================================================== --- projects/routing/sys/dev/cxgb/ulp/tom/cxgb_tom.h Sat Oct 25 17:42:44 2014 (r273641) +++ projects/routing/sys/dev/cxgb/ulp/tom/cxgb_tom.h Sat Oct 25 18:25:00 2014 (r273642) @@ -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 nhopu_extended *, struct sockaddr *); int t3_tod_output(struct toedev *, struct tcpcb *); int t3_send_rst(struct toedev *, struct tcpcb *); Modified: projects/routing/sys/dev/cxgbe/iw_cxgbe/cm.c ============================================================================== --- projects/routing/sys/dev/cxgbe/iw_cxgbe/cm.c Sat Oct 25 17:42:44 2014 (r273641) +++ projects/routing/sys/dev/cxgbe/iw_cxgbe/cm.c Sat Oct 25 18:25:00 2014 (r273642) @@ -52,6 +52,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include + #include struct sge_iq; @@ -86,8 +88,6 @@ static void __state_set(struct c4iw_ep_c static void state_set(struct c4iw_ep_common *epc, enum c4iw_ep_state tostate); static void *alloc_ep(int size, gfp_t flags); void __free_ep(struct c4iw_ep_common *epc); -static struct rtentry * find_route(__be32 local_ip, __be32 peer_ip, __be16 local_port, - __be16 peer_port, u8 tos); static int close_socket(struct c4iw_ep_common *epc, int close); static int shutdown_socket(struct c4iw_ep_common *epc); static void abort_socket(struct c4iw_ep *ep); @@ -201,25 +201,6 @@ done: } -static struct rtentry * -find_route(__be32 local_ip, __be32 peer_ip, __be16 local_port, - __be16 peer_port, u8 tos) -{ - struct route iproute; - struct sockaddr_in *dst = (struct sockaddr_in *)&iproute.ro_dst; - - CTR5(KTR_IW_CXGBE, "%s:frtB %x, %x, %d, %d", __func__, local_ip, - peer_ip, ntohs(local_port), ntohs(peer_port)); - bzero(&iproute, sizeof iproute); - dst->sin_family = AF_INET; - dst->sin_len = sizeof *dst; - dst->sin_addr.s_addr = peer_ip; - - rtalloc(&iproute); - CTR2(KTR_IW_CXGBE, "%s:frtE %p", __func__, (uint64_t)iproute.ro_rt); - return iproute.ro_rt; -} - static int close_socket(struct c4iw_ep_common *epc, int close) { @@ -2017,7 +1998,7 @@ int c4iw_connect(struct iw_cm_id *cm_id, int err = 0; struct c4iw_dev *dev = to_c4iw_dev(cm_id->device); struct c4iw_ep *ep = NULL; - struct rtentry *rt; + struct nhop4_extended nh_ext; struct toedev *tdev; CTR2(KTR_IW_CXGBE, "%s:ccB %p", __func__, cm_id); @@ -2073,13 +2054,8 @@ int c4iw_connect(struct iw_cm_id *cm_id, init_sock(&ep->com); /* find a route */ - rt = find_route( - cm_id->local_addr.sin_addr.s_addr, - cm_id->remote_addr.sin_addr.s_addr, - cm_id->local_addr.sin_port, - cm_id->remote_addr.sin_port, 0); - - if (!rt) { + if (fib4_lookup_nh_ext(RT_DEFAULT_FIB, cm_id->remote_addr.sin_addr, 0, + NHOP_LOOKUP_REF, &nh_ext) != 0) { CTR2(KTR_IW_CXGBE, "%s:cc7 %p", __func__, ep); printk(KERN_ERR MOD "%s - cannot find route.\n", __func__); @@ -2102,7 +2078,7 @@ int c4iw_connect(struct iw_cm_id *cm_id, printf("%s - No toedev for interface.\n", __func__); goto fail3; } - RTFREE(rt); + fib4_free_nh_ext(RT_DEFAULT_FIB, &nh_ext); state_set(&ep->com, CONNECTING); ep->tos = 0; @@ -2119,7 +2095,7 @@ int c4iw_connect(struct iw_cm_id *cm_id, fail3: CTR2(KTR_IW_CXGBE, "%s:ccb %p", __func__, ep); - RTFREE(rt); + fib4_free_nh_ext(RT_DEFAULT_FIB, &nh_ext); fail2: cm_id->rem_ref(cm_id); c4iw_put_ep(&ep->com); Modified: projects/routing/sys/dev/cxgbe/tom/t4_connect.c ============================================================================== --- projects/routing/sys/dev/cxgbe/tom/t4_connect.c Sat Oct 25 17:42:44 2014 (r273641) +++ projects/routing/sys/dev/cxgbe/tom/t4_connect.c Sat Oct 25 18:25:00 2014 (r273642) @@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$"); #define TCPSTATES #include #include +#include #include "common/common.h" #include "common/t4_msg.h" @@ -310,17 +311,17 @@ act_open_cpl_size(struct adapter *sc, in * tcbinfo not locked (This has changed - used to be WLOCKed) * inp WLOCKed * tp->t_state = TCPS_SYN_SENT - * rtalloc1, RT_UNLOCK on rt. + * fib4_lookup_nh_ext */ int -t4_connect(struct toedev *tod, struct socket *so, struct rtentry *rt, - struct sockaddr *nam) +t4_connect(struct toedev *tod, struct socket *so, + struct nhopu_extended *nhu_ext, struct sockaddr *nam) { struct adapter *sc = tod->tod_softc; struct tom_data *td = tod_td(tod); struct toepcb *toep = NULL; struct wrqe *wr = NULL; - struct ifnet *rt_ifp = rt->rt_ifp; + struct ifnet *rt_ifp = nhu_ext->u.nh4.nh_ifp; struct port_info *pi; int mtu_idx, rscale, qid_atid, rc, isipv6; struct inpcb *inp = sotoinpcb(so); @@ -350,8 +351,23 @@ t4_connect(struct toedev *tod, struct so if (toep->tid < 0) DONT_OFFLOAD_ACTIVE_OPEN(ENOMEM); - toep->l2te = t4_l2t_get(pi, rt_ifp, - rt->rt_flags & RTF_GATEWAY ? rt->rt_gateway : nam); + toep->l2te = NULL; + if (nam->sa_family == AF_INET) { + struct sockaddr_in gw4; + memset(&gw4, 0, sizeof(gw4)); + gw4.sin_family = AF_INET; + gw4.sin_len = sizeof(gw4); + gw4.sin_addr = nhu_ext->u.nh4.nh_addr; + toep->l2te = t4_l2t_get(pi, rt_ifp, (struct sockaddr *)&gw4); + } else if (nam->sa_family == AF_INET6) { + struct sockaddr_in6 gw6; + memset(&gw6, 0, sizeof(gw6)); + gw6.sin6_family = AF_INET6; + gw6.sin6_len = sizeof(gw6); + gw6.sin6_addr = nhu_ext->u.nh6.nh_addr; + toep->l2te = t4_l2t_get(pi, rt_ifp, (struct sockaddr *)&gw6); + } + if (toep->l2te == NULL) DONT_OFFLOAD_ACTIVE_OPEN(ENOMEM); Modified: projects/routing/sys/dev/cxgbe/tom/t4_listen.c ============================================================================== --- projects/routing/sys/dev/cxgbe/tom/t4_listen.c Sat Oct 25 17:42:44 2014 (r273641) +++ projects/routing/sys/dev/cxgbe/tom/t4_listen.c Sat Oct 25 18:25:00 2014 (r273642) @@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$"); #define TCPSTATES #include #include +#include #include "common/common.h" #include "common/t4_msg.h" @@ -1123,45 +1124,40 @@ static struct l2t_entry * get_l2te_for_nexthop(struct port_info *pi, struct ifnet *ifp, struct in_conninfo *inc) { - struct rtentry *rt; struct l2t_entry *e; struct sockaddr_in6 sin6; + struct nhopu_extended nhu; struct sockaddr *dst = (void *)&sin6; if (inc->inc_flags & INC_ISIPV6) { dst->sa_len = sizeof(struct sockaddr_in6); dst->sa_family = AF_INET6; - ((struct sockaddr_in6 *)dst)->sin6_addr = inc->inc6_faddr; if (IN6_IS_ADDR_LINKLOCAL(&inc->inc6_laddr)) { /* no need for route lookup */ e = t4_l2t_get(pi, ifp, dst); return (e); } + + /* TODO: Multipath */ + if (fib6_lookup_nh_ext(inc->inc_fibnum, inc->inc6_faddr, + 0, 0, 0, &nhu.u.nh6) != 0) + return (NULL); + ((struct sockaddr_in6 *)dst)->sin6_addr = nhu.u.nh6.nh_addr; } else { dst->sa_len = sizeof(struct sockaddr_in); dst->sa_family = AF_INET; - ((struct sockaddr_in *)dst)->sin_addr = inc->inc_faddr; + + /* TODO: Multipath */ + if (fib4_lookup_nh_ext(inc->inc_fibnum, inc->inc_faddr, + 0, 0, &nhu.u.nh4) != 0) + return (NULL); + ((struct sockaddr_in *)dst)->sin_addr = nhu.u.nh4.nh_addr; } - rt = rtalloc1(dst, 0, 0); - if (rt == NULL) + if (nhu.u.nh4.nh_ifp != ifp) return (NULL); - else { - struct sockaddr *nexthop; - - RT_UNLOCK(rt); - if (rt->rt_ifp != ifp) - e = NULL; - else { - if (rt->rt_flags & RTF_GATEWAY) - nexthop = rt->rt_gateway; - else - nexthop = dst; - e = t4_l2t_get(pi, ifp, nexthop); - } - RTFREE(rt); - } + e = t4_l2t_get(pi, ifp, dst); return (e); } Modified: projects/routing/sys/dev/cxgbe/tom/t4_tom.h ============================================================================== --- projects/routing/sys/dev/cxgbe/tom/t4_tom.h Sat Oct 25 17:42:44 2014 (r273641) +++ projects/routing/sys/dev/cxgbe/tom/t4_tom.h Sat Oct 25 18:25:00 2014 (r273642) @@ -255,7 +255,7 @@ void release_lip(struct tom_data *, stru /* 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 nhopu_extended *, struct sockaddr *); void act_open_failure_cleanup(struct adapter *, u_int, u_int); Modified: projects/routing/sys/net/rt_nhops.c ============================================================================== --- projects/routing/sys/net/rt_nhops.c Sat Oct 25 17:42:44 2014 (r273641) +++ projects/routing/sys/net/rt_nhops.c Sat Oct 25 18:25:00 2014 (r273642) @@ -65,6 +65,7 @@ #include #include #include +#include #include #include @@ -117,6 +118,8 @@ static void fib4_rte_to_nh_basic(struct struct nhop4_basic *pnh4); #endif #ifdef INET +static void fib6_rte_to_nh_extended(struct rtentry *rte, struct in6_addr dst, + struct nhop6_extended *pnh6); static void fib6_rte_to_nh_basic(struct rtentry *rte, struct in6_addr dst, struct nhop6_basic *pnh6); #endif @@ -385,25 +388,19 @@ fib_rte_to_nh_flags(int rt_flags) return (res); } - static void -fib4_rte_to_nh_extended(struct rtentry *rte, struct in_addr dst, - struct nhop4_extended *pnh4) +fib4_rte_to_nh_basic(struct rtentry *rte, struct in_addr dst, + struct nhop4_basic *pnh4) { struct sockaddr_in *gw; - struct in_ifaddr *ia; - pnh4->nh_ifp = rte->rt_ifp; + pnh4->nh_ifp = rte->rt_ifa->ifa_ifp; pnh4->nh_mtu = min(rte->rt_mtu, rte->rt_ifp->if_mtu); if (rte->rt_flags & RTF_GATEWAY) { gw = (struct sockaddr_in *)rte->rt_gateway; pnh4->nh_addr = gw->sin_addr; } else pnh4->nh_addr = dst; - - ia = ifatoia(rte->rt_ifa); - pnh4->nh_src = IA_SIN(ia)->sin_addr; - /* Set flags */ pnh4->nh_flags = fib_rte_to_nh_flags(rte->rt_flags); gw = (struct sockaddr_in *)rt_key(rte); @@ -411,12 +408,12 @@ fib4_rte_to_nh_extended(struct rtentry * pnh4->nh_flags |= NHF_DEFAULT; } - static void -fib4_rte_to_nh_basic(struct rtentry *rte, struct in_addr dst, - struct nhop4_basic *pnh4) +fib4_rte_to_nh_extended(struct rtentry *rte, struct in_addr dst, + struct nhop4_extended *pnh4) { struct sockaddr_in *gw; + struct in_ifaddr *ia; pnh4->nh_ifp = rte->rt_ifa->ifa_ifp; pnh4->nh_mtu = min(rte->rt_mtu, rte->rt_ifp->if_mtu); @@ -430,6 +427,9 @@ fib4_rte_to_nh_basic(struct rtentry *rte gw = (struct sockaddr_in *)rt_key(rte); if (gw->sin_addr.s_addr == 0) pnh4->nh_flags |= NHF_DEFAULT; + + ia = ifatoia(rte->rt_ifa); + pnh4->nh_src = IA_SIN(ia)->sin_addr; } /* @@ -560,7 +560,6 @@ fib6_choose_prepend(uint32_t fibnum, str */ } - static void fib6_rte_to_nh_basic(struct rtentry *rte, struct in6_addr dst, struct nhop6_basic *pnh6) @@ -581,6 +580,30 @@ fib6_rte_to_nh_basic(struct rtentry *rte pnh6->nh_flags |= NHF_DEFAULT; } +static void +fib6_rte_to_nh_extended(struct rtentry *rte, struct in6_addr dst, + struct nhop6_extended *pnh6) +{ + struct sockaddr_in6 *gw; + struct in6_ifaddr *ia; + + pnh6->nh_ifp = rte->rt_ifa->ifa_ifp; + pnh6->nh_mtu = min(rte->rt_mtu, rte->rt_ifp->if_mtu); + if (rte->rt_flags & RTF_GATEWAY) { + gw = (struct sockaddr_in6 *)rte->rt_gateway; + pnh6->nh_addr = gw->sin6_addr; + } else + pnh6->nh_addr = dst; + /* Set flags */ + pnh6->nh_flags = fib_rte_to_nh_flags(rte->rt_flags); + gw = (struct sockaddr_in6 *)rt_key(rte); + if (IN6_IS_ADDR_UNSPECIFIED(&gw->sin6_addr)) + pnh6->nh_flags |= NHF_DEFAULT; + + ia = ifatoia6(rte->rt_ifa); + pnh6->nh_src = IA6_SIN6(ia)->sin6_addr; +} + int fib6_lookup_nh_basic(uint32_t fibnum, struct in6_addr dst, uint32_t flowid, struct nhop6_basic *pnh6) @@ -591,7 +614,7 @@ fib6_lookup_nh_basic(uint32_t fibnum, st struct rtentry *rte; KASSERT((fibnum < rt_numfibs), ("fib6_lookup_nh_basic: bad fibnum")); - rnh = rt_tables_get_rnh(fibnum, AF_INET); + rnh = rt_tables_get_rnh(fibnum, AF_INET6); if (rnh == NULL) return (ENOENT); @@ -614,8 +637,69 @@ fib6_lookup_nh_basic(uint32_t fibnum, st return (ENOENT); } + +/* + * Performs IPv6 route table lookup on @dst. Returns 0 on success. + * Stores extende nexthop info provided @pnh4 structure. + * Note that + * - nh_ifp cannot be safely dereferenced unless NHOP_LOOKUP_REF is specified. + * - in that case you need to call fib6_free_nh_ext() + * - nh_ifp represents logical transmit interface (rt_ifp) + * - mtu from logical transmit interface will be returned. + */ +int +fib6_lookup_nh_ext(uint32_t fibnum, struct in6_addr dst, uint32_t scopeid, + uint32_t flowid, uint32_t flags, struct nhop6_extended *pnh6) +{ + struct radix_node_head *rnh; + struct radix_node *rn; + struct sockaddr_in6 sin6; + struct rtentry *rte; + + KASSERT((fibnum < rt_numfibs), ("fib4_lookup_nh_ext: bad fibnum")); + rnh = rt_tables_get_rnh(fibnum, AF_INET6); + if (rnh == NULL) + return (ENOENT); + + /* Prepare lookup key */ + memset(&sin6, 0, sizeof(sin6)); + sin6.sin6_len = sizeof(struct sockaddr_in6); + sin6.sin6_addr = dst; + + RADIX_NODE_HEAD_RLOCK(rnh); + rn = rnh->rnh_matchaddr((void *)&sin6, rnh); + if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { + rte = RNTORT(rn); + /* Ensure route & ifp is UP */ + if (RT_LINK_IS_UP(rte->rt_ifp)) { + fib6_rte_to_nh_extended(rte, dst, pnh6); + if ((flags & NHOP_LOOKUP_REF) != 0) { + /* TODO: Do lwref on egress ifp's */ + } + RADIX_NODE_HEAD_RUNLOCK(rnh); + + return (0); + } + } + RADIX_NODE_HEAD_RUNLOCK(rnh); + + return (ENOENT); +} + +void +fib6_free_nh_ext(uint32_t fibnum, struct nhop6_extended *pnh6) +{ + +} + #endif +void +fib_free_nh_ext(uint32_t fibnum, struct nhopu_extended *pnhu) +{ + +} + #if 0 typedef void nhop_change_cb_t(void *state); Modified: projects/routing/sys/net/rt_nhops.h ============================================================================== --- projects/routing/sys/net/rt_nhops.h Sat Oct 25 17:42:44 2014 (r273641) +++ projects/routing/sys/net/rt_nhops.h Sat Oct 25 18:25:00 2014 (r273642) @@ -148,7 +148,7 @@ struct nhop6_basic { struct in6_addr nh_addr; /* GW/DST IPv4 address */ }; -struct nhop64_basic { +struct nhopu_basic { union { struct nhop4_basic nh4; struct nhop6_basic nh6; @@ -176,7 +176,7 @@ struct nhop6_extended { uint64_t spare2[2]; }; -struct nhop64_extended { +struct nhopu_extended { union { struct nhop4_extended nh4; struct nhop6_extended nh6; @@ -199,14 +199,22 @@ struct route_compat { int fib4_lookup_nh_basic(uint32_t fibnum, struct in_addr dst, uint32_t flowid, struct nhop4_basic *pnh4); -int fib6_lookup_nh_basic(uint32_t fibnum, struct in6_addr dst, uint32_t flowid, - struct nhop6_basic *pnh6); - int fib4_lookup_nh_ext(uint32_t fibnum, struct in_addr dst, uint32_t flowid, uint32_t flags, struct nhop4_extended *pnh4); void fib4_free_nh_ext(uint32_t fibnum, struct nhop4_extended *pnh4); #define NHOP_LOOKUP_REF 0x01 + +int fib6_lookup_nh_basic(uint32_t fibnum, struct in6_addr dst, uint32_t flowid, + struct nhop6_basic *pnh6); +int fib6_lookup_nh_ext(uint32_t fibnum, struct in6_addr dst, + uint32_t scopeid, uint32_t flowid, uint32_t flags, + struct nhop6_extended *pnh6); +void fib6_free_nh_ext(uint32_t fibnum, struct nhop6_extended *pnh6); + +void fib_free_nh_ext(uint32_t fibnum, struct nhopu_extended *pnhu); + + void fib4_free_nh_prepend(uint32_t fibnum, struct nhop_prepend *nh); void fib4_choose_prepend(uint32_t fibnum, struct nhop_prepend *nh_src, uint32_t flowid, struct nhop_prepend *nh, struct nhop4_extended *nh_ext); Modified: projects/routing/sys/netinet/tcp_offload.c ============================================================================== --- projects/routing/sys/netinet/tcp_offload.c Sat Oct 25 17:42:44 2014 (r273641) +++ projects/routing/sys/netinet/tcp_offload.c Sat Oct 25 18:25:00 2014 (r273642) @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #define TCPOUTFLAGS #include #include @@ -58,8 +59,9 @@ tcp_offload_connect(struct socket *so, s { struct ifnet *ifp; struct toedev *tod; - struct rtentry *rt; - int error = EOPNOTSUPP; + struct nhopu_extended nhu_ext; + int af, error = EOPNOTSUPP; + int fibnum; INP_WLOCK_ASSERT(sotoinpcb(so)); KASSERT(nam->sa_family == AF_INET || nam->sa_family == AF_INET6, @@ -68,24 +70,40 @@ tcp_offload_connect(struct socket *so, s if (registered_toedevs == 0) return (error); - rt = rtalloc1(nam, 0, 0); - if (rt) - RT_UNLOCK(rt); - else - return (EHOSTUNREACH); - - ifp = rt->rt_ifp; - - 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; + af = nam->sa_family; + fibnum = so->so_fibnum; + ifp = NULL; + + /* TODO: Multipath */ + if (af == AF_INET) { + if (fib4_lookup_nh_ext(fibnum, + ((struct sockaddr_in *)nam)->sin_addr, + 0, NHOP_LOOKUP_REF, &nhu_ext.u.nh4) != 0) + return (EHOSTUNREACH); + + ifp = nhu_ext.u.nh4.nh_ifp; + if ((ifp->if_capenable & IFCAP_TOE4) == 0) + goto done; + } else if (af == AF_INET6) { + struct sockaddr_in6 *sin6; + + sin6 = (struct sockaddr_in6 *)nam; + + if (fib6_lookup_nh_ext(fibnum, + sin6->sin6_addr, sin6->sin6_scope_id, + 0, NHOP_LOOKUP_REF, &nhu_ext.u.nh6) != 0) + return (EHOSTUNREACH); + + ifp = nhu_ext.u.nh6.nh_ifp; + if ((ifp->if_capenable & IFCAP_TOE6) == 0) + goto done; + } tod = TOEDEV(ifp); if (tod != NULL) - error = tod->tod_connect(tod, so, rt, nam); + error = tod->tod_connect(tod, so, &nhu_ext, nam); done: - RTFREE(rt); + fib_free_nh_ext(fibnum, &nhu_ext); return (error); } Modified: projects/routing/sys/netinet/toecore.c ============================================================================== --- projects/routing/sys/netinet/toecore.c Sat Oct 25 17:42:44 2014 (r273641) +++ projects/routing/sys/netinet/toecore.c Sat Oct 25 18:25:00 2014 (r273642) @@ -74,7 +74,7 @@ static eventhandler_tag route_redirect_e static int toedev_connect(struct toedev *tod __unused, struct socket *so __unused, - struct rtentry *rt __unused, struct sockaddr *nam __unused) + struct nhopu_extended *nh __unused, struct sockaddr *nam __unused) { return (ENOTSUP); @@ -135,7 +135,7 @@ toedev_l2_update(struct toedev *tod __un static void toedev_route_redirect(struct toedev *tod __unused, struct ifnet *ifp __unused, - struct rtentry *rt0 __unused, struct rtentry *rt1 __unused) + struct nhopu_extended *nh0 __unused, struct nhopu_extended *nh1 __unused) { return; @@ -438,8 +438,8 @@ toe_lle_event(void *arg __unused, struct * XXX: implement. */ static void -toe_route_redirect_event(void *arg __unused, struct rtentry *rt0, - struct rtentry *rt1, struct sockaddr *sa) +toe_route_redirect_event(void *arg __unused, struct nhopu_extended *nh0, + struct nhopu_extended *nh1, struct sockaddr *sa) { return; Modified: projects/routing/sys/netinet/toecore.h ============================================================================== --- projects/routing/sys/netinet/toecore.h Sat Oct 25 17:42:44 2014 (r273641) +++ projects/routing/sys/netinet/toecore.h Sat Oct 25 18:25:00 2014 (r273642) @@ -36,6 +36,7 @@ struct tcpopt; struct tcphdr; struct in_conninfo; +struct nhopu_extended; struct toedev { TAILQ_ENTRY(toedev) link; /* glue for toedev_list */ @@ -45,8 +46,8 @@ 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 *, - struct sockaddr *); + int (*tod_connect)(struct toedev *, struct socket *, + struct nhopu_extended *, struct sockaddr *); /* Passive open. */ int (*tod_listen_start)(struct toedev *, struct tcpcb *); @@ -89,7 +90,7 @@ struct toedev { /* XXX. Route has been redirected. */ void (*tod_route_redirect)(struct toedev *, struct ifnet *, - struct rtentry *, struct rtentry *); + struct nhopu_extended *, struct nhopu_extended *); /* Syncache interaction. */ void (*tod_syncache_added)(struct toedev *, void *); Modified: projects/routing/sys/netpfil/pf/pf.c ============================================================================== --- projects/routing/sys/netpfil/pf/pf.c Sat Oct 25 17:42:44 2014 (r273641) +++ projects/routing/sys/netpfil/pf/pf.c Sat Oct 25 18:25:00 2014 (r273642) @@ -2908,7 +2908,7 @@ pf_get_mss(struct mbuf *m, int off, u_in static u_int16_t pf_calc_mss(struct pf_addr *addr, sa_family_t af, int rtableid, u_int16_t offer) { - struct nhop64_basic nh; + struct nhopu_basic nh; int hlen = 0; u_int16_t mss = V_tcp_mssdflt; @@ -5084,7 +5084,7 @@ int pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *kif, int rtableid) { - struct nhop64_basic nh; + struct nhopu_basic nh; /* Skip checks for ipsec interfaces */ if (kif != NULL && kif->pfik_ifp->if_type == IFT_ENC)