summaryrefslogtreecommitdiffstats
path: root/src/filter.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2013-07-11 00:43:20 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2013-07-11 02:42:55 +0200
commit586382d9a8389ee553db019fd9be14a8a7c0b8ec (patch)
tree5f00a12a32920319c95c5b0acafff0c9957131f5 /src/filter.c
parent479a37a549abf197ce59a4ae1666d8cba80fe977 (diff)
conntrackd: simplify expectation filtering
This patch simplifies the expectation filtering by looking up for the master conntrack. If it does not exists, then we assume that we don't want this expectation either. This simplification also fixes the current broken expectation filtering, since the master conntrack from expectations has neither reply tuple nor state, however, the filtering code assumes the opposite. This partially reverts (479a37a conntrackd: fix crash with IPv6 expectation in the filtering code) since it was incorrectly setting the reply tuple of the master conntrack. Thanks to Bill Fink for providing feedback to resolve this issue. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/filter.c')
-rw-r--r--src/filter.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/src/filter.c b/src/filter.c
index e21cfde..8fac71b 100644
--- a/src/filter.c
+++ b/src/filter.c
@@ -407,6 +407,51 @@ int ct_filter_conntrack(const struct nf_conntrack *ct, int userspace)
return 0;
}
+static inline int
+ct_filter_master_sanity_check(const struct nf_conntrack *master)
+{
+ if (master == NULL) {
+ dlog(LOG_ERR, "no master tuple in expectation");
+ return 0;
+ }
+
+ if (!nfct_attr_is_set(master, ATTR_L3PROTO)) {
+ dlog(LOG_ERR, "missing layer 3 protocol");
+ return 0;
+ }
+
+ switch (nfct_get_attr_u8(master, ATTR_L3PROTO)) {
+ case AF_INET:
+ if (!nfct_attr_is_set(master, ATTR_IPV4_SRC) ||
+ !nfct_attr_is_set(master, ATTR_IPV4_DST)) {
+ dlog(LOG_ERR, "missing IPv4 address. "
+ "You forgot to load nf_conntrack_ipv4?");
+ return 0;
+ }
+ break;
+ case AF_INET6:
+ if (!nfct_attr_is_set(master, ATTR_IPV6_SRC) ||
+ !nfct_attr_is_set(master, ATTR_IPV6_DST)) {
+ dlog(LOG_ERR, "missing IPv6 address. "
+ "You forgot to load nf_conntrack_ipv6?");
+ return 0;
+ }
+ break;
+ }
+ return 1;
+}
+
+int ct_filter_master(const struct nf_conntrack *master)
+{
+ if (!ct_filter_master_sanity_check(master))
+ return 1;
+
+ /* Check if we've got a master conntrack for this expectation in our
+ * caches. If there is not, we don't want this expectation either.
+ */
+ return STATE(mode)->internal->exp.find(master) ? 0 : 1;
+}
+
struct exp_filter {
struct list_head list;
};