From 65ad316d921930c9d5c1c8640fbf2f05ecd0ca49 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sat, 6 Dec 2008 21:54:43 +0100 Subject: 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 --- src/netlink.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) (limited to 'src') 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) -- cgit v1.2.3