summaryrefslogtreecommitdiffstats
path: root/src/netlink.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2008-12-06 21:54:43 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2008-12-06 21:54:43 +0100
commit65ad316d921930c9d5c1c8640fbf2f05ecd0ca49 (patch)
tree9fc0427a023eaaba9a4619576dc979e2dae51ded /src/netlink.c
parent567222194512c6d42c7e253fc69c3837fe7b078c (diff)
netlink: clone conntrack object while creation/update
This patch changes the behaviour of nl_create_conntrack() and nl_update_conntrack() which now clone the conntrack object received as parameter. This was not required as these functions were called inside fork(), thus, they modified a copy of the real conntrack objects in the child process. However, this behaviour is broken following the try-again logic in __do_commit_step. For example, if we try to update an expected conntrack object that has vanished for whatever reason, since nl_update_conntrack() modifies the object (unset the master conntrack information), nl_create_conntrak() will create an entry without the master conntrack information. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/netlink.c')
-rw-r--r--src/netlink.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/src/netlink.c b/src/netlink.c
index 81ac7a1..1a86a21 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -183,10 +183,15 @@ int nl_get_conntrack(struct nf_conntrack *ct)
return __nl_get_conntrack(STATE(dump), ct);
}
-/* This function modifies the conntrack passed as argument! */
-int nl_create_conntrack(struct nf_conntrack *ct)
+int nl_create_conntrack(const struct nf_conntrack *orig)
{
+ int ret;
uint8_t flags;
+ struct nf_conntrack *ct;
+
+ ct = nfct_clone(orig);
+ if (ct == NULL)
+ return -1;
/* we hit error if we try to change the expected bit */
if (nfct_attr_is_set(ct, ATTR_STATUS)) {
@@ -206,13 +211,21 @@ int nl_create_conntrack(struct nf_conntrack *ct)
nfct_set_attr_u8(ct, ATTR_TCP_FLAGS_REPL, flags);
nfct_set_attr_u8(ct, ATTR_TCP_MASK_REPL, flags);
- return nfct_query(STATE(dump), NFCT_Q_CREATE_UPDATE, ct);
+ ret = nfct_query(STATE(dump), NFCT_Q_CREATE_UPDATE, ct);
+ nfct_destroy(ct);
+
+ return ret;
}
-/* This function modifies the conntrack passed as argument! */
-int nl_update_conntrack(struct nf_conntrack *ct)
+int nl_update_conntrack(const struct nf_conntrack *orig)
{
+ int ret;
uint8_t flags;
+ struct nf_conntrack *ct;
+
+ ct = nfct_clone(orig);
+ if (ct == NULL)
+ return -1;
/* unset NAT info, otherwise we hit error */
nfct_attr_unset(ct, ATTR_SNAT_IPV4);
@@ -249,7 +262,10 @@ int nl_update_conntrack(struct nf_conntrack *ct)
nfct_set_attr_u8(ct, ATTR_TCP_FLAGS_REPL, flags);
nfct_set_attr_u8(ct, ATTR_TCP_MASK_REPL, flags);
- return nfct_query(STATE(dump), NFCT_Q_CREATE_UPDATE, ct);
+ ret = nfct_query(STATE(dump), NFCT_Q_CREATE_UPDATE, ct);
+ nfct_destroy(ct);
+
+ return ret;
}
int nl_destroy_conntrack(struct nf_conntrack *ct)