Skip to content

Commit

Permalink
openvswitch: add ct_clear action
Browse files Browse the repository at this point in the history
This adds a ct_clear action for clearing conntrack state. ct_clear is
currently implemented in OVS userspace, but is not backed by an action
in the kernel datapath. This is useful for flows that may modify a
packet tuple after a ct lookup has already occurred.

Signed-off-by: Eric Garver <e@erig.me>
Acked-by: Pravin B Shelar <pshelar@ovn.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Eric Garver authored and David S. Miller committed Oct 10, 2017
1 parent 833e0e2 commit b822696
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 0 deletions.
2 changes: 2 additions & 0 deletions include/uapi/linux/openvswitch.h
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,7 @@ struct ovs_action_push_eth {
* packet.
* @OVS_ACTION_ATTR_POP_ETH: Pop the outermost Ethernet header off the
* packet.
* @OVS_ACTION_ATTR_CT_CLEAR: Clear conntrack state from the packet.
*
* Only a single header can be set with a single %OVS_ACTION_ATTR_SET. Not all
* fields within a header are modifiable, e.g. the IPv4 protocol and fragment
Expand Down Expand Up @@ -836,6 +837,7 @@ enum ovs_action_attr {
OVS_ACTION_ATTR_TRUNC, /* u32 struct ovs_action_trunc. */
OVS_ACTION_ATTR_PUSH_ETH, /* struct ovs_action_push_eth. */
OVS_ACTION_ATTR_POP_ETH, /* No argument. */
OVS_ACTION_ATTR_CT_CLEAR, /* No argument. */

__OVS_ACTION_ATTR_MAX, /* Nothing past this will be accepted
* from userspace. */
Expand Down
4 changes: 4 additions & 0 deletions net/openvswitch/actions.c
Original file line number Diff line number Diff line change
Expand Up @@ -1203,6 +1203,10 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
return err == -EINPROGRESS ? 0 : err;
break;

case OVS_ACTION_ATTR_CT_CLEAR:
err = ovs_ct_clear(skb, key);
break;

case OVS_ACTION_ATTR_PUSH_ETH:
err = push_eth(skb, key, nla_data(a));
break;
Expand Down
11 changes: 11 additions & 0 deletions net/openvswitch/conntrack.c
Original file line number Diff line number Diff line change
Expand Up @@ -1129,6 +1129,17 @@ int ovs_ct_execute(struct net *net, struct sk_buff *skb,
return err;
}

int ovs_ct_clear(struct sk_buff *skb, struct sw_flow_key *key)
{
if (skb_nfct(skb)) {
nf_conntrack_put(skb_nfct(skb));
nf_ct_set(skb, NULL, IP_CT_UNTRACKED);
ovs_ct_fill_key(skb, key);
}

return 0;
}

static int ovs_ct_add_helper(struct ovs_conntrack_info *info, const char *name,
const struct sw_flow_key *key, bool log)
{
Expand Down
7 changes: 7 additions & 0 deletions net/openvswitch/conntrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ int ovs_ct_action_to_attr(const struct ovs_conntrack_info *, struct sk_buff *);

int ovs_ct_execute(struct net *, struct sk_buff *, struct sw_flow_key *,
const struct ovs_conntrack_info *);
int ovs_ct_clear(struct sk_buff *skb, struct sw_flow_key *key);

void ovs_ct_fill_key(const struct sk_buff *skb, struct sw_flow_key *key);
int ovs_ct_put_key(const struct sw_flow_key *swkey,
Expand Down Expand Up @@ -73,6 +74,12 @@ static inline int ovs_ct_execute(struct net *net, struct sk_buff *skb,
return -ENOTSUPP;
}

static inline int ovs_ct_clear(struct sk_buff *skb,
struct sw_flow_key *key)
{
return -ENOTSUPP;
}

static inline void ovs_ct_fill_key(const struct sk_buff *skb,
struct sw_flow_key *key)
{
Expand Down
5 changes: 5 additions & 0 deletions net/openvswitch/flow_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ static bool actions_may_change_flow(const struct nlattr *actions)
break;

case OVS_ACTION_ATTR_CT:
case OVS_ACTION_ATTR_CT_CLEAR:
case OVS_ACTION_ATTR_HASH:
case OVS_ACTION_ATTR_POP_ETH:
case OVS_ACTION_ATTR_POP_MPLS:
Expand Down Expand Up @@ -2528,6 +2529,7 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
[OVS_ACTION_ATTR_SAMPLE] = (u32)-1,
[OVS_ACTION_ATTR_HASH] = sizeof(struct ovs_action_hash),
[OVS_ACTION_ATTR_CT] = (u32)-1,
[OVS_ACTION_ATTR_CT_CLEAR] = 0,
[OVS_ACTION_ATTR_TRUNC] = sizeof(struct ovs_action_trunc),
[OVS_ACTION_ATTR_PUSH_ETH] = sizeof(struct ovs_action_push_eth),
[OVS_ACTION_ATTR_POP_ETH] = 0,
Expand Down Expand Up @@ -2669,6 +2671,9 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
skip_copy = true;
break;

case OVS_ACTION_ATTR_CT_CLEAR:
break;

case OVS_ACTION_ATTR_PUSH_ETH:
/* Disallow pushing an Ethernet header if one
* is already present */
Expand Down

0 comments on commit b822696

Please sign in to comment.