summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
author/C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org </C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org>2008-04-08 15:50:42 +0000
committer/C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org </C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org>2008-04-08 15:50:42 +0000
commit92701a6b224c533346f233061226bee5bb29a5dd (patch)
treea54f47f4f49160496768dfef38e07db9dcd36e67
parentc36b87b8562e1d8e7ba4df84daee002f7c2a6dbf (diff)
fix asymmetric path support (still some open concerns)
-rw-r--r--ChangeLog1
-rw-r--r--include/netlink.h4
-rw-r--r--src/cache_wt.c36
-rw-r--r--src/netlink.c31
4 files changed, 68 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 6d94c6a..4bd878b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,7 @@ version 0.9.7 (yet unreleased)
Pablo Neira Ayuso <pablo@netfilter.org>:
o remove .svn directory from make distcheck tarballs (reported by B.Benjamini)
o fix minor compilation issue in amd64 with gcc4.3 (reported by Daniel Schepler)
+o fix asymmetric path support (reported by Gary Richards)
Krzysztof Oledzki <ole@ans.pl>:
o fix minor compilation warning
diff --git a/include/netlink.h b/include/netlink.h
index 543eeda..d345656 100644
--- a/include/netlink.h
+++ b/include/netlink.h
@@ -14,8 +14,12 @@ void nl_resize_socket_buffer(struct nfct_handle *h);
int nl_dump_conntrack_table(void);
+int nl_exist_conntrack(struct nf_conntrack *ct);
+
int nl_create_conntrack(struct nf_conntrack *ct);
+int nl_update_conntrack(struct nf_conntrack *ct);
+
int nl_destroy_conntrack(struct nf_conntrack *ct);
#endif
diff --git a/src/cache_wt.c b/src/cache_wt.c
index 8ff8fae..65eb3fe 100644
--- a/src/cache_wt.c
+++ b/src/cache_wt.c
@@ -16,30 +16,58 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include "conntrackd.h"
#include "cache.h"
#include "netlink.h"
#include "us-conntrack.h"
+#include "log.h"
#include <string.h>
+#include <errno.h>
-static void add_update(struct us_conntrack *u)
+static void add_wt(struct us_conntrack *u)
+{
+ int ret;
+ char __ct[nfct_maxsize()];
+ struct nf_conntrack *ct = (struct nf_conntrack *)(void*) __ct;
+
+ ret = nl_exist_conntrack(u->ct);
+ switch (ret) {
+ case -1:
+ dlog(LOG_ERR, "cache_wt problem: %s", strerror(errno));
+ break;
+ case 0:
+ memcpy(ct, u->ct, nfct_maxsize());
+ if (nl_create_conntrack(ct) == -1)
+ dlog(LOG_ERR, "cache_wt create: %s", strerror(errno));
+ break;
+ case 1:
+ memcpy(ct, u->ct, nfct_maxsize());
+ if (nl_update_conntrack(ct) == -1)
+ dlog(LOG_ERR, "cache_wt crt-upd: %s", strerror(errno));
+ break;
+ }
+}
+
+static void upd_wt(struct us_conntrack *u)
{
char __ct[nfct_maxsize()];
struct nf_conntrack *ct = (struct nf_conntrack *)(void*) __ct;
memcpy(ct, u->ct, nfct_maxsize());
- nl_create_conntrack(ct);
+ if (nl_update_conntrack(ct) == -1)
+ dlog(LOG_ERR, "cache_wt update:%s", strerror(errno));
}
static void writethrough_add(struct us_conntrack *u, void *data)
{
- add_update(u);
+ add_wt(u);
}
static void writethrough_update(struct us_conntrack *u, void *data)
{
- add_update(u);
+ upd_wt(u);
}
static void writethrough_destroy(struct us_conntrack *u, void *data)
diff --git a/src/netlink.c b/src/netlink.c
index f6a2378..1ab75e4 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -23,6 +23,8 @@
#include "log.h"
#include "debug.h"
+#include <errno.h>
+
int ignore_conntrack(struct nf_conntrack *ct)
{
/* ignore a certain protocol */
@@ -193,6 +195,17 @@ int nl_dump_conntrack_table(void)
return nfct_query(STATE(dump), NFCT_Q_DUMP, &CONFIG(family));
}
+int nl_exist_conntrack(struct nf_conntrack *ct)
+{
+ int ret;
+
+ ret = nfct_query(STATE(dump), NFCT_Q_GET, ct);
+ if (ret == -1)
+ return errno == ENOENT ? 0 : -1;
+
+ return 1;
+}
+
/* This function modifies the conntrack passed as argument! */
int nl_create_conntrack(struct nf_conntrack *ct)
{
@@ -219,6 +232,24 @@ int nl_create_conntrack(struct nf_conntrack *ct)
return nfct_query(STATE(dump), NFCT_Q_CREATE_UPDATE, ct);
}
+/* This function modifies the conntrack passed as argument! */
+int nl_update_conntrack(struct nf_conntrack *ct)
+{
+ /* unset NAT info, otherwise we hit error */
+ nfct_attr_unset(ct, ATTR_SNAT_IPV4);
+ nfct_attr_unset(ct, ATTR_DNAT_IPV4);
+ nfct_attr_unset(ct, ATTR_SNAT_PORT);
+ nfct_attr_unset(ct, ATTR_DNAT_PORT);
+
+ if (nfct_attr_is_set(ct, ATTR_STATUS)) {
+ uint32_t status = nfct_get_attr_u32(ct, ATTR_STATUS);
+ status &= ~IPS_NAT_MASK;
+ nfct_set_attr_u32(ct, ATTR_STATUS, status);
+ }
+
+ return nl_create_conntrack(ct);
+}
+
int nl_destroy_conntrack(struct nf_conntrack *ct)
{
return nfct_query(STATE(dump), NFCT_Q_DESTROY, ct);