From 9851dd6727c99f25838781a8ff208c28eb0604db Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Fri, 3 Dec 2010 18:06:23 -0800 Subject: [PATCH] tunneling: Remove call to eth_type_trans() on receive. On receive we call eth_type_trans() to set skb->protocol. However, that function also sets skb->pkt_type, which requires several comparisons to MAC addresses. Nothing in OVS cares about pkt_type, so this is wasteful. If we actually do egress to the IP stack through an internal device then we'll call eth_type_trans() to get everything correctly setup. It's possible for device drivers to see an incorrect pkt_type or not correctly parse legacy IPX (which eth_type_trans() also handles) but it's highly unlikely that they will care. Signed-off-by: Jesse Gross --- datapath/tunnel.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/datapath/tunnel.c b/datapath/tunnel.c index ec3ad936f..542badc4e 100644 --- a/datapath/tunnel.c +++ b/datapath/tunnel.c @@ -401,17 +401,26 @@ static inline void ecn_decapsulate(struct sk_buff *skb) /* Called with rcu_read_lock. */ void tnl_rcv(struct vport *vport, struct sk_buff *skb) { - skb->pkt_type = PACKET_HOST; - skb->protocol = eth_type_trans(skb, skb->dev); + /* Packets received by this function are in the following state: + * - skb->data points to the inner Ethernet header. + * - The inner Ethernet header is in the linear data area. + * - skb->csum does not include the inner Ethernet header. + * - The layer pointers point at the outer headers. + */ + + struct ethhdr *eh = (struct ethhdr *)skb->data; + + if (likely(ntohs(eh->h_proto) >= 1536)) + skb->protocol = eh->h_proto; + else + skb->protocol = htons(ETH_P_802_2); skb_dst_drop(skb); nf_reset(skb); secpath_reset(skb); - skb_reset_network_header(skb); + skb_set_network_header(skb, ETH_HLEN); ecn_decapsulate(skb); - - skb_push(skb, ETH_HLEN); compute_ip_summed(skb, false); vport_receive(vport, skb); -- 2.43.0