summaryrefslogtreecommitdiffstats
path: root/net/openvswitch/conntrack.c
diff options
context:
space:
mode:
authorJarno Rajahalme <jarno@ovn.org>2016-06-21 17:59:38 -0400
committerDavid S. Miller <davem@davemloft.net>2016-06-25 11:55:51 -0400
commit7d904c7bcd51f72579c0c3134a50896c5a3efb9f (patch)
tree6c37dd06d6890378e1a48221e09fa42980fd3d08 /net/openvswitch/conntrack.c
parent1c1779fa54b2a9d4e1de990095d790d64b9e00a1 (diff)
openvswitch: Only set mark and labels with a commit flag.
Only set conntrack mark or labels when the commit flag is specified. This makes sure we can not set them before the connection has been persisted, as in that case the mark and labels would be lost in an event of an userspace upcall. OVS userspace already requires the commit flag to accept setting ct_mark and/or ct_labels. Validate for this in the kernel API. Signed-off-by: Jarno Rajahalme <jarno@ovn.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/openvswitch/conntrack.c')
-rw-r--r--net/openvswitch/conntrack.c76
1 files changed, 51 insertions, 25 deletions
diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c
index 23fd4fbd11e2..52f3b9b89e97 100644
--- a/net/openvswitch/conntrack.c
+++ b/net/openvswitch/conntrack.c
@@ -835,6 +835,42 @@ static bool labels_nonzero(const struct ovs_key_ct_labels *labels)
835 return false; 835 return false;
836} 836}
837 837
838/* Lookup connection and confirm if unconfirmed. */
839static int ovs_ct_commit(struct net *net, struct sw_flow_key *key,
840 const struct ovs_conntrack_info *info,
841 struct sk_buff *skb)
842{
843 int err;
844
845 err = __ovs_ct_lookup(net, key, info, skb);
846 if (err)
847 return err;
848
849 /* Apply changes before confirming the connection so that the initial
850 * conntrack NEW netlink event carries the values given in the CT
851 * action.
852 */
853 if (info->mark.mask) {
854 err = ovs_ct_set_mark(skb, key, info->mark.value,
855 info->mark.mask);
856 if (err)
857 return err;
858 }
859 if (labels_nonzero(&info->labels.mask)) {
860 err = ovs_ct_set_labels(skb, key, &info->labels.value,
861 &info->labels.mask);
862 if (err)
863 return err;
864 }
865 /* This will take care of sending queued events even if the connection
866 * is already confirmed.
867 */
868 if (nf_conntrack_confirm(skb) != NF_ACCEPT)
869 return -EINVAL;
870
871 return 0;
872}
873
838/* Returns 0 on success, -EINPROGRESS if 'skb' is stolen, or other nonzero 874/* Returns 0 on success, -EINPROGRESS if 'skb' is stolen, or other nonzero
839 * value if 'skb' is freed. 875 * value if 'skb' is freed.
840 */ 876 */
@@ -856,34 +892,10 @@ int ovs_ct_execute(struct net *net, struct sk_buff *skb,
856 } 892 }
857 893
858 if (info->commit) 894 if (info->commit)
859 err = __ovs_ct_lookup(net, key, info, skb); 895 err = ovs_ct_commit(net, key, info, skb);
860 else 896 else
861 err = ovs_ct_lookup(net, key, info, skb); 897 err = ovs_ct_lookup(net, key, info, skb);
862 if (err)
863 goto err;
864 898
865 /* Apply changes before confirming the connection so that the initial
866 * conntrack NEW netlink event carries the values given in the CT
867 * action.
868 */
869 if (info->mark.mask) {
870 err = ovs_ct_set_mark(skb, key, info->mark.value,
871 info->mark.mask);
872 if (err)
873 goto err;
874 }
875 if (labels_nonzero(&info->labels.mask)) {
876 err = ovs_ct_set_labels(skb, key, &info->labels.value,
877 &info->labels.mask);
878 if (err)
879 goto err;
880 }
881 /* This will take care of sending queued events even if the connection
882 * is already confirmed.
883 */
884 if (info->commit && nf_conntrack_confirm(skb) != NF_ACCEPT)
885 err = -EINVAL;
886err:
887 skb_push(skb, nh_ofs); 899 skb_push(skb, nh_ofs);
888 if (err) 900 if (err)
889 kfree_skb(skb); 901 kfree_skb(skb);
@@ -1140,6 +1152,20 @@ static int parse_ct(const struct nlattr *attr, struct ovs_conntrack_info *info,
1140 } 1152 }
1141 } 1153 }
1142 1154
1155#ifdef CONFIG_NF_CONNTRACK_MARK
1156 if (!info->commit && info->mark.mask) {
1157 OVS_NLERR(log,
1158 "Setting conntrack mark requires 'commit' flag.");
1159 return -EINVAL;
1160 }
1161#endif
1162#ifdef CONFIG_NF_CONNTRACK_LABELS
1163 if (!info->commit && labels_nonzero(&info->labels.mask)) {
1164 OVS_NLERR(log,
1165 "Setting conntrack labels requires 'commit' flag.");
1166 return -EINVAL;
1167 }
1168#endif
1143 if (rem > 0) { 1169 if (rem > 0) {
1144 OVS_NLERR(log, "Conntrack attr has %d unknown bytes", rem); 1170 OVS_NLERR(log, "Conntrack attr has %d unknown bytes", rem);
1145 return -EINVAL; 1171 return -EINVAL;