openvswitch: Set mark and labels before confirming.
authorJarno Rajahalme <jarno@ovn.org>
Tue, 21 Jun 2016 21:59:37 +0000 (14:59 -0700)
committerDavid S. Miller <davem@davemloft.net>
Sat, 25 Jun 2016 15:55:51 +0000 (11:55 -0400)
Set conntrack mark and labels right before committing so that
the initial conntrack NEW event has the mark and labels.

Signed-off-by: Jarno Rajahalme <jarno@ovn.org>
Acked-by: Joe Stringer <joe@ovn.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/openvswitch/conntrack.c

index 3d5feede962dc584408e9b5a79e4b723f5308319..23fd4fbd11e27058f7d9c0427f414f664539c256 100644 (file)
@@ -824,23 +824,6 @@ static int ovs_ct_lookup(struct net *net, struct sw_flow_key *key,
        return 0;
 }
 
-/* Lookup connection and confirm if unconfirmed. */
-static int ovs_ct_commit(struct net *net, struct sw_flow_key *key,
-                        const struct ovs_conntrack_info *info,
-                        struct sk_buff *skb)
-{
-       int err;
-
-       err = __ovs_ct_lookup(net, key, info, skb);
-       if (err)
-               return err;
-       /* This is a no-op if the connection has already been confirmed. */
-       if (nf_conntrack_confirm(skb) != NF_ACCEPT)
-               return -EINVAL;
-
-       return 0;
-}
-
 static bool labels_nonzero(const struct ovs_key_ct_labels *labels)
 {
        size_t i;
@@ -873,21 +856,33 @@ int ovs_ct_execute(struct net *net, struct sk_buff *skb,
        }
 
        if (info->commit)
-               err = ovs_ct_commit(net, key, info, skb);
+               err = __ovs_ct_lookup(net, key, info, skb);
        else
                err = ovs_ct_lookup(net, key, info, skb);
        if (err)
                goto err;
 
+       /* Apply changes before confirming the connection so that the initial
+        * conntrack NEW netlink event carries the values given in the CT
+        * action.
+        */
        if (info->mark.mask) {
                err = ovs_ct_set_mark(skb, key, info->mark.value,
                                      info->mark.mask);
                if (err)
                        goto err;
        }
-       if (labels_nonzero(&info->labels.mask))
+       if (labels_nonzero(&info->labels.mask)) {
                err = ovs_ct_set_labels(skb, key, &info->labels.value,
                                        &info->labels.mask);
+               if (err)
+                       goto err;
+       }
+       /* This will take care of sending queued events even if the connection
+        * is already confirmed.
+        */
+       if (info->commit && nf_conntrack_confirm(skb) != NF_ACCEPT)
+               err = -EINVAL;
 err:
        skb_push(skb, nh_ofs);
        if (err)