[NETFILTER]: don't use nested attributes for conntrack_expect
authorHarald Welte <laforge@netfilter.org>
Wed, 10 Aug 2005 03:04:07 +0000 (20:04 -0700)
committerDavid S. Miller <davem@sunset.davemloft.net>
Mon, 29 Aug 2005 22:40:09 +0000 (15:40 -0700)
We used to use nested nfattr structures for ip_conntrack_expect.  This is
bogus, since ip_conntrack and ip_conntrack_expect are communicated in
different netlink message types.  both should be encoded at the top level
attributes, no extra nesting required.  This patch addresses the issue.

Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/netfilter/nfnetlink_conntrack.h
net/ipv4/netfilter/ip_conntrack_netlink.c

index fb528e0e3bd93fd220b6786695fe941598f005b9..5c55751c78e4d3a83cc2b29a7d4e20bfdaeeaaa8 100644 (file)
@@ -33,7 +33,6 @@ enum ctattr_type {
        CTA_COUNTERS_ORIG,
        CTA_COUNTERS_REPLY,
        CTA_USE,
-       CTA_EXPECT,
        CTA_ID,
        __CTA_MAX
 };
@@ -103,10 +102,12 @@ enum ctattr_protonat {
 
 enum ctattr_expect {
        CTA_EXPECT_UNSPEC,
+       CTA_EXPECT_MASTER,
        CTA_EXPECT_TUPLE,
        CTA_EXPECT_MASK,
        CTA_EXPECT_TIMEOUT,
        CTA_EXPECT_ID,
+       CTA_EXPECT_HELP_NAME,
        __CTA_EXPECT_MAX
 };
 #define CTA_EXPECT_MAX (__CTA_EXPECT_MAX - 1)
index 53d98974dcf038c0288ea269573c05b2a9772f7b..f5bda82c28756dcc1a66792673a273ad174f5053 100644 (file)
@@ -1100,18 +1100,21 @@ static inline int
 ctnetlink_exp_dump_expect(struct sk_buff *skb,
                           const struct ip_conntrack_expect *exp)
 {
+       struct ip_conntrack *master = exp->master;
        u_int32_t timeout = htonl((exp->timeout.expires - jiffies) / HZ);
        u_int32_t id = htonl(exp->id);
-       struct nfattr *nest_parms = NFA_NEST(skb, CTA_EXPECT);
 
        if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0)
                goto nfattr_failure;
        if (ctnetlink_exp_dump_tuple(skb, &exp->mask, CTA_EXPECT_MASK) < 0)
                goto nfattr_failure;
+       if (ctnetlink_exp_dump_tuple(skb,
+                                &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
+                                CTA_EXPECT_MASTER) < 0)
+               goto nfattr_failure;
        
        NFA_PUT(skb, CTA_EXPECT_TIMEOUT, sizeof(timeout), &timeout);
        NFA_PUT(skb, CTA_EXPECT_ID, sizeof(u_int32_t), &id);
-       NFA_NEST_END(skb, nest_parms);
 
        return 0;
        
@@ -1259,10 +1262,8 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
                return 0;
        }
 
-       if (cda[CTA_TUPLE_ORIG-1])
-               err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG);
-       else if (cda[CTA_TUPLE_REPLY-1])
-               err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY);
+       if (cda[CTA_EXPECT_MASTER-1])
+               err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_MASTER);
        else
                return -EINVAL;
 
@@ -1310,13 +1311,33 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
        struct ip_conntrack_helper *h;
        int err;
 
-       /* delete by tuple needs either orig or reply tuple */
-       if (cda[CTA_TUPLE_ORIG-1])
-               err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG);
-       else if (cda[CTA_TUPLE_REPLY-1])
-               err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY);
-       else if (cda[CTA_HELP_NAME-1]) {
-               char *name = NFA_DATA(cda[CTA_HELP_NAME-1]);
+       if (cda[CTA_EXPECT_TUPLE-1]) {
+               /* delete a single expect by tuple */
+               err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE);
+               if (err < 0)
+                       return err;
+
+               /* bump usage count to 2 */
+               exp = ip_conntrack_expect_find_get(&tuple);
+               if (!exp)
+                       return -ENOENT;
+
+               if (cda[CTA_EXPECT_ID-1]) {
+                       u_int32_t id = 
+                               *(u_int32_t *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
+                       if (exp->id != ntohl(id)) {
+                               ip_conntrack_expect_put(exp);
+                               return -ENOENT;
+                       }
+               }
+
+               /* after list removal, usage count == 1 */
+               ip_conntrack_unexpect_related(exp);
+               /* have to put what we 'get' above. 
+                * after this line usage count == 0 */
+               ip_conntrack_expect_put(exp);
+       } else if (cda[CTA_EXPECT_HELP_NAME-1]) {
+               char *name = NFA_DATA(cda[CTA_EXPECT_HELP_NAME-1]);
 
                /* delete all expectations for this helper */
                write_lock_bh(&ip_conntrack_lock);
@@ -1332,7 +1353,6 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
                                __ip_ct_expect_unlink_destroy(exp);
                }
                write_unlock(&ip_conntrack_lock);
-               return 0;
        } else {
                /* This basically means we have to flush everything*/
                write_lock_bh(&ip_conntrack_lock);
@@ -1342,30 +1362,8 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
                                __ip_ct_expect_unlink_destroy(exp);
                }
                write_unlock_bh(&ip_conntrack_lock);
-               return 0;
        }
 
-       if (err < 0)
-               return err;
-
-       /* bump usage count to 2 */
-       exp = ip_conntrack_expect_find_get(&tuple);
-       if (!exp)
-               return -ENOENT;
-
-       if (cda[CTA_EXPECT_ID-1]) {
-               u_int32_t id = *(u_int32_t *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
-               if (exp->id != ntohl(id)) {
-                       ip_conntrack_expect_put(exp);
-                       return -ENOENT;
-               }
-       }
-
-       /* after list removal, usage count == 1 */
-       ip_conntrack_unexpect_related(exp);
-       /* have to put what we 'get' above. after this line usage count == 0 */
-       ip_conntrack_expect_put(exp);
-
        return 0;
 }
 static int
@@ -1385,21 +1383,14 @@ ctnetlink_create_expect(struct nfattr *cda[])
 
        DEBUGP("entered %s\n", __FUNCTION__);
 
+       /* caller guarantees that those three CTA_EXPECT_* exist */
        err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE);
        if (err < 0)
                return err;
        err = ctnetlink_parse_tuple(cda, &mask, CTA_EXPECT_MASK);
        if (err < 0)
                return err;
-
-       if (cda[CTA_TUPLE_ORIG-1])
-               err = ctnetlink_parse_tuple(cda, &master_tuple, CTA_TUPLE_ORIG);
-       else if (cda[CTA_TUPLE_REPLY-1])
-               err = ctnetlink_parse_tuple(cda, &master_tuple, 
-                                           CTA_TUPLE_REPLY);
-       else
-               return -EINVAL;
-
+       err = ctnetlink_parse_tuple(cda, &master_tuple, CTA_EXPECT_MASTER);
        if (err < 0)
                return err;
 
@@ -1444,7 +1435,9 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
 
        DEBUGP("entered %s\n", __FUNCTION__);   
 
-       if (!cda[CTA_EXPECT_TUPLE-1] || !cda[CTA_EXPECT_MASK-1])
+       if (!cda[CTA_EXPECT_TUPLE-1]
+           || !cda[CTA_EXPECT_MASK-1]
+           || !cda[CTA_EXPECT_MASTER-1])
                return -EINVAL;
 
        err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE);