[ovs-dev] [PATCH 1/2] datapath: Support a fixed size of 128 distinct labels.

Jarno Rajahalme jarno at ovn.org
Wed Oct 19 00:01:10 UTC 2016


Port upstream change in conntrack labels extension.  Add a new
configure macro HAVE_NF_CONN_LABELS_WITH_WORDS to detect the old
definition.  Unfortunately there is no conntrack API to hide the
difference, so the this makes conntrack.c deviate from upstream source
a bit.

Upstream commit:
    commit 23014011ba4209a086931ff402eac1c41abbe456
    Author: Florian Westphal <fw at strlen.de>
    Date:   Thu Jul 21 12:51:16 2016 +0200

    netfilter: conntrack: support a fixed size of 128 distinct labels

    The conntrack label extension is currently variable-sized, e.g. if
    only 2 labels are used by iptables rules then the labels->bits[] array
    will only contain one element.

    We track size of each label storage area in the 'words' member.

    But in nftables and openvswitch we always have to ask for worst-case
    since we don't know what bit will be used at configuration time.

    As most arches are 64bit we need to allocate 24 bytes in this case:

    struct nf_conn_labels {
        u8            words;   /*     0     1 */
        /* XXX 7 bytes hole, try to pack */
        long unsigned bits[2]; /*     8     24 */

    Make bits a fixed size and drop the words member, it simplifies
    the code and only increases memory requirements on x86 when
    less than 64bit labels are required.

    We still only allocate the extension if its needed.

    Signed-off-by: Florian Westphal <fw at strlen.de>
    Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>

Signed-off-by: Jarno Rajahalme <jarno at ovn.org>
---
 acinclude.m4         |  2 ++
 datapath/conntrack.c | 14 ++++++++++++--
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/acinclude.m4 b/acinclude.m4
index 353519d..a3c95f5 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -529,6 +529,8 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
   OVS_FIND_PARAM_IFELSE([$KSRC/include/net/netfilter/nf_conntrack_labels.h],
                   [nf_connlabels_get], [int bit],
                   [OVS_DEFINE([HAVE_NF_CONNLABELS_GET_TAKES_BIT])])
+  OVS_FIND_FIELD_IFELSE([$KSRC/include/net/netfilter/nf_conntrack_labels.h],
+                        [nf_conn_labels], [words])
   OVS_GREP_IFELSE([$KSRC/include/net/netfilter/ipv6/nf_defrag_ipv6.h],
                   [nf_ct_frag6_consume_orig])
   OVS_GREP_IFELSE([$KSRC/include/net/netfilter/ipv6/nf_defrag_ipv6.h],
diff --git a/datapath/conntrack.c b/datapath/conntrack.c
index a2fc450..6e722b6 100644
--- a/datapath/conntrack.c
+++ b/datapath/conntrack.c
@@ -136,13 +136,22 @@ static u32 ovs_ct_get_mark(const struct nf_conn *ct)
 #endif
 }
 
+static size_t ovs_ct_get_labels_len(struct nf_conn_labels *cl)
+{
+#ifdef HAVE_NF_CONN_LABELS_WITH_WORDS
+	return cl->words * sizeof(long);
+#else
+	return sizeof(cl->bits);
+#endif
+}
+
 static void ovs_ct_get_labels(const struct nf_conn *ct,
 			      struct ovs_key_ct_labels *labels)
 {
 	struct nf_conn_labels *cl = ct ? nf_ct_labels_find(ct) : NULL;
 
 	if (cl) {
-		size_t len = cl->words * sizeof(long);
+		size_t len = ovs_ct_get_labels_len(cl);
 
 		if (len > OVS_CT_LABELS_LEN)
 			len = OVS_CT_LABELS_LEN;
@@ -281,7 +290,8 @@ static int ovs_ct_set_labels(struct sk_buff *skb, struct sw_flow_key *key,
 		nf_ct_labels_ext_add(ct);
 		cl = nf_ct_labels_find(ct);
 	}
-	if (!cl || cl->words * sizeof(long) < OVS_CT_LABELS_LEN)
+
+	if (!cl || ovs_ct_get_labels_len(cl) < OVS_CT_LABELS_LEN)
 		return -ENOSPC;
 
 	err = nf_connlabels_replace(ct, (u32 *)labels, (u32 *)mask,
-- 
2.1.4




More information about the dev mailing list