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 14, 2014
1 parent e58ba93 commit bdfc1cf
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 4 deletions.
6 changes: 2 additions & 4 deletions datapath/actions.c
Expand Up @@ -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);

Expand Down
11 changes: 11 additions & 0 deletions datapath/flow.c
Expand Up @@ -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);
}
9 changes: 9 additions & 0 deletions datapath/flow.h
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 */

0 comments on commit bdfc1cf

Please sign in to comment.