diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2008-12-06 21:54:43 +0100 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2008-12-06 21:54:43 +0100 |
commit | 65ad316d921930c9d5c1c8640fbf2f05ecd0ca49 (patch) | |
tree | 9fc0427a023eaaba9a4619576dc979e2dae51ded /src | |
parent | 567222194512c6d42c7e253fc69c3837fe7b078c (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')
-rw-r--r-- | src/netlink.c | 28 |
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) |