datapath: Avoid using wrong metadata for recic action.
authorPravin B Shelar <pshelar@nicira.com>
Wed, 13 Aug 2014 23:08:02 +0000 (16:08 -0700)
committerPravin B Shelar <pshelar@nicira.com>
Thu, 14 Aug 2014 19:22:10 +0000 (12:22 -0700)
Recirc action needs to extract flow key from packet, it uses tun_info
from OVS_CB for setting tunnel meta data in flow key. But tun_info
can be overwritten by tunnel send action. This would result in wrong
flow key for the recirculation.
Following patch copies flow-key meta data from OVS_CB packet key
itself thus avoids this bug.

Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Acked-by: Andy Zhou <azhou@nicira.com>
datapath/actions.c
datapath/flow.c
datapath/flow.h

index 263bd55..c206446 100644 (file)
@@ -554,17 +554,15 @@ static int execute_recirc(struct datapath *dp, struct sk_buff *skb,
                                 const struct nlattr *a)
 {
        struct sw_flow_key recirc_key;
-       uint32_t hash = OVS_CB(skb)->pkt_key->ovs_flow_hash;
        int err;
 
-       err = ovs_flow_key_extract(skb, &recirc_key);
+       err = ovs_flow_key_extract_recirc(nla_get_u32(a), OVS_CB(skb)->pkt_key,
+                                         skb, &recirc_key);
        if (err) {
                kfree_skb(skb);
                return err;
        }
 
-       recirc_key.ovs_flow_hash = hash;
-       recirc_key.recirc_id = nla_get_u32(a);
 
        ovs_dp_process_packet_with_key(skb, &recirc_key, true);
 
index 5fa3491..ee835d1 100644 (file)
@@ -636,3 +636,14 @@ int ovs_flow_key_extract_userspace(const struct nlattr *attr,
 
        return key_extract(skb, key);
 }
+
+int ovs_flow_key_extract_recirc(u32 recirc_id,
+                               const struct sw_flow_key *key,
+                               struct sk_buff *skb,
+                               struct sw_flow_key *new_key)
+{
+       memset(new_key, 0, sizeof(*new_key));
+       memcpy(new_key, key, OVS_SW_FLOW_KEY_METADATA_SIZE);
+       new_key->recirc_id = recirc_id;
+       return key_extract(skb, new_key);
+}
index ffe2879..06d95ac 100644 (file)
@@ -67,6 +67,11 @@ static inline void ovs_flow_tun_key_init(struct ovs_key_ipv4_tunnel *tun_key,
               sizeof(*tun_key) - OVS_TUNNEL_KEY_SIZE);
 }
 
+#define OVS_SW_FLOW_KEY_METADATA_SIZE                  \
+       (offsetof(struct sw_flow_key, recirc_id) +      \
+       FIELD_SIZEOF(struct sw_flow_key, recirc_id))
+
+
 struct sw_flow_key {
        struct ovs_key_ipv4_tunnel tun_key;  /* Encapsulating tunnel key. */
        struct {
@@ -195,5 +200,9 @@ int ovs_flow_key_extract(struct sk_buff *skb, struct sw_flow_key *key);
 int ovs_flow_key_extract_userspace(const struct nlattr *attr,
                                   struct sk_buff *skb,
                                   struct sw_flow_key *key);
+int ovs_flow_key_extract_recirc(u32 recirc_id,
+                               const struct sw_flow_key *key,
+                               struct sk_buff *skb,
+                               struct sw_flow_key *new_key);
 
 #endif /* flow.h */