net: openvswitch: Set OvS recirc_id from tc chain index
Offloaded OvS datapath rules are translated one to one to tc rules, for example the following simplified OvS rule: recirc_id(0),in_port(dev1),eth_type(0x0800),ct_state(-trk) actions:ct(),recirc(2) Will be translated to the following tc rule: $ tc filter add dev dev1 ingress \ prio 1 chain 0 proto ip \ flower tcp ct_state -trk \ action ct pipe \ action goto chain 2 Received packets will first travel though tc, and if they aren't stolen by it, like in the above rule, they will continue to OvS datapath. Since we already did some actions (action ct in this case) which might modify the packets, and updated action stats, we would like to continue the proccessing with the correct recirc_id in OvS (here recirc_id(2)) where we left off. To support this, introduce a new skb extension for tc, which will be used for translating tc chain to ovs recirc_id to handle these miss cases. Last tc chain index will be set by tc goto chain action and read by OvS datapath. Signed-off-by: Paul Blakey <paulb@mellanox.com> Signed-off-by: Vlad Buslov <vladbu@mellanox.com> Acked-by: Jiri Pirko <jiri@mellanox.com> Acked-by: Pravin B Shelar <pshelar@ovn.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
47e2527769
commit
95a7233c45
@@ -1545,10 +1545,34 @@ static void ovs_dp_reset_user_features(struct sk_buff *skb, struct genl_info *in
|
||||
dp->user_features = 0;
|
||||
}
|
||||
|
||||
static void ovs_dp_change(struct datapath *dp, struct nlattr *a[])
|
||||
DEFINE_STATIC_KEY_FALSE(tc_recirc_sharing_support);
|
||||
|
||||
static int ovs_dp_change(struct datapath *dp, struct nlattr *a[])
|
||||
{
|
||||
if (a[OVS_DP_ATTR_USER_FEATURES])
|
||||
dp->user_features = nla_get_u32(a[OVS_DP_ATTR_USER_FEATURES]);
|
||||
u32 user_features = 0;
|
||||
|
||||
if (a[OVS_DP_ATTR_USER_FEATURES]) {
|
||||
user_features = nla_get_u32(a[OVS_DP_ATTR_USER_FEATURES]);
|
||||
|
||||
if (user_features & ~(OVS_DP_F_VPORT_PIDS |
|
||||
OVS_DP_F_UNALIGNED |
|
||||
OVS_DP_F_TC_RECIRC_SHARING))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
#if !IS_ENABLED(CONFIG_NET_TC_SKB_EXT)
|
||||
if (user_features & OVS_DP_F_TC_RECIRC_SHARING)
|
||||
return -EOPNOTSUPP;
|
||||
#endif
|
||||
}
|
||||
|
||||
dp->user_features = user_features;
|
||||
|
||||
if (dp->user_features & OVS_DP_F_TC_RECIRC_SHARING)
|
||||
static_branch_enable(&tc_recirc_sharing_support);
|
||||
else
|
||||
static_branch_disable(&tc_recirc_sharing_support);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
|
||||
@@ -1610,7 +1634,9 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
|
||||
parms.port_no = OVSP_LOCAL;
|
||||
parms.upcall_portids = a[OVS_DP_ATTR_UPCALL_PID];
|
||||
|
||||
ovs_dp_change(dp, a);
|
||||
err = ovs_dp_change(dp, a);
|
||||
if (err)
|
||||
goto err_destroy_meters;
|
||||
|
||||
/* So far only local changes have been made, now need the lock. */
|
||||
ovs_lock();
|
||||
@@ -1736,7 +1762,9 @@ static int ovs_dp_cmd_set(struct sk_buff *skb, struct genl_info *info)
|
||||
if (IS_ERR(dp))
|
||||
goto err_unlock_free;
|
||||
|
||||
ovs_dp_change(dp, info->attrs);
|
||||
err = ovs_dp_change(dp, info->attrs);
|
||||
if (err)
|
||||
goto err_unlock_free;
|
||||
|
||||
err = ovs_dp_cmd_fill_info(dp, reply, info->snd_portid,
|
||||
info->snd_seq, 0, OVS_DP_CMD_SET);
|
||||
|
||||
Reference in New Issue
Block a user