svn commit: r186576 - user/kmacy/HEAD_fast_net/sys/netinet
Kip Macy
kmacy at FreeBSD.org
Mon Dec 29 23:31:05 UTC 2008
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 <net/if.h>
#include <net/if_types.h>
+#include <net/if_llatbl.h>
#include <net/route.h>
#include <netinet/in.h>
@@ -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 <sys/vimage.h>
#include <net/if.h>
+#include <net/if_llatbl.h>
#include <net/netisr.h>
#include <net/pfil.h>
#include <net/route.h>
@@ -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);
More information about the svn-src-user
mailing list