summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2012-04-29 23:43:04 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2012-04-29 23:43:04 +0200
commitd5b8311d81719f90a8f8d7f0b85ad320b9d7a0cd (patch)
tree21f97e4d1a53d35ded02a35c6fd587265ddff897
parent096567100178c1f2d49b0d3e7764e665d547c3fa (diff)
conntrack: fix new ATTR_GRP_[ORIG|REPL]_ADDR_[SRC|DST]
The previous patch was incomplete. This fixes several issues with it like the IPV4 and IPV6 address are mutually exclusive, thus, the getter operation works. No sane way to support the setter operation correctly, thus, it's been documented that it has no effect. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--include/internal/bitops.h13
-rw-r--r--include/internal/extern.h5
-rw-r--r--include/internal/internal.h3
-rw-r--r--src/conntrack/api.c48
-rw-r--r--src/conntrack/grp.c101
-rw-r--r--src/conntrack/grp_setter.c36
6 files changed, 125 insertions, 81 deletions
diff --git a/include/internal/bitops.h b/include/internal/bitops.h
index 0c1fde8..7ae566b 100644
--- a/include/internal/bitops.h
+++ b/include/internal/bitops.h
@@ -60,4 +60,17 @@ test_bitmask_u32(const uint32_t *buf1, const uint32_t *buf2, int len)
return 1;
}
+static inline int
+test_bitmask_u32_or(const uint32_t *buf1, const uint32_t *buf2, int len)
+{
+ int i;
+
+ for (i=0; i<len; i++) {
+ if (buf1[i] & buf2[i]) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
#endif
diff --git a/include/internal/extern.h b/include/internal/extern.h
index fb9ca54..405c9ca 100644
--- a/include/internal/extern.h
+++ b/include/internal/extern.h
@@ -11,7 +11,10 @@ extern const get_attr_grp get_attr_grp_array[];
extern const set_exp_attr set_exp_attr_array[];
extern const get_exp_attr get_exp_attr_array[];
-extern const uint32_t attr_grp_bitmask[ATTR_GRP_MAX][__NFCT_BITSET];
+extern const struct attr_grp_bitmask {
+ uint32_t bitmask[__NFCT_BITSET];
+ uint32_t type;
+} attr_grp_bitmask[ATTR_GRP_MAX];
extern const set_filter_dump_attr set_filter_dump_attr_array[];
diff --git a/include/internal/internal.h b/include/internal/internal.h
index b2b1c43..aaf6bd4 100644
--- a/include/internal/internal.h
+++ b/include/internal/internal.h
@@ -82,4 +82,7 @@ struct nf_ct_tcp_flags {
u_int8_t mask;
};
+#define NFCT_BITMASK_AND 0
+#define NFCT_BITMASK_OR 1
+
#endif
diff --git a/src/conntrack/api.c b/src/conntrack/api.c
index 683b2ce..202b85d 100644
--- a/src/conntrack/api.c
+++ b/src/conntrack/api.c
@@ -601,8 +601,8 @@ int nfct_attr_unset(struct nf_conntrack *ct,
* \param type attribute group (see ATTR_GRP_*)
* \param data pointer to struct (see struct nfct_attr_grp_*)
*
- * Note that calling this function for ATTR_GRP_COUNTER_* does nothing since
- * counters are unsettable.
+ * Note that calling this function for ATTR_GRP_COUNTER_* and ATTR_GRP_ADDR_*
+ * have no effect.
*/
void nfct_set_attr_grp(struct nf_conntrack *ct,
const enum nf_conntrack_attr_grp type,
@@ -615,7 +615,8 @@ void nfct_set_attr_grp(struct nf_conntrack *ct,
if (set_attr_grp_array[type]) {
set_attr_grp_array[type](ct, data);
- set_bitmask_u32(ct->head.set, attr_grp_bitmask[type], __NFCT_BITSET);
+ set_bitmask_u32(ct->head.set,
+ attr_grp_bitmask[type].bitmask, __NFCT_BITSET);
}
}
@@ -638,9 +639,23 @@ int nfct_get_attr_grp(const struct nf_conntrack *ct,
errno = EINVAL;
return -1;
}
- if (!test_bitmask_u32(ct->head.set, attr_grp_bitmask[type], __NFCT_BITSET)) {
- errno = ENODATA;
- return -1;
+ switch(attr_grp_bitmask[type].type) {
+ case NFCT_BITMASK_AND:
+ if (!test_bitmask_u32(ct->head.set,
+ attr_grp_bitmask[type].bitmask,
+ __NFCT_BITSET)) {
+ errno = ENODATA;
+ return -1;
+ }
+ break;
+ case NFCT_BITMASK_OR:
+ if (!test_bitmask_u32_or(ct->head.set,
+ attr_grp_bitmask[type].bitmask,
+ __NFCT_BITSET)) {
+ errno = ENODATA;
+ return -1;
+ }
+ break;
}
assert(get_attr_grp_array[type]);
get_attr_grp_array[type](ct, data);
@@ -663,7 +678,23 @@ int nfct_attr_grp_is_set(const struct nf_conntrack *ct,
errno = EINVAL;
return -1;
}
- return test_bitmask_u32(ct->head.set, attr_grp_bitmask[type], __NFCT_BITSET);
+ switch(attr_grp_bitmask[type].type) {
+ case NFCT_BITMASK_AND:
+ if (test_bitmask_u32(ct->head.set,
+ attr_grp_bitmask[type].bitmask,
+ __NFCT_BITSET)) {
+ return 1;
+ }
+ break;
+ case NFCT_BITMASK_OR:
+ if (test_bitmask_u32_or(ct->head.set,
+ attr_grp_bitmask[type].bitmask,
+ __NFCT_BITSET)) {
+ return 1;
+ }
+ break;
+ }
+ return 0;
}
/**
@@ -683,7 +714,8 @@ int nfct_attr_grp_unset(struct nf_conntrack *ct,
errno = EINVAL;
return -1;
}
- unset_bitmask_u32(ct->head.set, attr_grp_bitmask[type], __NFCT_BITSET);
+ unset_bitmask_u32(ct->head.set, attr_grp_bitmask[type].bitmask,
+ __NFCT_BITSET);
return 0;
}
diff --git a/src/conntrack/grp.c b/src/conntrack/grp.c
index 92a523b..e971a33 100644
--- a/src/conntrack/grp.c
+++ b/src/conntrack/grp.c
@@ -1,5 +1,5 @@
/*
- * (C) 2005-2011 by Pablo Neira Ayuso <pablo@netfilter.org>
+ * (C) 2005-2012 by Pablo Neira Ayuso <pablo@netfilter.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
@@ -9,75 +9,96 @@
#include "internal/internal.h"
-const uint32_t attr_grp_bitmask[ATTR_GRP_MAX][__NFCT_BITSET] = {
+const struct attr_grp_bitmask attr_grp_bitmask[ATTR_GRP_MAX]= {
[ATTR_GRP_ORIG_IPV4] = {
- [0] = (1 << ATTR_ORIG_IPV4_SRC) |
- (1 << ATTR_ORIG_IPV4_DST) |
- (1 << ATTR_ORIG_L3PROTO),
+ .bitmask[0] = (1 << ATTR_ORIG_IPV4_SRC) |
+ (1 << ATTR_ORIG_IPV4_DST) |
+ (1 << ATTR_ORIG_L3PROTO),
+ .type = NFCT_BITMASK_AND,
},
[ATTR_GRP_REPL_IPV4] = {
- [0] = (1 << ATTR_REPL_IPV4_SRC) |
- (1 << ATTR_REPL_IPV4_DST) |
- (1 << ATTR_REPL_L3PROTO),
+ .bitmask[0] = (1 << ATTR_REPL_IPV4_SRC) |
+ (1 << ATTR_REPL_IPV4_DST) |
+ (1 << ATTR_REPL_L3PROTO),
+ .type = NFCT_BITMASK_AND,
},
[ATTR_GRP_ORIG_IPV6] = {
- [0] = (1 << ATTR_ORIG_IPV6_SRC) |
- (1 << ATTR_ORIG_IPV6_DST) |
- (1 << ATTR_ORIG_L3PROTO),
+ .bitmask[0] = (1 << ATTR_ORIG_IPV6_SRC) |
+ (1 << ATTR_ORIG_IPV6_DST) |
+ (1 << ATTR_ORIG_L3PROTO),
+ .type = NFCT_BITMASK_AND,
},
[ATTR_GRP_REPL_IPV6] = {
- [0] = (1 << ATTR_REPL_IPV6_SRC) |
- (1 << ATTR_REPL_IPV6_DST) |
- (1 << ATTR_REPL_L3PROTO),
+ .bitmask[0] = (1 << ATTR_REPL_IPV6_SRC) |
+ (1 << ATTR_REPL_IPV6_DST) |
+ (1 << ATTR_REPL_L3PROTO),
+ .type = NFCT_BITMASK_AND,
},
[ATTR_GRP_ORIG_PORT] = {
- [0] = (1 << ATTR_ORIG_PORT_SRC) |
- (1 << ATTR_ORIG_PORT_DST) |
- (1 << ATTR_ORIG_L4PROTO),
+ .bitmask[0] = (1 << ATTR_ORIG_PORT_SRC) |
+ (1 << ATTR_ORIG_PORT_DST) |
+ (1 << ATTR_ORIG_L4PROTO),
+ .type = NFCT_BITMASK_AND,
},
[ATTR_GRP_REPL_PORT] = {
- [0] = (1 << ATTR_REPL_PORT_SRC) |
- (1 << ATTR_REPL_PORT_DST) |
- (1 << ATTR_REPL_L4PROTO),
+ .bitmask[0] = (1 << ATTR_REPL_PORT_SRC) |
+ (1 << ATTR_REPL_PORT_DST) |
+ (1 << ATTR_REPL_L4PROTO),
+ .type = NFCT_BITMASK_AND,
},
[ATTR_GRP_ICMP] = {
- [0] = (1 << ATTR_ICMP_CODE) |
- (1 << ATTR_ICMP_TYPE) |
- (1 << ATTR_ICMP_ID),
+ .bitmask[0] = (1 << ATTR_ICMP_CODE) |
+ (1 << ATTR_ICMP_TYPE) |
+ (1 << ATTR_ICMP_ID),
+ .type = NFCT_BITMASK_AND,
},
[ATTR_GRP_MASTER_IPV4] = {
- [1] = (1 << (ATTR_MASTER_IPV4_SRC - 32)) |
- (1 << (ATTR_MASTER_IPV4_DST - 32)) |
- (1 << (ATTR_MASTER_L3PROTO - 32)),
+ .bitmask[1] = (1 << (ATTR_MASTER_IPV4_SRC - 32)) |
+ (1 << (ATTR_MASTER_IPV4_DST - 32)) |
+ (1 << (ATTR_MASTER_L3PROTO - 32)),
+ .type = NFCT_BITMASK_AND,
},
[ATTR_GRP_MASTER_IPV6] = {
- [1] = (1 << (ATTR_MASTER_IPV6_SRC - 32)) |
- (1 << (ATTR_MASTER_IPV6_DST - 32)) |
- (1 << (ATTR_MASTER_L3PROTO - 32)),
+ .bitmask[1] = (1 << (ATTR_MASTER_IPV6_SRC - 32)) |
+ (1 << (ATTR_MASTER_IPV6_DST - 32)) |
+ (1 << (ATTR_MASTER_L3PROTO - 32)),
+ .type = NFCT_BITMASK_AND,
},
[ATTR_GRP_MASTER_PORT] = {
- [1] = (1 << (ATTR_MASTER_PORT_SRC - 32)) |
- (1 << (ATTR_MASTER_PORT_DST - 32)) |
- (1 << (ATTR_MASTER_L4PROTO - 32)),
+ .bitmask[1] = (1 << (ATTR_MASTER_PORT_SRC - 32)) |
+ (1 << (ATTR_MASTER_PORT_DST - 32)) |
+ (1 << (ATTR_MASTER_L4PROTO - 32)),
+ .type = NFCT_BITMASK_AND,
},
[ATTR_GRP_ORIG_COUNTERS] = {
- [0] = (1 << (ATTR_ORIG_COUNTER_PACKETS)) |
- (1 << (ATTR_ORIG_COUNTER_BYTES)),
+ .bitmask[0] = (1 << (ATTR_ORIG_COUNTER_PACKETS)) |
+ (1 << (ATTR_ORIG_COUNTER_BYTES)),
+ .type = NFCT_BITMASK_AND,
},
[ATTR_GRP_REPL_COUNTERS] = {
- [0] = (1 << (ATTR_REPL_COUNTER_PACKETS)) |
- (1 << (ATTR_REPL_COUNTER_BYTES)),
+ .bitmask[0] = (1 << (ATTR_REPL_COUNTER_PACKETS)) |
+ (1 << (ATTR_REPL_COUNTER_BYTES)),
+ .type = NFCT_BITMASK_AND,
},
[ATTR_GRP_ORIG_ADDR_SRC] = {
- [0] = (1 << ATTR_ORIG_IPV4_SRC) | (1 << ATTR_ORIG_IPV6_SRC),
+ .bitmask[0] = (1 << ATTR_ORIG_IPV4_SRC) |
+ (1 << ATTR_ORIG_IPV6_SRC),
+ .type = NFCT_BITMASK_OR,
},
[ATTR_GRP_ORIG_ADDR_DST] = {
- [0] = (1 << ATTR_ORIG_IPV4_DST) | (1 << ATTR_ORIG_IPV6_DST),
+ .bitmask[0] = (1 << ATTR_ORIG_IPV4_DST) |
+ (1 << ATTR_ORIG_IPV6_DST),
+ .type = NFCT_BITMASK_OR,
+
},
[ATTR_GRP_REPL_ADDR_SRC] = {
- [1] = (1 << ATTR_REPL_IPV4_SRC) | (1 << ATTR_REPL_IPV6_SRC),
+ .bitmask[0] = (1 << ATTR_REPL_IPV4_SRC) |
+ (1 << ATTR_REPL_IPV6_SRC),
+ .type = NFCT_BITMASK_OR,
},
[ATTR_GRP_REPL_ADDR_DST] = {
- [1] = (1 << ATTR_REPL_IPV4_DST) | (1 << ATTR_REPL_IPV6_DST),
+ .bitmask[0] = (1 << ATTR_REPL_IPV4_DST) |
+ (1 << ATTR_REPL_IPV6_DST),
+ .type = NFCT_BITMASK_OR,
},
};
diff --git a/src/conntrack/grp_setter.c b/src/conntrack/grp_setter.c
index b451eef..0cc5f18 100644
--- a/src/conntrack/grp_setter.c
+++ b/src/conntrack/grp_setter.c
@@ -138,34 +138,6 @@ static void set_attr_grp_master_port(struct nf_conntrack *ct, const void *value)
ct->master.l4dst.all = this->dport;
}
-static void
-set_attr_grp_orig_addr_src(struct nf_conntrack *ct, const void *value)
-{
- const union nfct_attr_grp_addr *this = value;
- memcpy(&ct->head.orig.src, &this->addr, sizeof(&ct->head.orig.src));
-}
-
-static void
-set_attr_grp_orig_addr_dst(struct nf_conntrack *ct, const void *value)
-{
- const union nfct_attr_grp_addr *this = value;
- memcpy(&ct->head.orig.dst, &this->addr, sizeof(&ct->head.orig.src));
-}
-
-static void
-set_attr_grp_repl_addr_src(struct nf_conntrack *ct, const void *value)
-{
- const union nfct_attr_grp_addr *this = value;
- memcpy(&ct->repl.src, &this->addr, sizeof(&ct->repl.src));
-}
-
-static void
-set_attr_grp_repl_addr_dst(struct nf_conntrack *ct, const void *value)
-{
- const union nfct_attr_grp_addr *this = value;
- memcpy(&ct->repl.dst, &this->addr, sizeof(&ct->repl.dst));
-}
-
static void set_attr_grp_do_nothing(struct nf_conntrack *ct, const void *value)
{
}
@@ -183,8 +155,8 @@ const set_attr_grp set_attr_grp_array[ATTR_GRP_MAX] = {
[ATTR_GRP_MASTER_PORT] = set_attr_grp_master_port,
[ATTR_GRP_ORIG_COUNTERS] = set_attr_grp_do_nothing,
[ATTR_GRP_REPL_COUNTERS] = set_attr_grp_do_nothing,
- [ATTR_GRP_ORIG_ADDR_SRC] = set_attr_grp_orig_addr_src,
- [ATTR_GRP_ORIG_ADDR_DST] = set_attr_grp_orig_addr_dst,
- [ATTR_GRP_REPL_ADDR_SRC] = set_attr_grp_repl_addr_src,
- [ATTR_GRP_REPL_ADDR_DST] = set_attr_grp_repl_addr_dst,
+ [ATTR_GRP_ORIG_ADDR_SRC] = set_attr_grp_do_nothing,
+ [ATTR_GRP_ORIG_ADDR_DST] = set_attr_grp_do_nothing,
+ [ATTR_GRP_REPL_ADDR_SRC] = set_attr_grp_do_nothing,
+ [ATTR_GRP_REPL_ADDR_DST] = set_attr_grp_do_nothing,
};