net: change proto destroy method to return void
[pandora-kernel.git] / net / dccp / ipv6.c
index 2fec1af..eec3c47 100644 (file)
@@ -33,8 +33,7 @@
 #include "ipv6.h"
 #include "feat.h"
 
-/* Socket used for sending RSTs and ACKs */
-static struct socket *dccp_v6_ctl_socket;
+/* The per-net dccp.v6_ctl_sk is used for sending RSTs and ACKs */
 
 static struct inet_connection_sock_af_ops dccp_ipv6_mapped;
 static struct inet_connection_sock_af_ops dccp_ipv6_af_ops;
@@ -95,7 +94,8 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
        int err;
        __u64 seq;
 
-       sk = inet6_lookup(&init_net, &dccp_hashinfo, &hdr->daddr, dh->dccph_dport,
+       sk = inet6_lookup(dev_net(skb->dev), &dccp_hashinfo,
+                       &hdr->daddr, dh->dccph_dport,
                        &hdr->saddr, dh->dccph_sport, inet6_iif(skb));
 
        if (sk == NULL) {
@@ -296,6 +296,8 @@ static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb)
        struct ipv6hdr *rxip6h;
        struct sk_buff *skb;
        struct flowi fl;
+       struct net *net = dev_net(rxskb->dst->dev);
+       struct sock *ctl_sk = net->dccp.v6_ctl_sk;
 
        if (dccp_hdr(rxskb)->dccph_type == DCCP_PKT_RESET)
                return;
@@ -303,7 +305,7 @@ static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb)
        if (!ipv6_unicast_destination(rxskb))
                return;
 
-       skb = dccp_ctl_make_reset(dccp_v6_ctl_socket, rxskb);
+       skb = dccp_ctl_make_reset(ctl_sk, rxskb);
        if (skb == NULL)
                return;
 
@@ -322,9 +324,9 @@ static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb)
        security_skb_classify_flow(rxskb, &fl);
 
        /* sk = NULL, but it is safe for now. RST socket required. */
-       if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) {
+       if (!ip6_dst_lookup(ctl_sk, &skb->dst, &fl)) {
                if (xfrm_lookup(&skb->dst, &fl, NULL, 0) >= 0) {
-                       ip6_xmit(dccp_v6_ctl_socket->sk, skb, &fl, NULL, 0);
+                       ip6_xmit(ctl_sk, skb, &fl, NULL, 0);
                        DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS);
                        DCCP_INC_STATS_BH(DCCP_MIB_OUTRSTS);
                        return;
@@ -358,7 +360,7 @@ static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
        if (req != NULL)
                return dccp_check_req(sk, skb, req, prev);
 
-       nsk = __inet6_lookup_established(&init_net, &dccp_hashinfo,
+       nsk = __inet6_lookup_established(sock_net(sk), &dccp_hashinfo,
                                         &iph->saddr, dh->dccph_sport,
                                         &iph->daddr, ntohs(dh->dccph_dport),
                                         inet6_iif(skb));
@@ -419,7 +421,6 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
        ireq6 = inet6_rsk(req);
        ipv6_addr_copy(&ireq6->rmt_addr, &ipv6_hdr(skb)->saddr);
        ipv6_addr_copy(&ireq6->loc_addr, &ipv6_hdr(skb)->daddr);
-       ireq6->pktopts  = NULL;
 
        if (ipv6_opt_accepted(sk, skb) ||
            np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo ||
@@ -623,7 +624,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
        newinet->daddr = newinet->saddr = newinet->rcv_saddr = LOOPBACK4_IPV6;
 
        __inet6_hash(newsk);
-       inet_inherit_port(sk, newsk);
+       __inet_inherit_port(sk, newsk);
 
        return newsk;
 
@@ -789,8 +790,8 @@ static int dccp_v6_rcv(struct sk_buff *skb)
 
        /* Step 2:
         *      Look up flow ID in table and get corresponding socket */
-       sk = __inet6_lookup(&init_net, &dccp_hashinfo, &ipv6_hdr(skb)->saddr,
-                           dh->dccph_sport,
+       sk = __inet6_lookup(dev_net(skb->dst->dev), &dccp_hashinfo,
+                           &ipv6_hdr(skb)->saddr, dh->dccph_sport,
                            &ipv6_hdr(skb)->daddr, ntohs(dh->dccph_dport),
                            inet6_iif(skb));
        /*
@@ -1090,18 +1091,16 @@ static int dccp_v6_init_sock(struct sock *sk)
        return err;
 }
 
-static int dccp_v6_destroy_sock(struct sock *sk)
+static void dccp_v6_destroy_sock(struct sock *sk)
 {
        dccp_destroy_sock(sk);
-       return inet6_destroy_sock(sk);
+       inet6_destroy_sock(sk);
 }
 
 static struct timewait_sock_ops dccp6_timewait_sock_ops = {
        .twsk_obj_size  = sizeof(struct dccp6_timewait_sock),
 };
 
-DEFINE_PROTO_INUSE(dccp_v6)
-
 static struct proto dccp_v6_prot = {
        .name              = "DCCPv6",
        .owner             = THIS_MODULE,
@@ -1131,7 +1130,6 @@ static struct proto dccp_v6_prot = {
        .compat_setsockopt = compat_dccp_setsockopt,
        .compat_getsockopt = compat_dccp_getsockopt,
 #endif
-       REF_PROTO_INUSE(dccp_v6)
 };
 
 static struct inet6_protocol dccp_v6_protocol = {
@@ -1174,6 +1172,25 @@ static struct inet_protosw dccp_v6_protosw = {
        .flags          = INET_PROTOSW_ICSK,
 };
 
+static int dccp_v6_init_net(struct net *net)
+{
+       int err;
+
+       err = inet_ctl_sock_create(&net->dccp.v6_ctl_sk, PF_INET6,
+                                  SOCK_DCCP, IPPROTO_DCCP, net);
+       return err;
+}
+
+static void dccp_v6_exit_net(struct net *net)
+{
+       inet_ctl_sock_destroy(net->dccp.v6_ctl_sk);
+}
+
+static struct pernet_operations dccp_v6_ops = {
+       .init   = dccp_v6_init_net,
+       .exit   = dccp_v6_exit_net,
+};
+
 static int __init dccp_v6_init(void)
 {
        int err = proto_register(&dccp_v6_prot, 1);
@@ -1187,13 +1204,13 @@ static int __init dccp_v6_init(void)
 
        inet6_register_protosw(&dccp_v6_protosw);
 
-       err = inet_csk_ctl_sock_create(&dccp_v6_ctl_socket, PF_INET6,
-                                      SOCK_DCCP, IPPROTO_DCCP);
+       err = register_pernet_subsys(&dccp_v6_ops);
        if (err != 0)
-               goto out_unregister_protosw;
+               goto out_destroy_ctl_sock;
 out:
        return err;
-out_unregister_protosw:
+
+out_destroy_ctl_sock:
        inet6_del_protocol(&dccp_v6_protocol, IPPROTO_DCCP);
        inet6_unregister_protosw(&dccp_v6_protosw);
 out_unregister_proto:
@@ -1203,6 +1220,7 @@ out_unregister_proto:
 
 static void __exit dccp_v6_exit(void)
 {
+       unregister_pernet_subsys(&dccp_v6_ops);
        inet6_del_protocol(&dccp_v6_protocol, IPPROTO_DCCP);
        inet6_unregister_protosw(&dccp_v6_protosw);
        proto_unregister(&dccp_v6_prot);