From owner-svn-src-user@FreeBSD.ORG Mon Dec 29 23:31:05 2008 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 73A4C106564A; Mon, 29 Dec 2008 23:31:05 +0000 (UTC) (envelope-from kmacy@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 630A68FC14; Mon, 29 Dec 2008 23:31:05 +0000 (UTC) (envelope-from kmacy@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id mBTNV558069764; Mon, 29 Dec 2008 23:31:05 GMT (envelope-from kmacy@svn.freebsd.org) Received: (from kmacy@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id mBTNV5gu069760; Mon, 29 Dec 2008 23:31:05 GMT (envelope-from kmacy@svn.freebsd.org) Message-Id: <200812292331.mBTNV5gu069760@svn.freebsd.org> From: Kip Macy Date: Mon, 29 Dec 2008 23:31:05 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r186576 - user/kmacy/HEAD_fast_net/sys/netinet X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 29 Dec 2008 23:31:05 -0000 Author: kmacy Date: Mon Dec 29 23:31:04 2008 New Revision: 186576 URL: http://svn.freebsd.org/changeset/base/186576 Log: install cached llentry in the inpcb and then pass down to ether_output in the struct route Modified: user/kmacy/HEAD_fast_net/sys/netinet/if_ether.c user/kmacy/HEAD_fast_net/sys/netinet/in_pcb.c user/kmacy/HEAD_fast_net/sys/netinet/in_pcb.h user/kmacy/HEAD_fast_net/sys/netinet/ip_output.c Modified: user/kmacy/HEAD_fast_net/sys/netinet/if_ether.c ============================================================================== --- user/kmacy/HEAD_fast_net/sys/netinet/if_ether.c Mon Dec 29 22:36:23 2008 (r186575) +++ user/kmacy/HEAD_fast_net/sys/netinet/if_ether.c Mon Dec 29 23:31:04 2008 (r186576) @@ -80,7 +80,6 @@ __FBSDID("$FreeBSD$"); #define SIN(s) ((struct sockaddr_in *)s) #define SDL(s) ((struct sockaddr_dl *)s) -#define LLTABLE(ifp) ((struct lltable *)(ifp)->if_afdata[AF_INET]) SYSCTL_DECL(_net_link_ether); SYSCTL_NODE(_net_link_ether, PF_INET, inet, CTLFLAG_RW, 0, ""); Modified: user/kmacy/HEAD_fast_net/sys/netinet/in_pcb.c ============================================================================== --- user/kmacy/HEAD_fast_net/sys/netinet/in_pcb.c Mon Dec 29 22:36:23 2008 (r186575) +++ user/kmacy/HEAD_fast_net/sys/netinet/in_pcb.c Mon Dec 29 23:31:04 2008 (r186576) @@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -494,6 +495,11 @@ void in_pcbrtalloc(struct inpcb *inp, in_addr_t faddr, struct route *sro) { struct sockaddr_in *sin; + struct sockaddr *dst; + struct llentry *la; + struct rtentry *rt; + struct ifnet *ifp; + int flags = LLE_EXCLUSIVE; INP_WLOCK_ASSERT(inp); bzero(sro, sizeof(*sro)); @@ -516,11 +522,39 @@ in_pcbrtalloc(struct inpcb *inp, in_addr #endif } - if (sro->ro_rt != NULL) { - inp->inp_rt = sro->ro_rt; - inp->inp_vflag |= INP_RT_VALID; + rt = sro->ro_rt; + if (rt == NULL) + return; + + inp->inp_rt = rt; + inp->inp_vflag |= INP_RT_VALID; + if (rt->rt_ifp == NULL) + return; + + ifp = rt->rt_ifp; + dst = &sro->ro_dst; + if (rt->rt_flags & RTF_GATEWAY) + dst = rt->rt_gateway; + + IF_AFDATA_RLOCK(ifp); + la = lla_lookup(LLTABLE(ifp), flags, dst); + IF_AFDATA_RUNLOCK(ifp); + if ((la == NULL) && + (ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) == 0) { + flags |= (LLE_CREATE | LLE_EXCLUSIVE); + IF_AFDATA_WLOCK(ifp); + la = lla_lookup(LLTABLE(ifp), flags, dst); + IF_AFDATA_WUNLOCK(ifp); } + if (la == NULL) + return; + + LLE_ADDREF(la); + LLE_WUNLOCK(la); + + inp->inp_lle = la; + inp->inp_flags |= INP_LLE_VALID; } /* @@ -905,9 +939,14 @@ in_pcbdisconnect(struct inpcb *inp) INP_WLOCK_ASSERT(inp); if (inp->inp_vflag & INP_RT_VALID) { + inp->inp_vflag &= ~INP_RT_VALID; RTFREE(inp->inp_rt); inp->inp_rt = NULL; - inp->inp_vflag &= ~INP_RT_VALID; + } + if (inp->inp_flags & INP_LLE_VALID) { + inp->inp_flags &= ~INP_LLE_VALID; + LLE_FREE(inp->inp_lle); + inp->inp_lle = NULL; } inp->inp_faddr.s_addr = INADDR_ANY; @@ -948,11 +987,16 @@ in_pcbfree_internal(struct inpcb *inp) INP_WLOCK_ASSERT(inp); if (inp->inp_vflag & INP_RT_VALID) { + inp->inp_vflag &= ~INP_RT_VALID; RTFREE(inp->inp_rt); inp->inp_rt = NULL; - inp->inp_vflag &= ~INP_RT_VALID; } - + if (inp->inp_flags & INP_LLE_VALID) { + inp->inp_flags &= ~INP_LLE_VALID; + LLE_FREE(inp->inp_lle); + inp->inp_lle = NULL; + } + #ifdef IPSEC if (inp->inp_sp != NULL) ipsec_delete_pcbpolicy(inp); Modified: user/kmacy/HEAD_fast_net/sys/netinet/in_pcb.h ============================================================================== --- user/kmacy/HEAD_fast_net/sys/netinet/in_pcb.h Mon Dec 29 22:36:23 2008 (r186575) +++ user/kmacy/HEAD_fast_net/sys/netinet/in_pcb.h Mon Dec 29 23:31:04 2008 (r186576) @@ -418,6 +418,7 @@ void inp_4tuple_get(struct inpcb *inp, #define INP_FAITH 0x200 /* accept FAITH'ed connections */ #define INP_RECVTTL 0x400 /* receive incoming IP TTL */ #define INP_DONTFRAG 0x800 /* don't fragment packet */ +#define INP_LLE_VALID 0x1000 /* L2 entry is set */ #define IN6P_IPV6_V6ONLY 0x008000 /* restrict AF_INET6 socket for v6 */ Modified: user/kmacy/HEAD_fast_net/sys/netinet/ip_output.c ============================================================================== --- user/kmacy/HEAD_fast_net/sys/netinet/ip_output.c Mon Dec 29 22:36:23 2008 (r186575) +++ user/kmacy/HEAD_fast_net/sys/netinet/ip_output.c Mon Dec 29 23:31:04 2008 (r186576) @@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -121,7 +122,7 @@ ip_output(struct mbuf *m, struct mbuf *o int hlen = sizeof (struct ip); int mtu; int len, error = 0; - int neednewroute = 0; + int neednewroute = 0, neednewlle = 0; struct sockaddr_in *dst = NULL; /* keep compiler happy */ struct in_ifaddr *ia = NULL; int isbroadcast, sw_csum; @@ -150,7 +151,13 @@ ip_output(struct mbuf *m, struct mbuf *o ro->ro_rt = inp->inp_rt; } else neednewroute = 1; - } + } + if ((ro == &iproute) && (inp->inp_flags & INP_LLE_VALID)) { + if (inp->inp_lle->la_flags & LLE_VALID) { + ro->ro_lle = inp->inp_lle; + } else + neednewlle = 1; + } } if (opt) { @@ -625,19 +632,44 @@ passout: done: if (ro == &iproute && ro->ro_rt != NULL) { int wlocked; - + struct llentry *la; + + wlocked = INP_WLOCKED(inp); if (inp == NULL || (inp->inp_vflag & INP_RT_VALID) == 0) - RTFREE(ro->ro_rt); + RTFREE(ro->ro_rt); else if (neednewroute && ro->ro_rt != inp->inp_rt) { - wlocked = INP_WLOCKED(inp); if (!wlocked && INP_TRY_UPGRADE(inp) == 0) return (error); RTFREE(inp->inp_rt); inp->inp_rt = ro->ro_rt; - if (!wlocked) - INP_DOWNGRADE(inp); + + } + if (neednewlle) { + if (!wlocked && INP_TRY_UPGRADE(inp) == 0) + return (error); + IF_AFDATA_RLOCK(ifp); + la = lla_lookup(LLTABLE(ifp), LLE_EXCLUSIVE, + (struct sockaddr *)dst); + IF_AFDATA_RUNLOCK(ifp); + if ((la == NULL) && + (ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) == 0) { + IF_AFDATA_WLOCK(ifp); + la = lla_lookup(LLTABLE(ifp), + (LLE_CREATE | LLE_EXCLUSIVE), + (struct sockaddr *)dst); + IF_AFDATA_WUNLOCK(ifp); + } + if (la != NULL) { + LLE_FREE(inp->inp_lle); + LLE_ADDREF(la); + LLE_WUNLOCK(la); + inp->inp_lle = la; + } } + if (!wlocked) + INP_DOWNGRADE(inp); } + return (error); bad: m_freem(m);