Skip to content

Commit

Permalink
datapath: Avoid using wrong metadata for recic action.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Pravin B Shelar committed Aug 7, 2014
1 parent c135bba commit 7f45215
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 10 deletions.
6 changes: 2 additions & 4 deletions datapath/actions.c
Expand Up @@ -649,17 +649,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);

Expand Down
10 changes: 10 additions & 0 deletions datapath/flow.c
Expand Up @@ -718,3 +718,13 @@ 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)
{
memcpy(new_key, key, OVS_SW_FLOW_KEY_METADATA_SIZE);
new_key->recirc_id = recirc_id;
return key_extract(skb, new_key);
}
9 changes: 9 additions & 0 deletions datapath/flow.h
Expand Up @@ -87,6 +87,11 @@ static inline void ovs_flow_tun_info_init(struct ovs_tunnel_info *tun_info,
tun_info->options_len = opts_len;
}

#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 {
u8 tun_opts[255];
u8 tun_opts_len;
Expand Down Expand Up @@ -222,5 +227,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 */
7 changes: 1 addition & 6 deletions datapath/flow_netlink.c
Expand Up @@ -1016,13 +1016,8 @@ int ovs_nla_get_flow_metadata(const struct nlattr *attr,
memset(&match, 0, sizeof(match));
match.key = key;

key->tun_opts_len = 0;
memset(&key->tun_key, 0, sizeof(key->tun_key));
key->phy.priority = 0;
key->phy.skb_mark = 0;
memset(key, 0, OVS_SW_FLOW_KEY_METADATA_SIZE);
key->phy.in_port = DP_MAX_PORTS;
key->ovs_flow_hash = 0;
key->recirc_id = 0;

return metadata_from_nlattrs(&match, &attrs, a, false);
}
Expand Down

0 comments on commit 7f45215

Please sign in to comment.