summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2008-10-30 11:54:30 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2008-10-30 11:54:30 +0100
commit93c459d603cc7a3d9cadeb0844364d5e59aa267c (patch)
treeafa00c50d6099637d0cb690f7baf8a126d7e7f08
parent6dd45b13115d77860a8e3b37caa1560cbcfd265c (diff)
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@netfilter.org>
-rw-r--r--include/internal/types.h2
-rw-r--r--src/conntrack/objopt.c162
2 files changed, 101 insertions, 63 deletions
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);
}