|
@@ -608,17 +608,16 @@ static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port)
|
|
|
}
|
|
|
|
|
|
static int output_userspace(struct datapath *dp, struct sk_buff *skb,
|
|
|
- struct sw_flow_key *key, const struct nlattr *attr)
|
|
|
+ struct sw_flow_key *key, const struct nlattr *attr,
|
|
|
+ const struct nlattr *actions, int actions_len)
|
|
|
{
|
|
|
struct ovs_tunnel_info info;
|
|
|
struct dp_upcall_info upcall;
|
|
|
const struct nlattr *a;
|
|
|
int rem;
|
|
|
|
|
|
+ memset(&upcall, 0, sizeof(upcall));
|
|
|
upcall.cmd = OVS_PACKET_CMD_ACTION;
|
|
|
- upcall.userdata = NULL;
|
|
|
- upcall.portid = 0;
|
|
|
- upcall.egress_tun_info = NULL;
|
|
|
|
|
|
for (a = nla_data(attr), rem = nla_len(attr); rem > 0;
|
|
|
a = nla_next(a, &rem)) {
|
|
@@ -647,6 +646,13 @@ static int output_userspace(struct datapath *dp, struct sk_buff *skb,
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
+ case OVS_USERSPACE_ATTR_ACTIONS: {
|
|
|
+ /* Include actions. */
|
|
|
+ upcall.actions = actions;
|
|
|
+ upcall.actions_len = actions_len;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
} /* End of switch. */
|
|
|
}
|
|
|
|
|
@@ -654,7 +660,8 @@ static int output_userspace(struct datapath *dp, struct sk_buff *skb,
|
|
|
}
|
|
|
|
|
|
static int sample(struct datapath *dp, struct sk_buff *skb,
|
|
|
- struct sw_flow_key *key, const struct nlattr *attr)
|
|
|
+ struct sw_flow_key *key, const struct nlattr *attr,
|
|
|
+ const struct nlattr *actions, int actions_len)
|
|
|
{
|
|
|
const struct nlattr *acts_list = NULL;
|
|
|
const struct nlattr *a;
|
|
@@ -688,7 +695,7 @@ static int sample(struct datapath *dp, struct sk_buff *skb,
|
|
|
*/
|
|
|
if (likely(nla_type(a) == OVS_ACTION_ATTR_USERSPACE &&
|
|
|
nla_is_last(a, rem)))
|
|
|
- return output_userspace(dp, skb, key, a);
|
|
|
+ return output_userspace(dp, skb, key, a, actions, actions_len);
|
|
|
|
|
|
skb = skb_clone(skb, GFP_ATOMIC);
|
|
|
if (!skb)
|
|
@@ -872,7 +879,7 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
|
|
|
break;
|
|
|
|
|
|
case OVS_ACTION_ATTR_USERSPACE:
|
|
|
- output_userspace(dp, skb, key, a);
|
|
|
+ output_userspace(dp, skb, key, a, attr, len);
|
|
|
break;
|
|
|
|
|
|
case OVS_ACTION_ATTR_HASH:
|
|
@@ -916,7 +923,7 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
|
|
|
break;
|
|
|
|
|
|
case OVS_ACTION_ATTR_SAMPLE:
|
|
|
- err = sample(dp, skb, key, a);
|
|
|
+ err = sample(dp, skb, key, a, attr, len);
|
|
|
break;
|
|
|
}
|
|
|
|