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);
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);
+}
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;
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 */
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);
}