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