Skip to content

Commit

Permalink
openvswitch: Do not trigger events for unconfirmed connections.
Browse files Browse the repository at this point in the history
Receiving change events before the 'new' event for the connection has
been received can be confusing.  Avoid triggering change events for
setting conntrack mark or labels before the conntrack entry has been
confirmed.

Fixes: 182e304 ("openvswitch: Allow matching on conntrack mark")
Fixes: c2ac667 ("openvswitch: Allow matching on conntrack label")
Signed-off-by: Jarno Rajahalme <jarno@ovn.org>
Acked-by: Joe Stringer <joe@ovn.org>
Acked-by: Pravin B Shelar <pshelar@ovn.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Jarno Rajahalme authored and David S. Miller committed Feb 10, 2017
1 parent 9ff464d commit 193e309
Showing 1 changed file with 22 additions and 6 deletions.
28 changes: 22 additions & 6 deletions net/openvswitch/conntrack.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,8 @@ static int ovs_ct_set_mark(struct sk_buff *skb, struct sw_flow_key *key,
new_mark = ct_mark | (ct->mark & ~(mask));
if (ct->mark != new_mark) {
ct->mark = new_mark;
nf_conntrack_event_cache(IPCT_MARK, ct);
if (nf_ct_is_confirmed(ct))
nf_conntrack_event_cache(IPCT_MARK, ct);
key->ct.mark = new_mark;
}

Expand All @@ -262,7 +263,6 @@ static int ovs_ct_set_labels(struct sk_buff *skb, struct sw_flow_key *key,
enum ip_conntrack_info ctinfo;
struct nf_conn_labels *cl;
struct nf_conn *ct;
int err;

/* The connection could be invalid, in which case set_label is no-op.*/
ct = nf_ct_get(skb, &ctinfo);
Expand All @@ -277,10 +277,26 @@ static int ovs_ct_set_labels(struct sk_buff *skb, struct sw_flow_key *key,
if (!cl || sizeof(cl->bits) < OVS_CT_LABELS_LEN)
return -ENOSPC;

err = nf_connlabels_replace(ct, (u32 *)labels, (u32 *)mask,
OVS_CT_LABELS_LEN / sizeof(u32));
if (err)
return err;
if (nf_ct_is_confirmed(ct)) {
/* Triggers a change event, which makes sense only for
* confirmed connections.
*/
int err = nf_connlabels_replace(ct, (u32 *)labels, (u32 *)mask,
OVS_CT_LABELS_LEN / sizeof(u32));
if (err)
return err;
} else {
u32 *dst = (u32 *)cl->bits;
const u32 *msk = (const u32 *)mask->ct_labels;
const u32 *lbl = (const u32 *)labels->ct_labels;
int i;

/* No-one else has access to the non-confirmed entry, copy
* labels over, keeping any bits we are not explicitly setting.
*/
for (i = 0; i < OVS_CT_LABELS_LEN / sizeof(u32); i++)
dst[i] = (dst[i] & ~msk[i]) | (lbl[i] & msk[i]);
}

ovs_ct_get_labels(ct, &key->ct.labels);
return 0;
Expand Down

0 comments on commit 193e309

Please sign in to comment.