netlink: Rename pid to portid to avoid confusion
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / net / netfilter / nf_conntrack_netlink.c
index 14f67a2cbcb5f065e2b4eab61a59c2447c6826d7..59770039b82556711ff1218bbcdb18034adef3b5 100644 (file)
@@ -45,7 +45,7 @@
 #include <net/netfilter/nf_conntrack_timestamp.h>
 #ifdef CONFIG_NF_NAT_NEEDED
 #include <net/netfilter/nf_nat_core.h>
-#include <net/netfilter/nf_nat_protocol.h>
+#include <net/netfilter/nf_nat_l4proto.h>
 #include <net/netfilter/nf_nat_helper.h>
 #endif
 
@@ -418,16 +418,16 @@ nla_put_failure:
 }
 
 static int
-ctnetlink_fill_info(struct sk_buff *skb, u32 pid, u32 seq, u32 type,
+ctnetlink_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
                    struct nf_conn *ct)
 {
        struct nlmsghdr *nlh;
        struct nfgenmsg *nfmsg;
        struct nlattr *nest_parms;
-       unsigned int flags = pid ? NLM_F_MULTI : 0, event;
+       unsigned int flags = portid ? NLM_F_MULTI : 0, event;
 
        event = (NFNL_SUBSYS_CTNETLINK << 8 | IPCTNL_MSG_CT_NEW);
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
        if (nlh == NULL)
                goto nlmsg_failure;
 
@@ -604,7 +604,7 @@ ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item)
                goto errout;
 
        type |= NFNL_SUBSYS_CTNETLINK << 8;
-       nlh = nlmsg_put(skb, item->pid, 0, type, sizeof(*nfmsg), flags);
+       nlh = nlmsg_put(skb, item->portid, 0, type, sizeof(*nfmsg), flags);
        if (nlh == NULL)
                goto nlmsg_failure;
 
@@ -680,7 +680,7 @@ ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item)
        rcu_read_unlock();
 
        nlmsg_end(skb, nlh);
-       err = nfnetlink_send(skb, net, item->pid, group, item->report,
+       err = nfnetlink_send(skb, net, item->portid, group, item->report,
                             GFP_ATOMIC);
        if (err == -ENOBUFS || err == -EAGAIN)
                return -ENOBUFS;
@@ -757,7 +757,7 @@ restart:
 #endif
                        rcu_read_lock();
                        res =
-                       ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid,
+                       ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).portid,
                                            cb->nlh->nlmsg_seq,
                                            NFNL_MSG_TYPE(cb->nlh->nlmsg_type),
                                            ct);
@@ -961,7 +961,7 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
        else {
                /* Flush the whole table */
                nf_conntrack_flush_report(net,
-                                        NETLINK_CB(skb).pid,
+                                        NETLINK_CB(skb).portid,
                                         nlmsg_report(nlh));
                return 0;
        }
@@ -985,7 +985,7 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
 
        if (del_timer(&ct->timeout)) {
                if (nf_conntrack_event_report(IPCT_DESTROY, ct,
-                                             NETLINK_CB(skb).pid,
+                                             NETLINK_CB(skb).portid,
                                              nlmsg_report(nlh)) < 0) {
                        nf_ct_delete_from_lists(ct);
                        /* we failed to report the event, try later */
@@ -1069,14 +1069,14 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
        }
 
        rcu_read_lock();
-       err = ctnetlink_fill_info(skb2, NETLINK_CB(skb).pid, nlh->nlmsg_seq,
+       err = ctnetlink_fill_info(skb2, NETLINK_CB(skb).portid, nlh->nlmsg_seq,
                                  NFNL_MSG_TYPE(nlh->nlmsg_type), ct);
        rcu_read_unlock();
        nf_ct_put(ct);
        if (err <= 0)
                goto free;
 
-       err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
+       err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).portid, MSG_DONTWAIT);
        if (err < 0)
                goto out;
 
@@ -1096,13 +1096,14 @@ ctnetlink_parse_nat_setup(struct nf_conn *ct,
                          const struct nlattr *attr)
 {
        typeof(nfnetlink_parse_nat_setup_hook) parse_nat_setup;
+       int err;
 
        parse_nat_setup = rcu_dereference(nfnetlink_parse_nat_setup_hook);
        if (!parse_nat_setup) {
 #ifdef CONFIG_MODULES
                rcu_read_unlock();
                nfnl_unlock();
-               if (request_module("nf-nat-ipv4") < 0) {
+               if (request_module("nf-nat") < 0) {
                        nfnl_lock();
                        rcu_read_lock();
                        return -EOPNOTSUPP;
@@ -1115,7 +1116,26 @@ ctnetlink_parse_nat_setup(struct nf_conn *ct,
                return -EOPNOTSUPP;
        }
 
-       return parse_nat_setup(ct, manip, attr);
+       err = parse_nat_setup(ct, manip, attr);
+       if (err == -EAGAIN) {
+#ifdef CONFIG_MODULES
+               rcu_read_unlock();
+               spin_unlock_bh(&nf_conntrack_lock);
+               nfnl_unlock();
+               if (request_module("nf-nat-%u", nf_ct_l3num(ct)) < 0) {
+                       nfnl_lock();
+                       spin_lock_bh(&nf_conntrack_lock);
+                       rcu_read_lock();
+                       return -EOPNOTSUPP;
+               }
+               nfnl_lock();
+               spin_lock_bh(&nf_conntrack_lock);
+               rcu_read_lock();
+#else
+               err = -EOPNOTSUPP;
+#endif
+       }
+       return err;
 }
 #endif
 
@@ -1596,7 +1616,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
                                                      (1 << IPCT_PROTOINFO) |
                                                      (1 << IPCT_NATSEQADJ) |
                                                      (1 << IPCT_MARK) | events,
-                                                     ct, NETLINK_CB(skb).pid,
+                                                     ct, NETLINK_CB(skb).portid,
                                                      nlmsg_report(nlh));
                        nf_ct_put(ct);
                }
@@ -1618,7 +1638,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
                                                      (1 << IPCT_PROTOINFO) |
                                                      (1 << IPCT_NATSEQADJ) |
                                                      (1 << IPCT_MARK),
-                                                     ct, NETLINK_CB(skb).pid,
+                                                     ct, NETLINK_CB(skb).portid,
                                                      nlmsg_report(nlh));
                }
        }
@@ -1628,15 +1648,15 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
 }
 
 static int
-ctnetlink_ct_stat_cpu_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
+ctnetlink_ct_stat_cpu_fill_info(struct sk_buff *skb, u32 portid, u32 seq,
                                __u16 cpu, const struct ip_conntrack_stat *st)
 {
        struct nlmsghdr *nlh;
        struct nfgenmsg *nfmsg;
-       unsigned int flags = pid ? NLM_F_MULTI : 0, event;
+       unsigned int flags = portid ? NLM_F_MULTI : 0, event;
 
        event = (NFNL_SUBSYS_CTNETLINK << 8 | IPCTNL_MSG_CT_GET_STATS_CPU);
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
        if (nlh == NULL)
                goto nlmsg_failure;
 
@@ -1688,7 +1708,7 @@ ctnetlink_ct_stat_cpu_dump(struct sk_buff *skb, struct netlink_callback *cb)
 
                st = per_cpu_ptr(net->ct.stat, cpu);
                if (ctnetlink_ct_stat_cpu_fill_info(skb,
-                                                   NETLINK_CB(cb->skb).pid,
+                                                   NETLINK_CB(cb->skb).portid,
                                                    cb->nlh->nlmsg_seq,
                                                    cpu, st) < 0)
                                break;
@@ -1714,16 +1734,16 @@ ctnetlink_stat_ct_cpu(struct sock *ctnl, struct sk_buff *skb,
 }
 
 static int
-ctnetlink_stat_ct_fill_info(struct sk_buff *skb, u32 pid, u32 seq, u32 type,
+ctnetlink_stat_ct_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
                            struct net *net)
 {
        struct nlmsghdr *nlh;
        struct nfgenmsg *nfmsg;
-       unsigned int flags = pid ? NLM_F_MULTI : 0, event;
+       unsigned int flags = portid ? NLM_F_MULTI : 0, event;
        unsigned int nr_conntracks = atomic_read(&net->ct.count);
 
        event = (NFNL_SUBSYS_CTNETLINK << 8 | IPCTNL_MSG_CT_GET_STATS);
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
        if (nlh == NULL)
                goto nlmsg_failure;
 
@@ -1756,14 +1776,14 @@ ctnetlink_stat_ct(struct sock *ctnl, struct sk_buff *skb,
        if (skb2 == NULL)
                return -ENOMEM;
 
-       err = ctnetlink_stat_ct_fill_info(skb2, NETLINK_CB(skb).pid,
+       err = ctnetlink_stat_ct_fill_info(skb2, NETLINK_CB(skb).portid,
                                          nlh->nlmsg_seq,
                                          NFNL_MSG_TYPE(nlh->nlmsg_type),
                                          sock_net(skb->sk));
        if (err <= 0)
                goto free;
 
-       err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
+       err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).portid, MSG_DONTWAIT);
        if (err < 0)
                goto out;
 
@@ -1896,10 +1916,15 @@ static int
 ctnetlink_nfqueue_parse(const struct nlattr *attr, struct nf_conn *ct)
 {
        struct nlattr *cda[CTA_MAX+1];
+       int ret;
 
        nla_parse_nested(cda, CTA_MAX, attr, ct_nla_policy);
 
-       return ctnetlink_nfqueue_parse_ct((const struct nlattr **)cda, ct);
+       spin_lock_bh(&nf_conntrack_lock);
+       ret = ctnetlink_nfqueue_parse_ct((const struct nlattr **)cda, ct);
+       spin_unlock_bh(&nf_conntrack_lock);
+
+       return ret;
 }
 
 static struct nfq_ct_hook ctnetlink_nfqueue_hook = {
@@ -1974,6 +1999,8 @@ nla_put_failure:
        return -1;
 }
 
+static const union nf_inet_addr any_addr;
+
 static int
 ctnetlink_exp_dump_expect(struct sk_buff *skb,
                          const struct nf_conntrack_expect *exp)
@@ -2000,7 +2027,8 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb,
                goto nla_put_failure;
 
 #ifdef CONFIG_NF_NAT_NEEDED
-       if (exp->saved_ip || exp->saved_proto.all) {
+       if (!nf_inet_addr_cmp(&exp->saved_addr, &any_addr) ||
+           exp->saved_proto.all) {
                nest_parms = nla_nest_start(skb, CTA_EXPECT_NAT | NLA_F_NESTED);
                if (!nest_parms)
                        goto nla_put_failure;
@@ -2009,7 +2037,7 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb,
                        goto nla_put_failure;
 
                nat_tuple.src.l3num = nf_ct_l3num(master);
-               nat_tuple.src.u3.ip = exp->saved_ip;
+               nat_tuple.src.u3 = exp->saved_addr;
                nat_tuple.dst.protonum = nf_ct_protonum(master);
                nat_tuple.src.u = exp->saved_proto;
 
@@ -2045,15 +2073,15 @@ nla_put_failure:
 }
 
 static int
-ctnetlink_exp_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
+ctnetlink_exp_fill_info(struct sk_buff *skb, u32 portid, u32 seq,
                        int event, const struct nf_conntrack_expect *exp)
 {
        struct nlmsghdr *nlh;
        struct nfgenmsg *nfmsg;
-       unsigned int flags = pid ? NLM_F_MULTI : 0;
+       unsigned int flags = portid ? NLM_F_MULTI : 0;
 
        event |= NFNL_SUBSYS_CTNETLINK_EXP << 8;
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
        if (nlh == NULL)
                goto nlmsg_failure;
 
@@ -2104,7 +2132,7 @@ ctnetlink_expect_event(unsigned int events, struct nf_exp_event *item)
                goto errout;
 
        type |= NFNL_SUBSYS_CTNETLINK_EXP << 8;
-       nlh = nlmsg_put(skb, item->pid, 0, type, sizeof(*nfmsg), flags);
+       nlh = nlmsg_put(skb, item->portid, 0, type, sizeof(*nfmsg), flags);
        if (nlh == NULL)
                goto nlmsg_failure;
 
@@ -2119,7 +2147,7 @@ ctnetlink_expect_event(unsigned int events, struct nf_exp_event *item)
        rcu_read_unlock();
 
        nlmsg_end(skb, nlh);
-       nfnetlink_send(skb, net, item->pid, group, item->report, GFP_ATOMIC);
+       nfnetlink_send(skb, net, item->portid, group, item->report, GFP_ATOMIC);
        return 0;
 
 nla_put_failure:
@@ -2162,7 +2190,7 @@ restart:
                                cb->args[1] = 0;
                        }
                        if (ctnetlink_exp_fill_info(skb,
-                                                   NETLINK_CB(cb->skb).pid,
+                                                   NETLINK_CB(cb->skb).portid,
                                                    cb->nlh->nlmsg_seq,
                                                    IPCTNL_MSG_EXP_NEW,
                                                    exp) < 0) {
@@ -2255,14 +2283,14 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
        }
 
        rcu_read_lock();
-       err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).pid,
+       err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).portid,
                                      nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW, exp);
        rcu_read_unlock();
        nf_ct_expect_put(exp);
        if (err <= 0)
                goto free;
 
-       err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
+       err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).portid, MSG_DONTWAIT);
        if (err < 0)
                goto out;
 
@@ -2316,7 +2344,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
                /* after list removal, usage count == 1 */
                spin_lock_bh(&nf_conntrack_lock);
                if (del_timer(&exp->timeout)) {
-                       nf_ct_unlink_expect_report(exp, NETLINK_CB(skb).pid,
+                       nf_ct_unlink_expect_report(exp, NETLINK_CB(skb).portid,
                                                   nlmsg_report(nlh));
                        nf_ct_expect_put(exp);
                }
@@ -2338,7 +2366,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
                                if (!strcmp(m_help->helper->name, name) &&
                                    del_timer(&exp->timeout)) {
                                        nf_ct_unlink_expect_report(exp,
-                                                       NETLINK_CB(skb).pid,
+                                                       NETLINK_CB(skb).portid,
                                                        nlmsg_report(nlh));
                                        nf_ct_expect_put(exp);
                                }
@@ -2354,7 +2382,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
                                                  hnode) {
                                if (del_timer(&exp->timeout)) {
                                        nf_ct_unlink_expect_report(exp,
-                                                       NETLINK_CB(skb).pid,
+                                                       NETLINK_CB(skb).portid,
                                                        nlmsg_report(nlh));
                                        nf_ct_expect_put(exp);
                                }
@@ -2405,7 +2433,7 @@ ctnetlink_parse_expect_nat(const struct nlattr *attr,
        if (err < 0)
                return err;
 
-       exp->saved_ip = nat_tuple.src.u3.ip;
+       exp->saved_addr = nat_tuple.src.u3;
        exp->saved_proto = nat_tuple.src.u;
        exp->dir = ntohl(nla_get_be32(tb[CTA_EXPECT_NAT_DIR]));
 
@@ -2419,7 +2447,7 @@ static int
 ctnetlink_create_expect(struct net *net, u16 zone,
                        const struct nlattr * const cda[],
                        u_int8_t u3,
-                       u32 pid, int report)
+                       u32 portid, int report)
 {
        struct nf_conntrack_tuple tuple, mask, master_tuple;
        struct nf_conntrack_tuple_hash *h = NULL;
@@ -2532,7 +2560,7 @@ ctnetlink_create_expect(struct net *net, u16 zone,
                if (err < 0)
                        goto err_out;
        }
-       err = nf_ct_expect_related_report(exp, pid, report);
+       err = nf_ct_expect_related_report(exp, portid, report);
 err_out:
        nf_ct_expect_put(exp);
 out:
@@ -2575,7 +2603,7 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
                if (nlh->nlmsg_flags & NLM_F_CREATE) {
                        err = ctnetlink_create_expect(net, zone, cda,
                                                      u3,
-                                                     NETLINK_CB(skb).pid,
+                                                     NETLINK_CB(skb).portid,
                                                      nlmsg_report(nlh));
                }
                return err;
@@ -2590,15 +2618,15 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
 }
 
 static int
-ctnetlink_exp_stat_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int cpu,
+ctnetlink_exp_stat_fill_info(struct sk_buff *skb, u32 portid, u32 seq, int cpu,
                             const struct ip_conntrack_stat *st)
 {
        struct nlmsghdr *nlh;
        struct nfgenmsg *nfmsg;
-       unsigned int flags = pid ? NLM_F_MULTI : 0, event;
+       unsigned int flags = portid ? NLM_F_MULTI : 0, event;
 
        event = (NFNL_SUBSYS_CTNETLINK << 8 | IPCTNL_MSG_EXP_GET_STATS_CPU);
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
        if (nlh == NULL)
                goto nlmsg_failure;
 
@@ -2637,7 +2665,7 @@ ctnetlink_exp_stat_cpu_dump(struct sk_buff *skb, struct netlink_callback *cb)
                        continue;
 
                st = per_cpu_ptr(net->ct.stat, cpu);
-               if (ctnetlink_exp_stat_fill_info(skb, NETLINK_CB(cb->skb).pid,
+               if (ctnetlink_exp_stat_fill_info(skb, NETLINK_CB(cb->skb).portid,
                                                 cb->nlh->nlmsg_seq,
                                                 cpu, st) < 0)
                        break;
@@ -2785,7 +2813,8 @@ static int __init ctnetlink_init(void)
                goto err_unreg_subsys;
        }
 
-       if (register_pernet_subsys(&ctnetlink_net_ops)) {
+       ret = register_pernet_subsys(&ctnetlink_net_ops);
+       if (ret < 0) {
                pr_err("ctnetlink_init: cannot register pernet operations\n");
                goto err_unreg_exp_subsys;
        }