[libnetfilter_conntrack] API: use of __builtin_expect in error checking paths

Pablo Neira netfilter-cvslog-bounces at lists.netfilter.org
Thu Oct 30 13:26:33 CET 2008


Gitweb:		http://git.netfilter.org/cgi-bin/gitweb.cgi?p=libnetfilter_conntrack.git;a=commit;h=83ee97498db28cb3e092f26f1a9169fbff1b1c6e
commit 83ee97498db28cb3e092f26f1a9169fbff1b1c6e
Author:     Pablo Neira Ayuso <pablo at netfilter.org>
AuthorDate: Thu Oct 30 13:24:13 2008 +0100
Commit:     Pablo Neira Ayuso <pablo at netfilter.org>
CommitDate: Thu Oct 30 13:24:13 2008 +0100

    API: use of __builtin_expect in error checking paths
    
    This patch introduces likely() and unlikely() that use
    __builtin_expect to assist the compiler in the branch decisions.
    I am assuming that we have no clients of libnetfilter_conntrack
    that use gcc < 2.96.
    
    Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>

commit 93c459d603cc7a3d9cadeb0844364d5e59aa267c
Author:     Pablo Neira Ayuso <pablo at netfilter.org>
AuthorDate: Thu Oct 30 11:54:30 2008 +0100
Commit:     Pablo Neira Ayuso <pablo at netfilter.org>
CommitDate: Thu Oct 30 11:54:30 2008 +0100

    objopt: use indirect calls instead of switch
    
    This patch replaces the use of switch by indirect function calls.
    
    Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>
       via  83ee97498db28cb3e092f26f1a9169fbff1b1c6e (commit)
       via  93c459d603cc7a3d9cadeb0844364d5e59aa267c (commit)
      from  6dd45b13115d77860a8e3b37caa1560cbcfd265c (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 83ee97498db28cb3e092f26f1a9169fbff1b1c6e
Author: Pablo Neira Ayuso <pablo at netfilter.org>
Date:   Thu Oct 30 13:24:13 2008 +0100

    API: use of __builtin_expect in error checking paths
    
    This patch introduces likely() and unlikely() that use
    __builtin_expect to assist the compiler in the branch decisions.
    I am assuming that we have no clients of libnetfilter_conntrack
    that use gcc < 2.96.
    
    Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>

commit 93c459d603cc7a3d9cadeb0844364d5e59aa267c
Author: Pablo Neira Ayuso <pablo at netfilter.org>
Date:   Thu Oct 30 11:54:30 2008 +0100

    objopt: use indirect calls instead of switch
    
    This patch replaces the use of switch by indirect function calls.
    
    Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>

-----------------------------------------------------------------------

 include/internal/internal.h |    3 +
 include/internal/types.h    |    2 +
 src/conntrack/api.c         |   16 ++--
 src/conntrack/objopt.c      |  162 ++++++++++++++++++++++++++-----------------
 4 files changed, 112 insertions(+), 71 deletions(-)
This patch replaces the use of switch by indirect function calls.

Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>

diff --git a/include/internal/types.h b/include/internal/types.h
index a13722c..790bf7a 100644
--- a/include/internal/types.h
+++ b/include/internal/types.h
@@ -11,6 +11,8 @@ typedef void (*set_attr)(struct nf_conntrack *ct, const void *value);
 typedef const void *(*get_attr)(const struct nf_conntrack *ct);
 typedef void (*copy_attr)(struct nf_conntrack *d, const struct nf_conntrack *o);
 typedef void (*filter_attr)(struct nfct_filter *filter, const void *value);
+typedef int (*getobjopt)(const struct nf_conntrack *ct);
+typedef void (*setobjopt)(struct nf_conntrack *ct);
 
 /*
  * expectation types
diff --git a/src/conntrack/objopt.c b/src/conntrack/objopt.c
index 709bd2f..822215f 100644
--- a/src/conntrack/objopt.c
+++ b/src/conntrack/objopt.c
@@ -28,75 +28,111 @@ static void __autocomplete(struct nf_conntrack *ct, int dir)
         ct->set[0] |= TS_ORIG | TS_REPL;
 }
 
-int __setobjopt(struct nf_conntrack *ct, unsigned int option)
+static void setobjopt_undo_snat(struct nf_conntrack *ct)
 {
-	switch(option) {
-	case NFCT_SOPT_UNDO_SNAT:
-		ct->snat.min_ip = ct->tuple[__DIR_REPL].dst.v4;
-		ct->snat.max_ip = ct->snat.min_ip;
-		ct->tuple[__DIR_REPL].dst.v4 = ct->tuple[__DIR_ORIG].src.v4;
-		set_bit(ATTR_SNAT_IPV4, ct->set);
-		break;
-	case NFCT_SOPT_UNDO_DNAT:
-		ct->dnat.min_ip = ct->tuple[__DIR_REPL].src.v4;
-		ct->dnat.max_ip = ct->dnat.min_ip;
-		ct->tuple[__DIR_REPL].src.v4 = ct->tuple[__DIR_ORIG].dst.v4;
-		set_bit(ATTR_DNAT_IPV4, ct->set);
-		break;
-	case NFCT_SOPT_UNDO_SPAT:
-		ct->snat.l4min.all = ct->tuple[__DIR_REPL].l4dst.tcp.port;
-		ct->snat.l4max.all = ct->snat.l4max.all;
-		ct->tuple[__DIR_REPL].l4dst.tcp.port = 
+	ct->snat.min_ip = ct->tuple[__DIR_REPL].dst.v4;
+	ct->snat.max_ip = ct->snat.min_ip;
+	ct->tuple[__DIR_REPL].dst.v4 = ct->tuple[__DIR_ORIG].src.v4;
+	set_bit(ATTR_SNAT_IPV4, ct->set);
+}
+
+static void setobjopt_undo_dnat(struct nf_conntrack *ct)
+{
+	ct->dnat.min_ip = ct->tuple[__DIR_REPL].src.v4;
+	ct->dnat.max_ip = ct->dnat.min_ip;
+	ct->tuple[__DIR_REPL].src.v4 = ct->tuple[__DIR_ORIG].dst.v4;
+	set_bit(ATTR_DNAT_IPV4, ct->set);
+}
+
+static void setobjopt_undo_spat(struct nf_conntrack *ct)
+{
+	ct->snat.l4min.all = ct->tuple[__DIR_REPL].l4dst.tcp.port;
+	ct->snat.l4max.all = ct->snat.l4max.all;
+	ct->tuple[__DIR_REPL].l4dst.tcp.port =
 			ct->tuple[__DIR_ORIG].l4src.tcp.port;
-		set_bit(ATTR_SNAT_PORT, ct->set);
-		break;
-	case NFCT_SOPT_UNDO_DPAT:
-		ct->dnat.l4min.all = ct->tuple[__DIR_REPL].l4src.tcp.port;
-		ct->dnat.l4max.all = ct->dnat.l4min.all;
-		ct->tuple[__DIR_REPL].l4src.tcp.port =
+	set_bit(ATTR_SNAT_PORT, ct->set);
+}
+
+static void setobjopt_undo_dpat(struct nf_conntrack *ct)
+{
+	ct->dnat.l4min.all = ct->tuple[__DIR_REPL].l4src.tcp.port;
+	ct->dnat.l4max.all = ct->dnat.l4min.all;
+	ct->tuple[__DIR_REPL].l4src.tcp.port =
 			ct->tuple[__DIR_ORIG].l4dst.tcp.port;
-		set_bit(ATTR_DNAT_PORT, ct->set);
-		break;
-	case NFCT_SOPT_SETUP_ORIGINAL:
-		__autocomplete(ct, __DIR_ORIG);
-		break;
-	case NFCT_SOPT_SETUP_REPLY:
-		__autocomplete(ct, __DIR_REPL);
-		break;
-	}
+	set_bit(ATTR_DNAT_PORT, ct->set);
+}
+
+static void setobjopt_setup_orig(struct nf_conntrack *ct)
+{
+	__autocomplete(ct, __DIR_ORIG);
+}
+
+static void setobjopt_setup_repl(struct nf_conntrack *ct)
+{
+	__autocomplete(ct, __DIR_REPL);
+}
+
+setobjopt setobjopt_array[] = {
+	[NFCT_SOPT_UNDO_SNAT] 		= setobjopt_undo_snat,
+	[NFCT_SOPT_UNDO_DNAT] 		= setobjopt_undo_dnat,
+	[NFCT_SOPT_UNDO_SPAT] 		= setobjopt_undo_spat,
+	[NFCT_SOPT_UNDO_DPAT] 		= setobjopt_undo_dpat,
+	[NFCT_SOPT_SETUP_ORIGINAL] 	= setobjopt_setup_orig,
+	[NFCT_SOPT_SETUP_REPLY]		= setobjopt_setup_repl,
+};
+
+int __setobjopt(struct nf_conntrack *ct, unsigned int option)
+{
+	if (option > NFCT_SOPT_MAX)
+		return -1;
+
+	setobjopt_array[option](ct);
 	return 0;
 }
 
+static int getobjopt_is_snat(const struct nf_conntrack *ct)
+{
+	return ((test_bit(ATTR_STATUS, ct->set) ?
+		ct->status & IPS_SRC_NAT_DONE : 1) &&
+		ct->tuple[__DIR_REPL].dst.v4 != 
+		ct->tuple[__DIR_ORIG].src.v4);
+}
+
+static int getobjopt_is_dnat(const struct nf_conntrack *ct)
+{
+	return ((test_bit(ATTR_STATUS, ct->set) ?
+		ct->status & IPS_DST_NAT_DONE : 1) &&
+		ct->tuple[__DIR_REPL].src.v4 !=
+		ct->tuple[__DIR_ORIG].dst.v4);
+}
+
+static int getobjopt_is_spat(const struct nf_conntrack *ct)
+{
+	return ((test_bit(ATTR_STATUS, ct->set) ?
+		ct->status & IPS_SRC_NAT_DONE : 1) &&
+		ct->tuple[__DIR_REPL].l4dst.tcp.port !=
+		ct->tuple[__DIR_ORIG].l4src.tcp.port);
+}
+
+static int getobjopt_is_dpat(const struct nf_conntrack *ct)
+{
+	return ((test_bit(ATTR_STATUS, ct->set) ?
+		ct->status & IPS_DST_NAT_DONE : 1) &&
+		ct->tuple[__DIR_REPL].l4src.tcp.port !=
+		ct->tuple[__DIR_ORIG].l4dst.tcp.port);
+}
+
+getobjopt getobjopt_array[] = {
+	[NFCT_GOPT_IS_SNAT] = getobjopt_is_snat,
+	[NFCT_GOPT_IS_DNAT] = getobjopt_is_dnat,
+	[NFCT_GOPT_IS_SPAT] = getobjopt_is_spat,
+	[NFCT_GOPT_IS_DPAT] = getobjopt_is_dpat,
+};
+
 int __getobjopt(const struct nf_conntrack *ct, unsigned int option)
 {
-	int ret = -1;
-
-	switch(option) {
-	case NFCT_GOPT_IS_SNAT:
-		ret = ((test_bit(ATTR_STATUS, ct->set) ? 
-		        ct->status & IPS_SRC_NAT_DONE : 1) &&
-		       ct->tuple[__DIR_REPL].dst.v4 != 
-		       ct->tuple[__DIR_ORIG].src.v4);
-		break;
-	case NFCT_GOPT_IS_DNAT:
-		ret = ((test_bit(ATTR_STATUS, ct->set) ? 
-		        ct->status & IPS_DST_NAT_DONE : 1) &&
-		       ct->tuple[__DIR_REPL].src.v4 !=
-		       ct->tuple[__DIR_ORIG].dst.v4);
-		break;
-	case NFCT_GOPT_IS_SPAT:
-		ret = ((test_bit(ATTR_STATUS, ct->set) ? 
-		        ct->status & IPS_SRC_NAT_DONE : 1) &&
-		       ct->tuple[__DIR_REPL].l4dst.tcp.port !=
-		       ct->tuple[__DIR_ORIG].l4src.tcp.port);
-		break;
-	case NFCT_GOPT_IS_DPAT:
-		ret = ((test_bit(ATTR_STATUS, ct->set) ? 
-		        ct->status & IPS_DST_NAT_DONE : 1) &&
-		       ct->tuple[__DIR_REPL].l4src.tcp.port !=
-		       ct->tuple[__DIR_ORIG].l4dst.tcp.port);
-		break;
-	}
-
-	return ret;
+	if (option > NFCT_GOPT_MAX)
+		return -1;
+
+	return getobjopt_array[option](ct);
 }



More information about the netfilter-cvslog mailing list