aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch
diff options
context:
space:
mode:
authorEric Garver <e@erig.me>2017-10-10 16:54:44 -0400
committerDavid S. Miller <davem@davemloft.net>2017-10-10 19:38:34 -0400
commitb8226962b1c49c784aeddb9d2fafbf53dfdc2190 (patch)
tree838a6a361a81ff5f613371bcdfcd2113270b0fab /net/openvswitch
parent833e0e2f24fd0525090878f71e129a8a4cb8bf78 (diff)
openvswitch: add ct_clear action
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>
Diffstat (limited to 'net/openvswitch')
-rw-r--r--net/openvswitch/actions.c4
-rw-r--r--net/openvswitch/conntrack.c11
-rw-r--r--net/openvswitch/conntrack.h7
-rw-r--r--net/openvswitch/flow_netlink.c5
4 files changed, 27 insertions, 0 deletions
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
index a54a556fcdb5..a551232daf61 100644
--- a/net/openvswitch/actions.c
+++ b/net/openvswitch/actions.c
@@ -1203,6 +1203,10 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
1203 return err == -EINPROGRESS ? 0 : err; 1203 return err == -EINPROGRESS ? 0 : err;
1204 break; 1204 break;
1205 1205
1206 case OVS_ACTION_ATTR_CT_CLEAR:
1207 err = ovs_ct_clear(skb, key);
1208 break;
1209
1206 case OVS_ACTION_ATTR_PUSH_ETH: 1210 case OVS_ACTION_ATTR_PUSH_ETH:
1207 err = push_eth(skb, key, nla_data(a)); 1211 err = push_eth(skb, key, nla_data(a));
1208 break; 1212 break;
diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c
index d558e882ca0c..fe861e2f0deb 100644
--- a/net/openvswitch/conntrack.c
+++ b/net/openvswitch/conntrack.c
@@ -1129,6 +1129,17 @@ int ovs_ct_execute(struct net *net, struct sk_buff *skb,
1129 return err; 1129 return err;
1130} 1130}
1131 1131
1132int ovs_ct_clear(struct sk_buff *skb, struct sw_flow_key *key)
1133{
1134 if (skb_nfct(skb)) {
1135 nf_conntrack_put(skb_nfct(skb));
1136 nf_ct_set(skb, NULL, IP_CT_UNTRACKED);
1137 ovs_ct_fill_key(skb, key);
1138 }
1139
1140 return 0;
1141}
1142
1132static int ovs_ct_add_helper(struct ovs_conntrack_info *info, const char *name, 1143static int ovs_ct_add_helper(struct ovs_conntrack_info *info, const char *name,
1133 const struct sw_flow_key *key, bool log) 1144 const struct sw_flow_key *key, bool log)
1134{ 1145{
diff --git a/net/openvswitch/conntrack.h b/net/openvswitch/conntrack.h
index bc7efd1867ab..399dfdd2c4f9 100644
--- a/net/openvswitch/conntrack.h
+++ b/net/openvswitch/conntrack.h
@@ -30,6 +30,7 @@ int ovs_ct_action_to_attr(const struct ovs_conntrack_info *, struct sk_buff *);
30 30
31int ovs_ct_execute(struct net *, struct sk_buff *, struct sw_flow_key *, 31int ovs_ct_execute(struct net *, struct sk_buff *, struct sw_flow_key *,
32 const struct ovs_conntrack_info *); 32 const struct ovs_conntrack_info *);
33int ovs_ct_clear(struct sk_buff *skb, struct sw_flow_key *key);
33 34
34void ovs_ct_fill_key(const struct sk_buff *skb, struct sw_flow_key *key); 35void ovs_ct_fill_key(const struct sk_buff *skb, struct sw_flow_key *key);
35int ovs_ct_put_key(const struct sw_flow_key *swkey, 36int ovs_ct_put_key(const struct sw_flow_key *swkey,
@@ -73,6 +74,12 @@ static inline int ovs_ct_execute(struct net *net, struct sk_buff *skb,
73 return -ENOTSUPP; 74 return -ENOTSUPP;
74} 75}
75 76
77static inline int ovs_ct_clear(struct sk_buff *skb,
78 struct sw_flow_key *key)
79{
80 return -ENOTSUPP;
81}
82
76static inline void ovs_ct_fill_key(const struct sk_buff *skb, 83static inline void ovs_ct_fill_key(const struct sk_buff *skb,
77 struct sw_flow_key *key) 84 struct sw_flow_key *key)
78{ 85{
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
index fc0ca9a89b8e..dc0d79092e74 100644
--- a/net/openvswitch/flow_netlink.c
+++ b/net/openvswitch/flow_netlink.c
@@ -76,6 +76,7 @@ static bool actions_may_change_flow(const struct nlattr *actions)
76 break; 76 break;
77 77
78 case OVS_ACTION_ATTR_CT: 78 case OVS_ACTION_ATTR_CT:
79 case OVS_ACTION_ATTR_CT_CLEAR:
79 case OVS_ACTION_ATTR_HASH: 80 case OVS_ACTION_ATTR_HASH:
80 case OVS_ACTION_ATTR_POP_ETH: 81 case OVS_ACTION_ATTR_POP_ETH:
81 case OVS_ACTION_ATTR_POP_MPLS: 82 case OVS_ACTION_ATTR_POP_MPLS:
@@ -2528,6 +2529,7 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
2528 [OVS_ACTION_ATTR_SAMPLE] = (u32)-1, 2529 [OVS_ACTION_ATTR_SAMPLE] = (u32)-1,
2529 [OVS_ACTION_ATTR_HASH] = sizeof(struct ovs_action_hash), 2530 [OVS_ACTION_ATTR_HASH] = sizeof(struct ovs_action_hash),
2530 [OVS_ACTION_ATTR_CT] = (u32)-1, 2531 [OVS_ACTION_ATTR_CT] = (u32)-1,
2532 [OVS_ACTION_ATTR_CT_CLEAR] = 0,
2531 [OVS_ACTION_ATTR_TRUNC] = sizeof(struct ovs_action_trunc), 2533 [OVS_ACTION_ATTR_TRUNC] = sizeof(struct ovs_action_trunc),
2532 [OVS_ACTION_ATTR_PUSH_ETH] = sizeof(struct ovs_action_push_eth), 2534 [OVS_ACTION_ATTR_PUSH_ETH] = sizeof(struct ovs_action_push_eth),
2533 [OVS_ACTION_ATTR_POP_ETH] = 0, 2535 [OVS_ACTION_ATTR_POP_ETH] = 0,
@@ -2669,6 +2671,9 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
2669 skip_copy = true; 2671 skip_copy = true;
2670 break; 2672 break;
2671 2673
2674 case OVS_ACTION_ATTR_CT_CLEAR:
2675 break;
2676
2672 case OVS_ACTION_ATTR_PUSH_ETH: 2677 case OVS_ACTION_ATTR_PUSH_ETH:
2673 /* Disallow pushing an Ethernet header if one 2678 /* Disallow pushing an Ethernet header if one
2674 * is already present */ 2679 * is already present */