svn commit: r186622 - user/kmacy/HEAD_fast_net/sys/net

Kip Macy kmacy at FreeBSD.org
Wed Dec 31 02:23:32 UTC 2008


Author: kmacy
Date: Wed Dec 31 02:23:31 2008
New Revision: 186622
URL: http://svn.freebsd.org/changeset/base/186622

Log:
  add shortcut for off-host ipv4 or ipv6 packets in ether_output

Modified:
  user/kmacy/HEAD_fast_net/sys/net/if_ethersubr.c

Modified: user/kmacy/HEAD_fast_net/sys/net/if_ethersubr.c
==============================================================================
--- user/kmacy/HEAD_fast_net/sys/net/if_ethersubr.c	Wed Dec 31 01:51:07 2008	(r186621)
+++ user/kmacy/HEAD_fast_net/sys/net/if_ethersubr.c	Wed Dec 31 02:23:31 2008	(r186622)
@@ -163,7 +163,7 @@ static int ether_ipfw;
 int
 ether_output(struct ifnet *ifp, struct mbuf *m, struct route *ro)
 {
-	short type;
+	short type = 0;
 	int error = 0, hdrcmplt = 0;
 	u_char esrc[ETHER_ADDR_LEN], edst[ETHER_ADDR_LEN];
 	struct llentry *lle = ro->ro_lle;
@@ -174,13 +174,11 @@ ether_output(struct ifnet *ifp, struct m
 	struct rtentry *rt0 = ro->ro_rt;
 	int hlen;	/* link layer header length */
 
-
 #ifdef MAC
 	error = mac_ifnet_check_transmit(ifp, m);
 	if (error)
 		senderr(error);
 #endif
-
 	M_PROFILE(m);
 	if (ifp->if_flags & IFF_MONITOR)
 		senderr(ENETDOWN);
@@ -189,6 +187,50 @@ ether_output(struct ifnet *ifp, struct m
 		senderr(ENETDOWN);
 
 	hlen = ETHER_HDR_LEN;
+
+	/*
+	 * First try to see if we can shortcut most of ether_output
+	 * 1) do we have a valid lle?
+	 * 2) is this not a bridge?
+	 * 3) is carp disabled?
+	 * 4) is netgraph disabled for this device?
+	 * 5) is this not loopback?
+	 */
+	t = pf_find_mtag(m);
+	if (lle != NULL && (lle->la_flags & LLE_VALID) &&
+	    ifp->if_bridge == NULL && ifp->if_carp == NULL &&
+	    IFP2AC(ifp)->ac_netgraph == NULL &&
+	    (t == NULL || t->routed)) {
+
+		switch (dst->sa_family) {
+		case AF_INET:
+			type = htons(ETHERTYPE_IP);
+			break;
+		case AF_INET6:
+			type = htons(ETHERTYPE_IPV6);
+			break;
+		}
+		if (type != 0) {
+			M_PREPEND(m, ETHER_HDR_LEN, M_DONTWAIT);
+			if (m == NULL)
+				senderr(ENOBUFS);
+			eh = mtod(m, struct ether_header *);
+			(void)memcpy(&eh->ether_type, &type,
+			    sizeof(eh->ether_type));
+			(void)memcpy(eh->ether_dhost, &lle->ll_addr.mac16,
+			    sizeof (edst));
+			(void)memcpy(eh->ether_shost, IF_LLADDR(ifp),
+			    sizeof(eh->ether_shost));
+
+		}
+		/* Continue with link-layer output */
+		return ether_output_frame(ifp, m);
+	}
+
+	/*
+	 * The shortcut failed, use default path
+	 *
+	 */
 	switch (dst->sa_family) {
 #ifdef INET
 	case AF_INET:
@@ -340,7 +382,7 @@ ether_output(struct ifnet *ifp, struct m
 	 * reasons and compatibility with the original behavior.
 	 */
 	if ((ifp->if_flags & IFF_SIMPLEX) && loop_copy &&
-	    ((t = pf_find_mtag(m)) == NULL || !t->routed)) {
+	    (t == NULL || !t->routed)) {
 		int csum_flags = 0;
 
 		if (m->m_pkthdr.csum_flags & CSUM_IP)


More information about the svn-src-user mailing list