netfilter: nfnetlink: netns support
[safe/jmp/linux-2.6] / net / netfilter / nf_conntrack_netlink.c
index 19706ef..d4c5d06 100644 (file)
@@ -463,6 +463,7 @@ ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item)
        struct sk_buff *skb;
        unsigned int type;
        unsigned int flags = 0, group;
+       int err;
 
        /* ignore our fake conntrack entry */
        if (ct == &nf_conntrack_untracked)
@@ -481,7 +482,7 @@ ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item)
        } else
                return 0;
 
-       if (!item->report && !nfnetlink_has_listeners(group))
+       if (!item->report && !nfnetlink_has_listeners(&init_net, group))
                return 0;
 
        skb = nlmsg_new(ctnetlink_nlmsg_size(ct), GFP_ATOMIC);
@@ -558,7 +559,11 @@ ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item)
        rcu_read_unlock();
 
        nlmsg_end(skb, nlh);
-       nfnetlink_send(skb, item->pid, group, item->report, GFP_ATOMIC);
+       err = nfnetlink_send(skb, &init_net, item->pid, group, item->report,
+                            GFP_ATOMIC);
+       if (err == -ENOBUFS || err == -EAGAIN)
+               return -ENOBUFS;
+
        return 0;
 
 nla_put_failure:
@@ -567,7 +572,7 @@ nla_put_failure:
 nlmsg_failure:
        kfree_skb(skb);
 errout:
-       nfnetlink_set_err(0, group, -ENOBUFS);
+       nfnetlink_set_err(&init_net, 0, group, -ENOBUFS);
        return 0;
 }
 #endif /* CONFIG_NF_CONNTRACK_EVENTS */
@@ -700,7 +705,8 @@ ctnetlink_parse_tuple_proto(struct nlattr *attr,
 }
 
 static int
-ctnetlink_parse_tuple(struct nlattr *cda[], struct nf_conntrack_tuple *tuple,
+ctnetlink_parse_tuple(const struct nlattr * const cda[],
+                     struct nf_conntrack_tuple *tuple,
                      enum ctattr_tuple type, u_int8_t l3num)
 {
        struct nlattr *tb[CTA_TUPLE_MAX+1];
@@ -736,7 +742,7 @@ ctnetlink_parse_tuple(struct nlattr *cda[], struct nf_conntrack_tuple *tuple,
 }
 
 static inline int
-ctnetlink_parse_help(struct nlattr *attr, char **helper_name)
+ctnetlink_parse_help(const struct nlattr *attr, char **helper_name)
 {
        struct nlattr *tb[CTA_HELP_MAX+1];
 
@@ -760,7 +766,8 @@ static const struct nla_policy ct_nla_policy[CTA_MAX+1] = {
 
 static int
 ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
-                       struct nlmsghdr *nlh, struct nlattr *cda[])
+                       const struct nlmsghdr *nlh,
+                       const struct nlattr * const cda[])
 {
        struct nf_conntrack_tuple_hash *h;
        struct nf_conntrack_tuple tuple;
@@ -798,10 +805,15 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
                }
        }
 
-       nf_conntrack_event_report(IPCT_DESTROY,
-                                 ct,
-                                 NETLINK_CB(skb).pid,
-                                 nlmsg_report(nlh));
+       if (nf_conntrack_event_report(IPCT_DESTROY, ct,
+                                     NETLINK_CB(skb).pid,
+                                     nlmsg_report(nlh)) < 0) {
+               nf_ct_delete_from_lists(ct);
+               /* we failed to report the event, try later */
+               nf_ct_insert_dying_list(ct);
+               nf_ct_put(ct);
+               return 0;
+       }
 
        /* death_by_timeout would report the event again */
        set_bit(IPS_DYING_BIT, &ct->status);
@@ -814,7 +826,8 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
 
 static int
 ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
-                       struct nlmsghdr *nlh, struct nlattr *cda[])
+                       const struct nlmsghdr *nlh,
+                       const struct nlattr * const cda[])
 {
        struct nf_conntrack_tuple_hash *h;
        struct nf_conntrack_tuple tuple;
@@ -875,7 +888,7 @@ out:
 static int
 ctnetlink_parse_nat_setup(struct nf_conn *ct,
                          enum nf_nat_manip_type manip,
-                         struct nlattr *attr)
+                         const struct nlattr *attr)
 {
        typeof(nfnetlink_parse_nat_setup_hook) parse_nat_setup;
 
@@ -905,7 +918,7 @@ ctnetlink_parse_nat_setup(struct nf_conn *ct,
 #endif
 
 static int
-ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
+ctnetlink_change_status(struct nf_conn *ct, const struct nlattr * const cda[])
 {
        unsigned long d;
        unsigned int status = ntohl(nla_get_be32(cda[CTA_STATUS]));
@@ -931,7 +944,7 @@ ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
 }
 
 static int
-ctnetlink_change_nat(struct nf_conn *ct, struct nlattr *cda[])
+ctnetlink_change_nat(struct nf_conn *ct, const struct nlattr * const cda[])
 {
 #ifdef CONFIG_NF_NAT_NEEDED
        int ret;
@@ -957,7 +970,7 @@ ctnetlink_change_nat(struct nf_conn *ct, struct nlattr *cda[])
 }
 
 static inline int
-ctnetlink_change_helper(struct nf_conn *ct, struct nlattr *cda[])
+ctnetlink_change_helper(struct nf_conn *ct, const struct nlattr * const cda[])
 {
        struct nf_conntrack_helper *helper;
        struct nf_conn_help *help = nfct_help(ct);
@@ -1019,7 +1032,7 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nlattr *cda[])
 }
 
 static inline int
-ctnetlink_change_timeout(struct nf_conn *ct, struct nlattr *cda[])
+ctnetlink_change_timeout(struct nf_conn *ct, const struct nlattr * const cda[])
 {
        u_int32_t timeout = ntohl(nla_get_be32(cda[CTA_TIMEOUT]));
 
@@ -1033,9 +1046,10 @@ ctnetlink_change_timeout(struct nf_conn *ct, struct nlattr *cda[])
 }
 
 static inline int
-ctnetlink_change_protoinfo(struct nf_conn *ct, struct nlattr *cda[])
+ctnetlink_change_protoinfo(struct nf_conn *ct, const struct nlattr * const cda[])
 {
-       struct nlattr *tb[CTA_PROTOINFO_MAX+1], *attr = cda[CTA_PROTOINFO];
+       const struct nlattr *attr = cda[CTA_PROTOINFO];
+       struct nlattr *tb[CTA_PROTOINFO_MAX+1];
        struct nf_conntrack_l4proto *l4proto;
        int err = 0;
 
@@ -1052,7 +1066,7 @@ ctnetlink_change_protoinfo(struct nf_conn *ct, struct nlattr *cda[])
 
 #ifdef CONFIG_NF_NAT_NEEDED
 static inline int
-change_nat_seq_adj(struct nf_nat_seq *natseq, struct nlattr *attr)
+change_nat_seq_adj(struct nf_nat_seq *natseq, const struct nlattr * const attr)
 {
        struct nlattr *cda[CTA_NAT_SEQ_MAX+1];
 
@@ -1080,7 +1094,8 @@ change_nat_seq_adj(struct nf_nat_seq *natseq, struct nlattr *attr)
 }
 
 static int
-ctnetlink_change_nat_seq_adj(struct nf_conn *ct, struct nlattr *cda[])
+ctnetlink_change_nat_seq_adj(struct nf_conn *ct,
+                            const struct nlattr * const cda[])
 {
        int ret = 0;
        struct nf_conn_nat *nat = nfct_nat(ct);
@@ -1111,7 +1126,8 @@ ctnetlink_change_nat_seq_adj(struct nf_conn *ct, struct nlattr *cda[])
 #endif
 
 static int
-ctnetlink_change_conntrack(struct nf_conn *ct, struct nlattr *cda[])
+ctnetlink_change_conntrack(struct nf_conn *ct,
+                          const struct nlattr * const cda[])
 {
        int err;
 
@@ -1160,7 +1176,7 @@ ctnetlink_change_conntrack(struct nf_conn *ct, struct nlattr *cda[])
 }
 
 static struct nf_conn *
-ctnetlink_create_conntrack(struct nlattr *cda[],
+ctnetlink_create_conntrack(const struct nlattr * const cda[],
                           struct nf_conntrack_tuple *otuple,
                           struct nf_conntrack_tuple *rtuple,
                           u8 u3)
@@ -1295,7 +1311,8 @@ err1:
 
 static int
 ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
-                       struct nlmsghdr *nlh, struct nlattr *cda[])
+                       const struct nlmsghdr *nlh,
+                       const struct nlattr * const cda[])
 {
        struct nf_conntrack_tuple otuple, rtuple;
        struct nf_conntrack_tuple_hash *h = NULL;
@@ -1523,7 +1540,7 @@ ctnetlink_expect_event(unsigned int events, struct nf_exp_event *item)
                return 0;
 
        if (!item->report &&
-           !nfnetlink_has_listeners(NFNLGRP_CONNTRACK_EXP_NEW))
+           !nfnetlink_has_listeners(&init_net, NFNLGRP_CONNTRACK_EXP_NEW))
                return 0;
 
        skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
@@ -1546,7 +1563,7 @@ ctnetlink_expect_event(unsigned int events, struct nf_exp_event *item)
        rcu_read_unlock();
 
        nlmsg_end(skb, nlh);
-       nfnetlink_send(skb, item->pid, NFNLGRP_CONNTRACK_EXP_NEW,
+       nfnetlink_send(skb, &init_net, item->pid, NFNLGRP_CONNTRACK_EXP_NEW,
                       item->report, GFP_ATOMIC);
        return 0;
 
@@ -1556,7 +1573,7 @@ nla_put_failure:
 nlmsg_failure:
        kfree_skb(skb);
 errout:
-       nfnetlink_set_err(0, 0, -ENOBUFS);
+       nfnetlink_set_err(&init_net, 0, 0, -ENOBUFS);
        return 0;
 }
 #endif
@@ -1620,7 +1637,8 @@ static const struct nla_policy exp_nla_policy[CTA_EXPECT_MAX+1] = {
 
 static int
 ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
-                    struct nlmsghdr *nlh, struct nlattr *cda[])
+                    const struct nlmsghdr *nlh,
+                    const struct nlattr * const cda[])
 {
        struct nf_conntrack_tuple tuple;
        struct nf_conntrack_expect *exp;
@@ -1680,7 +1698,8 @@ out:
 
 static int
 ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
-                    struct nlmsghdr *nlh, struct nlattr *cda[])
+                    const struct nlmsghdr *nlh,
+                    const struct nlattr * const cda[])
 {
        struct nf_conntrack_expect *exp;
        struct nf_conntrack_tuple tuple;
@@ -1758,13 +1777,15 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
        return 0;
 }
 static int
-ctnetlink_change_expect(struct nf_conntrack_expect *x, struct nlattr *cda[])
+ctnetlink_change_expect(struct nf_conntrack_expect *x,
+                       const struct nlattr * const cda[])
 {
        return -EOPNOTSUPP;
 }
 
 static int
-ctnetlink_create_expect(struct nlattr *cda[], u_int8_t u3, u32 pid, int report)
+ctnetlink_create_expect(const struct nlattr * const cda[], u_int8_t u3,
+                       u32 pid, int report)
 {
        struct nf_conntrack_tuple tuple, mask, master_tuple;
        struct nf_conntrack_tuple_hash *h = NULL;
@@ -1822,7 +1843,8 @@ out:
 
 static int
 ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
-                    struct nlmsghdr *nlh, struct nlattr *cda[])
+                    const struct nlmsghdr *nlh,
+                    const struct nlattr * const cda[])
 {
        struct nf_conntrack_tuple tuple;
        struct nf_conntrack_expect *exp;