[ovs-dev] [PATCH 15/16] datapath: ovs_flow_used: use encap_eth_type

Simon Horman horms at verge.net.au
Fri Jan 25 07:22:21 UTC 2013


The ethernet type of an encapsulated frame may be obtained from
actions. If so it should be used to correct decoding of L3 and L4
packet data.

Signed-off-by: Simon Horman <horms at verge.net.au>

---

v2.14 - v2.17
* No change

v2.13
* As suggested by Jarno Rajahalme
  - Initialise encap_eth_type as 0 in ovs_dp_process_received_packet()

v2.12
* Rebase
* Add dl_type parameter to flow_extract_l3_onwards,
  allowing this patch to be applied independently of
  the rest of the MPLS patch-set.

v2.11
* First post

flow: Split flow_extract

Split the L3 and above portion of flow_extract() out into
flow_extract_l3_onwards() and call flow_extract_l3_onwards()
from flow_extract().

This is to allow re-extraction of l3 and higher information using
flow->encap_dl_type which may be set using information contained
in actions.

Signed-off-by: Simon Horman <horms at verge.net.au>
---
 datapath/datapath.c |    6 +++---
 datapath/flow.c     |    8 +++++---
 datapath/flow.h     |    2 +-
 3 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/datapath/datapath.c b/datapath/datapath.c
index 02a0f16..c0c6d03 100644
--- a/datapath/datapath.c
+++ b/datapath/datapath.c
@@ -242,6 +242,7 @@ void ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb)
 	struct sw_flow *flow, *outer_flow = NULL;
 	struct dp_stats_percpu *stats;
 	u64 *stats_counter;
+	__be16 encap_eth_type = 0;
 	int error;
 
 	stats = this_cpu_ptr(dp->stats_percpu);
@@ -266,7 +267,6 @@ void ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb)
 		 * allow more information to be included in the flow's match
 		 */
 		if (likely(flow)) {
-			__be16 encap_eth_type;
 			encap_eth_type = flow->encap_eth_type;
 			if (unlikely(encap_eth_type)) {
 				error = ovs_flow_extract_l3_onwards(skb, &key, &key_len,
@@ -298,8 +298,8 @@ void ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb)
 
 	stats_counter = &stats->n_hit;
 	if (unlikely(outer_flow))
-		ovs_flow_used(outer_flow, skb);
-	ovs_flow_used(OVS_CB(skb)->flow, skb);
+		ovs_flow_used(outer_flow, htons(0), skb);
+	ovs_flow_used(OVS_CB(skb)->flow, encap_eth_type, skb);
 	ovs_execute_actions(dp, skb);
 
 out:
diff --git a/datapath/flow.c b/datapath/flow.c
index 973c871..0ff3247 100644
--- a/datapath/flow.c
+++ b/datapath/flow.c
@@ -180,12 +180,14 @@ static bool icmp6hdr_ok(struct sk_buff *skb)
 #define TCP_FLAGS_OFFSET 13
 #define TCP_FLAG_MASK 0x3f
 
-void ovs_flow_used(struct sw_flow *flow, struct sk_buff *skb)
+void ovs_flow_used(struct sw_flow *flow, __be16 encap_eth_type,
+		   struct sk_buff *skb)
 {
 	u8 tcp_flags = 0;
+	__be16 eth_type;
 
-	if ((flow->key.eth.type == htons(ETH_P_IP) ||
-	     flow->key.eth.type == htons(ETH_P_IPV6)) &&
+	eth_type = encap_eth_type ? encap_eth_type : flow->key.eth.type;
+	if ((eth_type == htons(ETH_P_IP) || eth_type == htons(ETH_P_IPV6)) &&
 	    flow->key.ip.proto == IPPROTO_TCP &&
 	    likely(skb->len >= skb_transport_offset(skb) + sizeof(struct tcphdr))) {
 		u8 *tcp = (u8 *)tcp_hdr(skb);
diff --git a/datapath/flow.h b/datapath/flow.h
index e29c4e7..488c307 100644
--- a/datapath/flow.h
+++ b/datapath/flow.h
@@ -199,7 +199,7 @@ int ovs_flow_extract_l3_onwards(struct sk_buff *, struct sw_flow_key *,
 				int key_lenp[2], __be16 eth_type);
 int ovs_flow_extract(struct sk_buff *, u16 in_port, struct sw_flow_key *,
 		     int *key_lenp);
-void ovs_flow_used(struct sw_flow *, struct sk_buff *);
+void ovs_flow_used(struct sw_flow *, __be16 encap_eth_type, struct sk_buff *);
 u64 ovs_flow_used_time(unsigned long flow_jiffies);
 
 /* Upper bound on the length of a nlattr-formatted flow key.  The longest
-- 
1.7.10.4




More information about the dev mailing list