[ovs-dev] [PATCH 06/14] tunneling: Fix header parsing for ECN decapsulation.

Jesse Gross jesse at nicira.com
Thu Dec 2 20:36:55 UTC 2010


When copying ECN bits from the tunnel header to the inner packet,
the network header was not being properly located when there was
a vlan tag.  This simplies and fixes the header parsing to prevent
this problem.  It also removes a call to eth_type_trans() which
does several comparisions of MAC addresses which are not needed here
because we do not need to set skb->pkt_type.

Signed-off-by: Jesse Gross <jesse at nicira.com>
---
 datapath/tunnel.c |   38 +++++++++++++++++++-------------------
 1 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/datapath/tunnel.c b/datapath/tunnel.c
index 4a60fa7..0671853 100644
--- a/datapath/tunnel.c
+++ b/datapath/tunnel.c
@@ -368,34 +368,33 @@ found:
 
 static inline void ecn_decapsulate(struct sk_buff *skb)
 {
-	u8 tos = ip_hdr(skb)->tos;
+	__be16 protocol = skb->protocol;
 
-	if (INET_ECN_is_ce(tos)) {
-		__be16 protocol = skb->protocol;
-		unsigned int nw_header = skb_network_offset(skb);
+	skb_set_network_header(skb, ETH_HLEN);
 
-		if (skb->protocol == htons(ETH_P_8021Q)) {
-			if (unlikely(!pskb_may_pull(skb, VLAN_ETH_HLEN)))
-				return;
+	if (protocol == htons(ETH_P_8021Q)) {
+		if (unlikely(!pskb_may_pull(skb, VLAN_ETH_HLEN)))
+			return;
 
-			protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
-			nw_header += VLAN_HLEN;
-		}
+		protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
+		skb_set_network_header(skb, VLAN_ETH_HLEN);
+	}
 
+	if (unlikely(INET_ECN_is_ce(ip_hdr(skb)->tos))) {
 		if (protocol == htons(ETH_P_IP)) {
-			if (unlikely(!pskb_may_pull(skb, nw_header
+			if (unlikely(!pskb_may_pull(skb, skb_network_offset(skb)
 			    + sizeof(struct iphdr))))
 				return;
 
-			IP_ECN_set_ce((struct iphdr *)(skb->data + nw_header));
+			IP_ECN_set_ce(ip_hdr(skb));
 		}
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 		else if (protocol == htons(ETH_P_IPV6)) {
-			if (unlikely(!pskb_may_pull(skb, nw_header
+			if (unlikely(!pskb_may_pull(skb, skb_network_offset(skb)
 			    + sizeof(struct ipv6hdr))))
 				return;
 
-			IP6_ECN_set_ce((struct ipv6hdr *)(skb->data + nw_header));
+			IP6_ECN_set_ce(ipv6_hdr(skb));
 		}
 #endif
 	}
@@ -404,17 +403,18 @@ 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);
+	skb_reset_mac_header(skb);
+
+	if (likely(ntohs(eth_hdr(skb)->h_proto) >= 1536))
+		skb->protocol = eth_hdr(skb)->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);
 
 	ecn_decapsulate(skb);
-
-	skb_push(skb, ETH_HLEN);
 	compute_ip_summed(skb, false);
 
 	vport_receive(vport, skb);
-- 
1.7.1





More information about the dev mailing list