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 <ho...@verge.net.au>

---

v2.12
* No change

v2.11
* First post
---
 datapath/datapath.c |   12 ++++++------
 datapath/flow.c     |    8 +++++---
 datapath/flow.h     |    2 +-
 3 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/datapath/datapath.c b/datapath/datapath.c
index 57ab1b1..6dd92e4 100644
--- a/datapath/datapath.c
+++ b/datapath/datapath.c
@@ -344,6 +344,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;
        int error;
 
        stats = this_cpu_ptr(dp->stats_percpu);
@@ -368,11 +369,10 @@ 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 eth_type;
-                       eth_type = ovs_actions_allow_l3_extraction(flow);
-                       if (unlikely(eth_type)) {
+                       encap_eth_type = ovs_actions_allow_l3_extraction(flow);
+                       if (unlikely(encap_eth_type)) {
                                error = ovs_flow_extract_l3_onwards(skb, &key, 
&key_len,
-                                                                   eth_type);
+                                                                   
encap_eth_type);
                                if (unlikely(error)) {
                                        kfree_skb(skb);
                                        return;
@@ -400,8 +400,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 89b72a9..70eb590 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 a6d76d1..78a3af0 100644
--- a/datapath/flow.h
+++ b/datapath/flow.h
@@ -162,7 +162,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

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to