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.14 - v2.18 * 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 <ho...@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 960f4b1..e4bfc55 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 8c08c3a..f4ead98 100644 --- a/datapath/flow.h +++ b/datapath/flow.h @@ -204,7 +204,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