[NETFILTER]: ctnetlink: return EEXIST instead of EINVAL for existing nat'ed conntracks
Pablo Neira Ayuso [Wed, 8 Aug 2007 01:11:26 +0000 (18:11 -0700)]
ctnetlink must return EEXIST for existing nat'ed conntracks instead of
EINVAL. Only return EINVAL if we try to update a conntrack with NAT
handlings (that is not allowed).

Decadence:libnetfilter_conntrack/utils# ./conntrack_create_nat
TEST: create conntrack (0)(Success)
Decadence:libnetfilter_conntrack/utils# ./conntrack_create_nat
TEST: create conntrack (-1)(Invalid argument)

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>

net/netfilter/nf_conntrack_netlink.c

index 6f89b10..2863e72 100644 (file)
@@ -1052,17 +1052,18 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
        }
        /* implicit 'else' */
 
-       /* we only allow nat config for new conntracks */
-       if (cda[CTA_NAT_SRC-1] || cda[CTA_NAT_DST-1]) {
-               err = -EINVAL;
-               goto out_unlock;
-       }
-
        /* We manipulate the conntrack inside the global conntrack table lock,
         * so there's no need to increase the refcount */
        err = -EEXIST;
-       if (!(nlh->nlmsg_flags & NLM_F_EXCL))
-               err = ctnetlink_change_conntrack(nf_ct_tuplehash_to_ctrack(h), cda);
+       if (!(nlh->nlmsg_flags & NLM_F_EXCL)) {
+               /* we only allow nat config for new conntracks */
+               if (cda[CTA_NAT_SRC-1] || cda[CTA_NAT_DST-1]) {
+                       err = -EINVAL;
+                       goto out_unlock;
+               }
+               err = ctnetlink_change_conntrack(nf_ct_tuplehash_to_ctrack(h),
+                                                cda);
+       }
 
 out_unlock:
        write_unlock_bh(&nf_conntrack_lock);