Make a separate local_addr_list for each netns, and use that list
to when creating associations.

Signed-off-by: Jan Ariyasu <jan.ariy...@hp.com>
---
 include/net/sctp/sctp.h    |    8 ++-
 include/net/sctp/structs.h |   28 ++++----
 net/sctp/associola.c       |    6 +-
 net/sctp/bind_addr.c       |   25 ++++---
 net/sctp/ipv6.c            |   47 ++++++++------
 net/sctp/output.c          |    4 +-
 net/sctp/protocol.c        |  154 ++++++++++++++++++++++++--------------------
 net/sctp/sm_make_chunk.c   |    8 ++-
 net/sctp/sm_sideeffect.c   |    3 +-
 net/sctp/sm_statefuns.c    |   16 +++--
 net/sctp/socket.c          |   59 ++++++++++-------
 net/sctp/transport.c       |   15 +++--
 12 files changed, 216 insertions(+), 157 deletions(-)

diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 97ba550..bda317a 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -121,10 +121,11 @@ extern int sctp_net_id;
  */
 extern int sctp_copy_local_addr_list(struct sctp_bind_addr *,
                                     sctp_scope_t, gfp_t gfp,
-                                    int flags);
+                                    int flags, struct net *);
 extern struct sctp_pf *sctp_get_pf_specific(sa_family_t family);
 extern int sctp_register_pf(struct sctp_pf *, sa_family_t);
-extern void sctp_addr_wq_mgmt(struct sctp_sockaddr_entry *, int);
+extern void sctp_addr_wq_mgmt(struct net *,
+                             struct sctp_sockaddr_entry *, int);
 
 /*
  * sctp/socket.c
@@ -139,7 +140,8 @@ void sctp_sock_rfree(struct sk_buff *skb);
 void sctp_copy_sock(struct sock *newsk, struct sock *sk,
                    struct sctp_association *asoc);
 extern struct percpu_counter sctp_sockets_allocated;
-extern int sctp_asconf_mgmt(struct sctp_sock *, struct sctp_sockaddr_entry *);
+extern int sctp_asconf_mgmt(struct net *, struct sctp_sock *,
+                   struct sctp_sockaddr_entry *);
 
 /*
  * sctp/primitive.c
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index bc65718..2034d53 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -718,7 +718,8 @@ struct sctp_af {
                                         int optname,
                                         char __user *optval,
                                         int __user *optlen);
-       void            (*get_dst)      (struct sctp_transport *t,
+       void            (*get_dst)      (struct net *net,
+                                        struct sctp_transport *t,
                                         union sctp_addr *saddr,
                                         struct flowi *fl,
                                         struct sock *sk);
@@ -751,7 +752,7 @@ struct sctp_af {
        sctp_scope_t    (*scope) (union sctp_addr *);
        void            (*inaddr_any)   (union sctp_addr *, __be16);
        int             (*is_any)       (const union sctp_addr *);
-       int             (*available)    (union sctp_addr *,
+       int             (*available)    (struct net *, union sctp_addr *,
                                         struct sctp_sock *);
        int             (*skb_iif)      (const struct sk_buff *sk);
        int             (*is_ce)        (const struct sk_buff *sk);
@@ -775,8 +776,10 @@ struct sctp_pf {
        int  (*cmp_addr) (const union sctp_addr *,
                          const union sctp_addr *,
                          struct sctp_sock *);
-       int  (*bind_verify) (struct sctp_sock *, union sctp_addr *);
-       int  (*send_verify) (struct sctp_sock *, union sctp_addr *);
+       int  (*bind_verify) (struct net *, struct sctp_sock *,
+                               union sctp_addr *);
+       int  (*send_verify) (struct net *, struct sctp_sock *,
+                               union sctp_addr *);
        int  (*supported_addrs)(const struct sctp_sock *, __be16 *);
        struct sock *(*create_accept_sk) (struct sock *sk,
                                          struct sctp_association *asoc);
@@ -1220,9 +1223,10 @@ struct sctp_transport *sctp_transport_new(const union 
sctp_addr *,
                                          gfp_t);
 void sctp_transport_set_owner(struct sctp_transport *,
                              struct sctp_association *);
-void sctp_transport_route(struct sctp_transport *, union sctp_addr *,
-                         struct sctp_sock *);
-void sctp_transport_pmtu(struct sctp_transport *, struct sock *sk);
+void sctp_transport_route(struct net *, struct sctp_transport *,
+                         union sctp_addr *, struct sctp_sock *);
+void sctp_transport_pmtu(struct net *, struct sctp_transport *,
+                        struct sock *sk);
 void sctp_transport_free(struct sctp_transport *);
 void sctp_transport_reset_timers(struct sctp_transport *);
 void sctp_transport_hold(struct sctp_transport *);
@@ -1373,6 +1377,7 @@ void sctp_bind_addr_init(struct sctp_bind_addr *, __u16 
port);
 void sctp_bind_addr_free(struct sctp_bind_addr *);
 int sctp_bind_addr_copy(struct sctp_bind_addr *dest,
                        const struct sctp_bind_addr *src,
+                       struct net *net,
                        sctp_scope_t scope, gfp_t gfp,
                        int flags);
 int sctp_bind_addr_dup(struct sctp_bind_addr *dest,
@@ -1398,7 +1403,8 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, 
__u8 *raw, int len,
                           __u16 port, gfp_t gfp);
 
 sctp_scope_t sctp_scope(const union sctp_addr *);
-int sctp_in_scope(const union sctp_addr *addr, const sctp_scope_t scope);
+int sctp_in_scope(const union sctp_addr *addr, const sctp_scope_t scope,
+                                 struct net *net);
 int sctp_is_any(struct sock *sk, const union sctp_addr *addr);
 int sctp_addr_is_valid(const union sctp_addr *addr);
 int sctp_is_ep_boundall(struct sock *sk);
@@ -1564,8 +1570,8 @@ int sctp_verify_init(const struct sctp_association *asoc, 
sctp_cid_t,
                     sctp_init_chunk_t *peer_init, struct sctp_chunk *chunk,
                     struct sctp_chunk **err_chunk);
 int sctp_process_init(struct sctp_association *, struct sctp_chunk *chunk,
-                     const union sctp_addr *peer,
-                     sctp_init_chunk_t *init, gfp_t gfp);
+                     const union sctp_addr *peer, sctp_init_chunk_t *init,
+                     struct net *net, gfp_t gfp);
 __u32 sctp_generate_tag(const struct sctp_endpoint *);
 __u32 sctp_generate_tsn(const struct sctp_endpoint *);
 
@@ -2160,7 +2166,7 @@ void sctp_assoc_set_primary(struct sctp_association *,
 void sctp_assoc_del_nonprimary_peers(struct sctp_association *,
                                    struct sctp_transport *);
 int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *,
-                                    sctp_scope_t, gfp_t);
+                                    struct net *, sctp_scope_t, gfp_t);
 int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *,
                                         struct sctp_cookie*,
                                         gfp_t gfp);
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index ebaef3e..001f44b 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -644,6 +644,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct 
sctp_association *asoc,
        struct sctp_transport *peer;
        struct sctp_sock *sp;
        unsigned short port;
+       struct net *net = sock_net(asoc->base.sk);
 
        sp = sctp_sk(asoc->base.sk);
 
@@ -702,7 +703,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct 
sctp_association *asoc,
         */
        peer->param_flags = asoc->param_flags;
 
-       sctp_transport_route(peer, NULL, sp);
+       sctp_transport_route(net, peer, NULL, sp);
 
        /* Initialize the pmtu of the transport. */
        if (peer->param_flags & SPP_PMTUD_DISABLE) {
@@ -1529,6 +1530,7 @@ void sctp_assoc_rwnd_decrease(struct sctp_association 
*asoc, unsigned int len)
  * local endpoint and the remote peer.
  */
 int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc,
+                                    struct net *net,
                                     sctp_scope_t scope, gfp_t gfp)
 {
        int flags;
@@ -1543,7 +1545,7 @@ int sctp_assoc_set_bind_addr_from_ep(struct 
sctp_association *asoc,
                flags |= SCTP_ADDR6_PEERSUPP;
 
        return sctp_bind_addr_copy(&asoc->base.bind_addr,
-                                  &asoc->ep->base.bind_addr,
+                                  &asoc->ep->base.bind_addr, net,
                                   scope, gfp, flags);
 }
 
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c
index 4ece451..2b18722 100644
--- a/net/sctp/bind_addr.c
+++ b/net/sctp/bind_addr.c
@@ -52,9 +52,10 @@
 #include <net/sctp/sm.h>
 
 /* Forward declarations for internal helpers. */
-static int sctp_copy_one_addr(struct sctp_bind_addr *, union sctp_addr *,
-                             sctp_scope_t scope, gfp_t gfp,
-                             int flags);
+static int sctp_copy_one_addr(struct sctp_bind_addr *,
+                             union sctp_addr *, struct net *,
+                             sctp_scope_t scope,
+                             gfp_t gfp, int flags);
 static void sctp_bind_addr_clean(struct sctp_bind_addr *);
 
 /* First Level Abstractions. */
@@ -64,6 +65,7 @@ static void sctp_bind_addr_clean(struct sctp_bind_addr *);
  */
 int sctp_bind_addr_copy(struct sctp_bind_addr *dest,
                        const struct sctp_bind_addr *src,
+                       struct net *net,
                        sctp_scope_t scope, gfp_t gfp,
                        int flags)
 {
@@ -75,8 +77,8 @@ int sctp_bind_addr_copy(struct sctp_bind_addr *dest,
 
        /* Extract the addresses which are relevant for this scope.  */
        list_for_each_entry(addr, &src->address_list, list) {
-               error = sctp_copy_one_addr(dest, &addr->a, scope,
-                                          gfp, flags);
+               error = sctp_copy_one_addr(dest, &addr->a, net,
+                                          scope, gfp, flags);
                if (error < 0)
                        goto out;
        }
@@ -87,7 +89,7 @@ int sctp_bind_addr_copy(struct sctp_bind_addr *dest,
         */
        if (list_empty(&dest->address_list) && (SCTP_SCOPE_GLOBAL == scope)) {
                list_for_each_entry(addr, &src->address_list, list) {
-                       error = sctp_copy_one_addr(dest, &addr->a,
+                       error = sctp_copy_one_addr(dest, &addr->a, net,
                                                   SCTP_SCOPE_LINK, gfp,
                                                   flags);
                        if (error < 0)
@@ -450,14 +452,15 @@ union sctp_addr *sctp_find_unmatch_addr(struct 
sctp_bind_addr     *bp,
 /* Copy out addresses from the global local address list. */
 static int sctp_copy_one_addr(struct sctp_bind_addr *dest,
                              union sctp_addr *addr,
+                             struct net *net,
                              sctp_scope_t scope, gfp_t gfp,
                              int flags)
 {
        int error = 0;
 
        if (sctp_is_any(NULL, addr)) {
-               error = sctp_copy_local_addr_list(dest, scope, gfp, flags);
-       } else if (sctp_in_scope(addr, scope)) {
+               error = sctp_copy_local_addr_list(dest, scope, gfp, flags, net);
+       } else if (sctp_in_scope(addr, scope, net)) {
                /* Now that the address is in scope, check to see if
                 * the address type is supported by local sock as
                 * well as the remote peer.
@@ -494,9 +497,11 @@ int sctp_is_any(struct sock *sk, const union sctp_addr 
*addr)
 }
 
 /* Is 'addr' valid for 'scope'?  */
-int sctp_in_scope(const union sctp_addr *addr, sctp_scope_t scope)
+int sctp_in_scope(const union sctp_addr *addr, sctp_scope_t scope,
+                 struct net *net)
 {
        sctp_scope_t addr_scope = sctp_scope(addr);
+       struct sctp_net_params *net_params = sctp_get_params(net);
 
        /* The unusable SCTP addresses will not be considered with
         * any defined scopes.
@@ -512,7 +517,7 @@ int sctp_in_scope(const union sctp_addr *addr, sctp_scope_t 
scope)
         * Address scoping can be selectively controlled via sysctl
         * option
         */
-       switch (sctp_scope_policy) {
+       switch (net_params->ipv4_scope_policy) {
        case SCTP_SCOPE_POLICY_DISABLE:
                return 1;
        case SCTP_SCOPE_POLICY_ENABLE:
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index ed7139e..67cae63 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -88,7 +88,7 @@ static int sctp_v6_cmp_addr(const union sctp_addr *addr1,
                            const union sctp_addr *addr2);
 
 /* Event handler for inet6 address addition/deletion events.
- * The sctp_local_addr_list needs to be protocted by a spin lock since
+ * The local_addr_list needs to be protocted by a spin lock since
  * multiple notifiers (say IPv4 and IPv6) may be running at the same
  * time and thus corrupt the list.
  * The reader side is protected with RCU.
@@ -100,6 +100,8 @@ static int sctp_inet6addr_event(struct notifier_block 
*this, unsigned long ev,
        struct sctp_sockaddr_entry *addr = NULL;
        struct sctp_sockaddr_entry *temp;
        int found = 0;
+       struct net *net = dev_net(ifa->idev->dev);
+       struct sctp_net_params *net_params = sctp_get_params(net);
 
        switch (ev) {
        case NETDEV_UP:
@@ -110,27 +112,28 @@ static int sctp_inet6addr_event(struct notifier_block 
*this, unsigned long ev,
                        addr->a.v6.sin6_addr = ifa->addr;
                        addr->a.v6.sin6_scope_id = ifa->idev->dev->ifindex;
                        addr->valid = 1;
-                       spin_lock_bh(&sctp_local_addr_lock);
-                       list_add_tail_rcu(&addr->list, &sctp_local_addr_list);
-                       sctp_addr_wq_mgmt(addr, SCTP_ADDR_NEW);
-                       spin_unlock_bh(&sctp_local_addr_lock);
+                       spin_lock_bh(&net_params->addr_list_lock);
+                       list_add_tail_rcu(&addr->list,
+                                         &net_params->local_addr_list);
+                       sctp_addr_wq_mgmt(net, addr, SCTP_ADDR_NEW);
+                       spin_unlock_bh(&net_params->addr_list_lock);
                }
                break;
        case NETDEV_DOWN:
-               spin_lock_bh(&sctp_local_addr_lock);
+               spin_lock_bh(&net_params->addr_list_lock);
                list_for_each_entry_safe(addr, temp,
-                                       &sctp_local_addr_list, list) {
+                                       &net_params->local_addr_list, list) {
                        if (addr->a.sa.sa_family == AF_INET6 &&
                                        ipv6_addr_equal(&addr->a.v6.sin6_addr,
                                                &ifa->addr)) {
-                               sctp_addr_wq_mgmt(addr, SCTP_ADDR_DEL);
+                               sctp_addr_wq_mgmt(net, addr, SCTP_ADDR_DEL);
                                found = 1;
                                addr->valid = 0;
                                list_del_rcu(&addr->list);
                                break;
                        }
                }
-               spin_unlock_bh(&sctp_local_addr_lock);
+               spin_unlock_bh(&net_params->addr_list_lock);
                if (found)
                        kfree_rcu(addr, rcu);
                break;
@@ -252,8 +255,9 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct 
sctp_transport *transport)
 /* Returns the dst cache entry for the given source and destination ip
  * addresses.
  */
-static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
-                           struct flowi *fl, struct sock *sk)
+static void sctp_v6_get_dst(struct net *net, struct sctp_transport *t,
+                           union sctp_addr *saddr, struct flowi *fl,
+                           struct sock *sk)
 {
        struct sctp_association *asoc = t->asoc;
        struct dst_entry *dst = NULL;
@@ -561,7 +565,8 @@ static int sctp_v6_is_any(const union sctp_addr *addr)
 }
 
 /* Should this be available for binding?   */
-static int sctp_v6_available(union sctp_addr *addr, struct sctp_sock *sp)
+static int sctp_v6_available(struct net *net, union sctp_addr *addr,
+                            struct sctp_sock *sp)
 {
        int type;
        const struct in6_addr *in6 = (const struct in6_addr 
*)&addr->v6.sin6_addr;
@@ -575,12 +580,12 @@ static int sctp_v6_available(union sctp_addr *addr, 
struct sctp_sock *sp)
                if (sp && ipv6_only_sock(sctp_opt2sk(sp)))
                        return 0;
                sctp_v6_map_v4(addr);
-               return sctp_get_af_specific(AF_INET)->available(addr, sp);
+               return sctp_get_af_specific(AF_INET)->available(net, addr, sp);
        }
        if (!(type & IPV6_ADDR_UNICAST))
                return 0;
 
-       return ipv6_chk_addr(&init_net, in6, NULL, 0);
+       return ipv6_chk_addr(net, in6, NULL, 0);
 }
 
 /* This function checks if the address is a valid address to be used for
@@ -845,7 +850,8 @@ static int sctp_inet6_cmp_addr(const union sctp_addr *addr1,
 /* Verify that the provided sockaddr looks bindable.   Common verification,
  * has already been taken care of.
  */
-static int sctp_inet6_bind_verify(struct sctp_sock *opt, union sctp_addr *addr)
+static int sctp_inet6_bind_verify(struct net *net, struct sctp_sock *opt,
+                                 union sctp_addr *addr)
 {
        struct sctp_af *af;
 
@@ -860,10 +866,10 @@ static int sctp_inet6_bind_verify(struct sctp_sock *opt, 
union sctp_addr *addr)
                        if (!addr->v6.sin6_scope_id)
                                return 0;
                        rcu_read_lock();
-                       dev = dev_get_by_index_rcu(&init_net,
+                       dev = dev_get_by_index_rcu(net,
                                                   addr->v6.sin6_scope_id);
                        if (!dev ||
-                           !ipv6_chk_addr(&init_net, &addr->v6.sin6_addr,
+                           !ipv6_chk_addr(net, &addr->v6.sin6_addr,
                                           dev, 0)) {
                                rcu_read_unlock();
                                return 0;
@@ -876,13 +882,14 @@ static int sctp_inet6_bind_verify(struct sctp_sock *opt, 
union sctp_addr *addr)
 
                af = opt->pf->af;
        }
-       return af->available(addr, opt);
+       return af->available(net, addr, opt);
 }
 
 /* Verify that the provided sockaddr looks sendable.   Common verification,
  * has already been taken care of.
  */
-static int sctp_inet6_send_verify(struct sctp_sock *opt, union sctp_addr *addr)
+static int sctp_inet6_send_verify(struct net *net, struct sctp_sock *opt,
+                                 union sctp_addr *addr)
 {
        struct sctp_af *af = NULL;
 
@@ -897,7 +904,7 @@ static int sctp_inet6_send_verify(struct sctp_sock *opt, 
union sctp_addr *addr)
                        if (!addr->v6.sin6_scope_id)
                                return 0;
                        rcu_read_lock();
-                       dev = dev_get_by_index_rcu(&init_net,
+                       dev = dev_get_by_index_rcu(net,
                                                   addr->v6.sin6_scope_id);
                        rcu_read_unlock();
                        if (!dev)
diff --git a/net/sctp/output.c b/net/sctp/output.c
index 838e18b..f9c5ffa 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -377,6 +377,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
        struct sk_buff *nskb;
        struct sctp_chunk *chunk, *tmp;
        struct sock *sk;
+       struct net *net;
        int err = 0;
        int padding;            /* How much padding do we need?  */
        __u8 has_data = 0;
@@ -393,6 +394,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
        /* Set up convenience variables... */
        chunk = list_entry(packet->chunk_list.next, struct sctp_chunk, list);
        sk = chunk->skb->sk;
+       net = sock_net(sk);
 
        /* Allocate the new skb.  */
        nskb = alloc_skb(packet->size + LL_MAX_HEADER, GFP_ATOMIC);
@@ -408,7 +410,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
        skb_set_owner_w(nskb, sk);
 
        if (!sctp_transport_dst_check(tp)) {
-               sctp_transport_route(tp, NULL, sctp_sk(sk));
+               sctp_transport_route(net, tp, NULL, sctp_sk(sk));
                if (asoc && (asoc->param_flags & SPP_PMTUD_ENABLE)) {
                        sctp_assoc_sync_pmtu(sk, asoc);
                }
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 28dbef2..dce07d6 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -196,29 +196,32 @@ static void sctp_v4_copy_addrlist(struct list_head 
*addrlist,
 /* Extract our IP addresses from the system and stash them in the
  * protocol structure.
  */
-static void sctp_get_local_addr_list(void)
+static void sctp_get_local_addr_list(struct net *net)
 {
        struct net_device *dev;
        struct list_head *pos;
        struct sctp_af *af;
+       struct sctp_net_params *net_params = sctp_get_params(net);
 
        rcu_read_lock();
-       for_each_netdev_rcu(&init_net, dev) {
+       for_each_netdev_rcu(net, dev) {
                __list_for_each(pos, &sctp_address_families) {
                        af = list_entry(pos, struct sctp_af, list);
-                       af->copy_addrlist(&sctp_local_addr_list, dev);
+                       af->copy_addrlist(&net_params->local_addr_list, dev);
                }
        }
        rcu_read_unlock();
 }
 
 /* Free the existing local addresses.  */
-static void sctp_free_local_addr_list(void)
+static void sctp_free_local_addr_list(struct net *net)
 {
        struct sctp_sockaddr_entry *addr;
        struct list_head *pos, *temp;
+       struct sctp_net_params *net_params =
+               sctp_get_params(net);
 
-       list_for_each_safe(pos, temp, &sctp_local_addr_list) {
+       list_for_each_safe(pos, temp, &net_params->local_addr_list) {
                addr = list_entry(pos, struct sctp_sockaddr_entry, list);
                list_del(pos);
                kfree(addr);
@@ -227,16 +230,17 @@ static void sctp_free_local_addr_list(void)
 
 /* Copy the local addresses which are valid for 'scope' into 'bp'.  */
 int sctp_copy_local_addr_list(struct sctp_bind_addr *bp, sctp_scope_t scope,
-                             gfp_t gfp, int copy_flags)
+                             gfp_t gfp, int copy_flags, struct net *net)
 {
        struct sctp_sockaddr_entry *addr;
        int error = 0;
+       struct sctp_net_params *net_params = sctp_get_params(net);
 
        rcu_read_lock();
-       list_for_each_entry_rcu(addr, &sctp_local_addr_list, list) {
+       list_for_each_entry_rcu(addr, &net_params->local_addr_list, list) {
                if (!addr->valid)
                        continue;
-               if (sctp_in_scope(&addr->a, scope)) {
+               if (sctp_in_scope(&addr->a, scope, net)) {
                        /* Now that the address is in scope, check to see if
                         * the address type is really supported by the local
                         * sock as well as the remote peer.
@@ -389,11 +393,15 @@ static int sctp_v4_addr_valid(union sctp_addr *addr,
        return 1;
 }
 
-/* Should this be available for binding?   */
-static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp)
+/* Should this be available for binding?
+ *  Note that we could derive struct net *net from the sctp_sock *sp,
+ *  but the IPv6 version of this code doesn't have the same information
+ *  in the last argument.
+ */
+static int sctp_v4_available(struct net *net, union sctp_addr *addr,
+                            struct sctp_sock *sp)
 {
-       int ret = inet_addr_type(&init_net, addr->v4.sin_addr.s_addr);
-
+       int ret = inet_addr_type(net, addr->v4.sin_addr.s_addr);
 
        if (addr->v4.sin_addr.s_addr != htonl(INADDR_ANY) &&
           ret != RTN_LOCAL &&
@@ -450,8 +458,9 @@ static sctp_scope_t sctp_v4_scope(union sctp_addr *addr)
  * addresses. If an association is passed, trys to get a dst entry with a
  * source address that matches an address in the bind address list.
  */
-static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
-                               struct flowi *fl, struct sock *sk)
+static void sctp_v4_get_dst(struct net *net, struct sctp_transport *t,
+                           union sctp_addr *saddr, struct flowi *fl,
+                           struct sock *sk)
 {
        struct sctp_association *asoc = t->asoc;
        struct rtable *rt;
@@ -479,7 +488,7 @@ static void sctp_v4_get_dst(struct sctp_transport *t, union 
sctp_addr *saddr,
        SCTP_DEBUG_PRINTK("%s: DST:%pI4, SRC:%pI4 - ",
                          __func__, &fl4->daddr, &fl4->saddr);
 
-       rt = ip_route_output_key(&init_net, fl4);
+       rt = ip_route_output_key(net, fl4);
        if (!IS_ERR(rt))
                dst = &rt->dst;
 
@@ -525,7 +534,7 @@ static void sctp_v4_get_dst(struct sctp_transport *t, union 
sctp_addr *saddr,
                    (AF_INET == laddr->a.sa.sa_family)) {
                        fl4->saddr = laddr->a.v4.sin_addr.s_addr;
                        fl4->fl4_sport = laddr->a.v4.sin_port;
-                       rt = ip_route_output_key(&init_net, fl4);
+                       rt = ip_route_output_key(sock_net(asoc->base.sk), fl4);
                        if (!IS_ERR(rt)) {
                                dst = &rt->dst;
                                goto out_unlock;
@@ -624,13 +633,15 @@ void sctp_addr_wq_timeout_handler(unsigned long arg)
 {
        struct sctp_sockaddr_entry *addrw, *temp;
        struct sctp_sock *sp;
+       struct net *net = (struct net *)arg;
+       struct sctp_net_params *net_params = sctp_get_params(net);
 
-       spin_lock_bh(&sctp_addr_wq_lock);
+       spin_lock_bh(&net_params->addr_wq_lock);
 
-       list_for_each_entry_safe(addrw, temp, &sctp_addr_waitq, list) {
+       list_for_each_entry_safe(addrw, temp, &net_params->addr_waitq, list) {
                SCTP_DEBUG_PRINTK_IPADDR("sctp_addrwq_timo_handler: the first 
ent in wq %p is ",
-                   " for cmd %d at entry %p\n", &sctp_addr_waitq, &addrw->a, 
addrw->state,
-                   addrw);
+                   " for cmd %d at entry %p\n", &net_params->addr_waitq,
+                   &addrw->a, addrw->state, addrw);
 
 #if IS_ENABLED(CONFIG_IPV6)
                /* Now we send an ASCONF for each association */
@@ -643,7 +654,7 @@ void sctp_addr_wq_timeout_handler(unsigned long arg)
                                goto free_next;
 
                        in6 = (struct in6_addr *)&addrw->a.v6.sin6_addr;
-                       if (ipv6_chk_addr(&init_net, in6, NULL, 0) == 0 &&
+                       if (ipv6_chk_addr(net, in6, NULL, 0) == 0 &&
                            addrw->state == SCTP_ADDR_NEW) {
                                unsigned long timeo_val;
 
@@ -651,7 +662,8 @@ void sctp_addr_wq_timeout_handler(unsigned long arg)
                                    SCTP_ADDRESS_TICK_DELAY);
                                timeo_val = jiffies;
                                timeo_val += 
msecs_to_jiffies(SCTP_ADDRESS_TICK_DELAY);
-                               mod_timer(&sctp_addr_wq_timer, timeo_val);
+                               mod_timer(&net_params->addr_wq_timer,
+                                         timeo_val);
                                break;
                        }
                }
@@ -664,7 +676,7 @@ void sctp_addr_wq_timeout_handler(unsigned long arg)
                        if (!sctp_is_ep_boundall(sk))
                                continue;
                        sctp_bh_lock_sock(sk);
-                       if (sctp_asconf_mgmt(sp, addrw) < 0)
+                       if (sctp_asconf_mgmt(net, sp, addrw) < 0)
                                SCTP_DEBUG_PRINTK("sctp_addrwq_timo_handler: 
sctp_asconf_mgmt failed\n");
                        sctp_bh_unlock_sock(sk);
                }
@@ -674,31 +686,35 @@ free_next:
                list_del(&addrw->list);
                kfree(addrw);
        }
-       spin_unlock_bh(&sctp_addr_wq_lock);
+       spin_unlock_bh(&net_params->addr_wq_lock);
 }
 
-static void sctp_free_addr_wq(void)
+static void sctp_free_addr_wq(struct net *net)
 {
        struct sctp_sockaddr_entry *addrw;
        struct sctp_sockaddr_entry *temp;
+       struct sctp_net_params *net_params = sctp_get_params(net);
 
-       spin_lock_bh(&sctp_addr_wq_lock);
-       del_timer(&sctp_addr_wq_timer);
-       list_for_each_entry_safe(addrw, temp, &sctp_addr_waitq, list) {
+       spin_lock_bh(&net_params->addr_wq_lock);
+       del_timer(&net_params->addr_wq_timer);
+       list_for_each_entry_safe(addrw, temp, &net_params->addr_waitq, list) {
                list_del(&addrw->list);
                kfree(addrw);
        }
-       spin_unlock_bh(&sctp_addr_wq_lock);
+       spin_unlock_bh(&net_params->addr_wq_lock);
 }
 
 /* lookup the entry for the same address in the addr_waitq
  * sctp_addr_wq MUST be locked
  */
-static struct sctp_sockaddr_entry *sctp_addr_wq_lookup(struct 
sctp_sockaddr_entry *addr)
+static struct sctp_sockaddr_entry *sctp_addr_wq_lookup(
+                                    struct net *net,
+                                    struct sctp_sockaddr_entry *addr)
 {
        struct sctp_sockaddr_entry *addrw;
+       struct sctp_net_params *net_params = sctp_get_params(net);
 
-       list_for_each_entry(addrw, &sctp_addr_waitq, list) {
+       list_for_each_entry(addrw, &net_params->addr_waitq, list) {
                if (addrw->a.sa.sa_family != addr->a.sa.sa_family)
                        continue;
                if (addrw->a.sa.sa_family == AF_INET) {
@@ -714,10 +730,12 @@ static struct sctp_sockaddr_entry 
*sctp_addr_wq_lookup(struct sctp_sockaddr_entr
        return NULL;
 }
 
-void sctp_addr_wq_mgmt(struct sctp_sockaddr_entry *addr, int cmd)
+void sctp_addr_wq_mgmt(struct net *net, struct sctp_sockaddr_entry *addr,
+                       int cmd)
 {
        struct sctp_sockaddr_entry *addrw;
        unsigned long timeo_val;
+       struct sctp_net_params *net_params = sctp_get_params(net);
 
        /* first, we check if an opposite message already exist in the queue.
         * If we found such message, it is removed.
@@ -725,38 +743,38 @@ void sctp_addr_wq_mgmt(struct sctp_sockaddr_entry *addr, 
int cmd)
         * new address after a couple of addition and deletion of that address
         */
 
-       spin_lock_bh(&sctp_addr_wq_lock);
+       spin_lock_bh(&net_params->addr_wq_lock);
        /* Offsets existing events in addr_wq */
-       addrw = sctp_addr_wq_lookup(addr);
+       addrw = sctp_addr_wq_lookup(net, addr);
        if (addrw) {
                if (addrw->state != cmd) {
                        SCTP_DEBUG_PRINTK_IPADDR("sctp_addr_wq_mgmt offsets 
existing entry for %d ",
                            " in wq %p\n", addrw->state, &addrw->a,
-                           &sctp_addr_waitq);
+                           &net_params->addr_waitq);
                        list_del(&addrw->list);
                        kfree(addrw);
                }
-               spin_unlock_bh(&sctp_addr_wq_lock);
+               spin_unlock_bh(&net_params->addr_wq_lock);
                return;
        }
 
        /* OK, we have to add the new address to the wait queue */
        addrw = kmemdup(addr, sizeof(struct sctp_sockaddr_entry), GFP_ATOMIC);
        if (addrw == NULL) {
-               spin_unlock_bh(&sctp_addr_wq_lock);
+               spin_unlock_bh(&net_params->addr_wq_lock);
                return;
        }
        addrw->state = cmd;
-       list_add_tail(&addrw->list, &sctp_addr_waitq);
+       list_add_tail(&addrw->list, &net_params->addr_waitq);
        SCTP_DEBUG_PRINTK_IPADDR("sctp_addr_wq_mgmt add new entry for cmd:%d ",
-           " in wq %p\n", addrw->state, &addrw->a, &sctp_addr_waitq);
+           " in wq %p\n", addrw->state, &addrw->a, &net_params->addr_waitq);
 
-       if (!timer_pending(&sctp_addr_wq_timer)) {
+       if (!timer_pending(&net_params->addr_wq_timer)) {
                timeo_val = jiffies;
                timeo_val += msecs_to_jiffies(SCTP_ADDRESS_TICK_DELAY);
-               mod_timer(&sctp_addr_wq_timer, timeo_val);
+               mod_timer(&net_params->addr_wq_timer, timeo_val);
        }
-       spin_unlock_bh(&sctp_addr_wq_lock);
+       spin_unlock_bh(&net_params->addr_wq_lock);
 }
 
 /* Event handler for inet address addition/deletion events.
@@ -772,9 +790,8 @@ static int sctp_inetaddr_event(struct notifier_block *this, 
unsigned long ev,
        struct sctp_sockaddr_entry *addr = NULL;
        struct sctp_sockaddr_entry *temp;
        int found = 0;
-
-       if (!net_eq(dev_net(ifa->ifa_dev->dev), &init_net))
-               return NOTIFY_DONE;
+       struct net *net = dev_net(ifa->ifa_dev->dev);
+       struct sctp_net_params *net_params = sctp_get_params(net);
 
        switch (ev) {
        case NETDEV_UP:
@@ -784,27 +801,28 @@ static int sctp_inetaddr_event(struct notifier_block 
*this, unsigned long ev,
                        addr->a.v4.sin_port = 0;
                        addr->a.v4.sin_addr.s_addr = ifa->ifa_local;
                        addr->valid = 1;
-                       spin_lock_bh(&sctp_local_addr_lock);
-                       list_add_tail_rcu(&addr->list, &sctp_local_addr_list);
-                       sctp_addr_wq_mgmt(addr, SCTP_ADDR_NEW);
-                       spin_unlock_bh(&sctp_local_addr_lock);
+                       spin_lock_bh(&net_params->addr_list_lock);
+                       list_add_tail_rcu(&addr->list,
+                                         &net_params->local_addr_list);
+                       sctp_addr_wq_mgmt(net, addr, SCTP_ADDR_NEW);
+                       spin_unlock_bh(&net_params->addr_list_lock);
                }
                break;
        case NETDEV_DOWN:
-               spin_lock_bh(&sctp_local_addr_lock);
+               spin_lock_bh(&net_params->addr_list_lock);
                list_for_each_entry_safe(addr, temp,
-                                       &sctp_local_addr_list, list) {
+                                       &net_params->local_addr_list, list) {
                        if (addr->a.sa.sa_family == AF_INET &&
                                        addr->a.v4.sin_addr.s_addr ==
                                        ifa->ifa_local) {
-                               sctp_addr_wq_mgmt(addr, SCTP_ADDR_DEL);
+                               sctp_addr_wq_mgmt(net, addr, SCTP_ADDR_DEL);
                                found = 1;
                                addr->valid = 0;
                                list_del_rcu(&addr->list);
                                break;
                        }
                }
-               spin_unlock_bh(&sctp_local_addr_lock);
+               spin_unlock_bh(&net_params->addr_list_lock);
                if (found)
                        kfree_rcu(addr, rcu);
                break;
@@ -955,15 +973,17 @@ static int sctp_inet_cmp_addr(const union sctp_addr 
*addr1,
 /* Verify that provided sockaddr looks bindable.  Common verification has
  * already been taken care of.
  */
-static int sctp_inet_bind_verify(struct sctp_sock *opt, union sctp_addr *addr)
+static int sctp_inet_bind_verify(struct net *net, struct sctp_sock *opt,
+                                union sctp_addr *addr)
 {
-       return sctp_v4_available(addr, opt);
+       return sctp_v4_available(net, addr, opt);
 }
 
 /* Verify that sockaddr looks sendable.  Common verification has already
  * been taken care of.
  */
-static int sctp_inet_send_verify(struct sctp_sock *opt, union sctp_addr *addr)
+static int sctp_inet_send_verify(struct net *net, struct sctp_sock *opt,
+                                union sctp_addr *addr)
 {
        return 1;
 }
@@ -1562,6 +1582,8 @@ static int __net_init sctp_net_init(struct net *net)
        if (err)
                goto err_param_init;
 
+       sctp_get_local_addr_list(net);
+       goto out;
 err_param_init:
        sctp_proc_exit(net);
 err_proc_init:
@@ -1572,7 +1594,12 @@ out:
 
 static void __net_exit sctp_net_exit(struct net *net)
 {
+       sctp_free_addr_wq(net);
+       /* Free the control sock */
        sctp_ctl_sock_destroy(net);
+       /* Free the local address list.  */
+       sctp_free_local_addr_list(net);
+       /* Clean up procfs */
        sctp_proc_exit(net);
 }
 
@@ -1623,17 +1650,7 @@ SCTP_STATIC __init int sctp_init(void)
        sctp_v4_pf_init();
        sctp_v6_pf_init();
 
-       /* Initialize the local address list. */
-       INIT_LIST_HEAD(&sctp_local_addr_list);
-       spin_lock_init(&sctp_local_addr_lock);
-       sctp_get_local_addr_list();
 
-       /* Initialize the address event list */
-       INIT_LIST_HEAD(&sctp_addr_waitq);
-       INIT_LIST_HEAD(&sctp_auto_asconf_splist);
-       spin_lock_init(&sctp_addr_wq_lock);
-       sctp_addr_wq_timer.expires = 0;
-       setup_timer(&sctp_addr_wq_timer, sctp_addr_wq_timeout_handler, 0);
 
        /* Register SCTP protocol */
        status = sctp_v4_protosw_init();
@@ -1689,7 +1706,6 @@ err_add_protocol:
 err_v6_protosw_init:
        sctp_v4_protosw_exit();
 err_protosw_init:
-       sctp_free_local_addr_list();
        sctp_v6_pf_exit();
        sctp_v4_pf_exit();
        sctp_hashtable_globals_free();
@@ -1710,15 +1726,11 @@ SCTP_STATIC __exit void sctp_exit(void)
        /* Unregister with inet6/inet layers. */
        sctp_v6_del_protocol();
        sctp_v4_del_protocol();
-       sctp_free_addr_wq();
 
        /* Free protosw registrations */
        sctp_v6_protosw_exit();
        sctp_v4_protosw_exit();
 
-       /* Free the local address list.  */
-       sctp_free_local_addr_list();
-
        /* Unregister with socket layer. */
        sctp_v6_pf_exit();
        sctp_v4_pf_exit();
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 479a70e..af02b44 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -79,6 +79,7 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct 
sctp_endpoint *ep,
 static int sctp_process_param(struct sctp_association *asoc,
                              union sctp_params param,
                              const union sctp_addr *peer_addr,
+                             struct net *net,
                              gfp_t gfp);
 static void *sctp_addto_param(struct sctp_chunk *chunk, int len,
                              const void *data);
@@ -2268,7 +2269,7 @@ int sctp_verify_init(const struct sctp_association *asoc,
  */
 int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk,
                      const union sctp_addr *peer_addr,
-                     sctp_init_chunk_t *peer_init, gfp_t gfp)
+                     sctp_init_chunk_t *peer_init, struct net *net, gfp_t gfp)
 {
        union sctp_params param;
        struct sctp_transport *transport;
@@ -2305,7 +2306,7 @@ int sctp_process_init(struct sctp_association *asoc, 
struct sctp_chunk *chunk,
                                src_match = 1;
                }
 
-               if (!sctp_process_param(asoc, param, peer_addr, gfp))
+               if (!sctp_process_param(asoc, param, peer_addr, net, gfp))
                        goto clean_up;
        }
 
@@ -2464,6 +2465,7 @@ nomem:
 static int sctp_process_param(struct sctp_association *asoc,
                              union sctp_params param,
                              const union sctp_addr *peer_addr,
+                             struct net *net,
                              gfp_t gfp)
 {
        union sctp_addr addr;
@@ -2494,7 +2496,7 @@ do_addr_param:
                af = sctp_get_af_specific(param_type2af(param.p->type));
                af->from_addr_param(&addr, param.addr, htons(asoc->peer.port), 
0);
                scope = sctp_scope(peer_addr);
-               if (sctp_in_scope(&addr, scope))
+               if (sctp_in_scope(&addr, scope, net))
                        if (!sctp_assoc_add_peer(asoc, &addr, gfp, 
SCTP_UNCONFIRMED))
                                return 0;
                break;
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index fe99628..8fe4a25 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -615,7 +615,8 @@ static int sctp_cmd_process_init(sctp_cmd_seq_t *commands,
         * fail during INIT processing (due to malloc problems),
         * just return the error and stop processing the stack.
         */
-       if (!sctp_process_init(asoc, chunk, sctp_source(chunk), peer_init, gfp))
+       if (!sctp_process_init(asoc, chunk, sctp_source(chunk), peer_init,
+               &init_net, gfp))
                error = -ENOMEM;
        else
                error = 0;
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 91dcdd6..85a46ac 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -388,6 +388,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct 
sctp_endpoint *ep,
                goto nomem;
 
        if (sctp_assoc_set_bind_addr_from_ep(new_asoc,
+                                            &init_net,
                                             sctp_scope(sctp_source(chunk)),
                                             GFP_ATOMIC) < 0)
                goto nomem_init;
@@ -395,7 +396,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct 
sctp_endpoint *ep,
        /* The call, sctp_process_init(), can fail on memory allocation.  */
        if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk),
                               (sctp_init_chunk_t *)chunk->chunk_hdr,
-                              GFP_ATOMIC))
+                              &init_net, GFP_ATOMIC))
                goto nomem_init;
 
        /* B) "Z" shall respond immediately with an INIT ACK chunk.  */
@@ -726,7 +727,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct 
sctp_endpoint *ep,
 
        if (!sctp_process_init(new_asoc, chunk,
                               &chunk->subh.cookie_hdr->c.peer_addr,
-                              peer_init, GFP_ATOMIC))
+                              peer_init, &init_net, GFP_ATOMIC))
                goto nomem_init;
 
        /* SCTP-AUTH:  Now that we've populate required fields in
@@ -1444,7 +1445,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
        if (!new_asoc)
                goto nomem;
 
-       if (sctp_assoc_set_bind_addr_from_ep(new_asoc,
+       if (sctp_assoc_set_bind_addr_from_ep(new_asoc, &init_net,
                                sctp_scope(sctp_source(chunk)), GFP_ATOMIC) < 0)
                goto nomem;
 
@@ -1454,7 +1455,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
         */
        if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk),
                               (sctp_init_chunk_t *)chunk->chunk_hdr,
-                              GFP_ATOMIC))
+                              &init_net, GFP_ATOMIC))
                goto nomem;
 
        /* Make sure no new addresses are being added during the
@@ -1682,7 +1683,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const 
struct sctp_endpoint *ep,
        peer_init = &chunk->subh.cookie_hdr->c.peer_init[0];
 
        if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk), peer_init,
-                              GFP_ATOMIC))
+                              &init_net, GFP_ATOMIC))
                goto nomem;
 
        /* Make sure no new addresses are being added during the
@@ -1777,7 +1778,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_b(const 
struct sctp_endpoint *ep,
         */
        peer_init = &chunk->subh.cookie_hdr->c.peer_init[0];
        if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk), peer_init,
-                              GFP_ATOMIC))
+                              &init_net, GFP_ATOMIC))
                goto nomem;
 
        /* Update the content of current association.  */
@@ -5918,7 +5919,8 @@ static struct sctp_packet *sctp_ootb_pkt_new(const struct 
sctp_association *asoc
        /* Cache a route for the transport with the chunk's destination as
         * the source address.
         */
-       sctp_transport_route(transport, (union sctp_addr *)&chunk->dest,
+       sctp_transport_route(&init_net, transport,
+                            (union sctp_addr *)&chunk->dest,
                             sctp_sk(*sctp_get_ctl_sock(&init_net)));
 
        packet = sctp_packet_init(&transport->packet, transport, sport, dport);
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 5e25981..790e597 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -101,8 +101,10 @@ static struct sctp_af *sctp_sockaddr_af(struct sctp_sock 
*opt,
                                        union sctp_addr *addr, int len);
 static int sctp_bindx_add(struct sock *, struct sockaddr *, int);
 static int sctp_bindx_rem(struct sock *, struct sockaddr *, int);
-static int sctp_send_asconf_add_ip(struct sock *, struct sockaddr *, int);
-static int sctp_send_asconf_del_ip(struct sock *, struct sockaddr *, int);
+static int sctp_send_asconf_add_ip(struct net*, struct sock *,
+                                  struct sockaddr *, int);
+static int sctp_send_asconf_del_ip(struct net*, struct sock *,
+                                  struct sockaddr *, int);
 static int sctp_send_asconf(struct sctp_association *asoc,
                            struct sctp_chunk *chunk);
 static int sctp_do_bind(struct sock *, union sctp_addr *, int);
@@ -197,7 +199,7 @@ static inline int sctp_verify_addr(struct sock *sk, union 
sctp_addr *addr,
        if (!af->addr_valid(addr, sctp_sk(sk), NULL))
                return -EINVAL;
 
-       if (!sctp_sk(sk)->pf->send_verify(sctp_sk(sk), (addr)))
+       if (!sctp_sk(sk)->pf->send_verify(sock_net(sk), sctp_sk(sk), (addr)))
                return -EINVAL;
 
        return 0;
@@ -360,7 +362,7 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union 
sctp_addr *addr, int len)
                                 len);
 
        /* PF specific bind() address verification. */
-       if (!sp->pf->bind_verify(sp, addr))
+       if (!sp->pf->bind_verify(sock_net(sk), sp, addr))
                return -EADDRNOTAVAIL;
 
        /* We must either be unbound, or bind to the same port.
@@ -511,7 +513,8 @@ err_bindx_add:
  *
  * Only sctp_setsockopt_bindx() is supposed to call this function.
  */
-static int sctp_send_asconf_add_ip(struct sock         *sk,
+static int sctp_send_asconf_add_ip(struct net          *net,
+                                  struct sock          *sk,
                                   struct sockaddr      *addrs,
                                   int                  addrcnt)
 {
@@ -608,7 +611,7 @@ static int sctp_send_asconf_add_ip(struct sock              
*sk,
                                trans->ssthresh = asoc->peer.i.a_rwnd;
                                trans->rto = asoc->rto_initial;
                                trans->rtt = trans->srtt = trans->rttvar = 0;
-                               sctp_transport_route(trans, NULL,
+                               sctp_transport_route(net, trans, NULL,
                                    sctp_sk(asoc->base.sk));
                        }
                }
@@ -713,7 +716,8 @@ err_bindx_rem:
  *
  * Only sctp_setsockopt_bindx() is supposed to call this function.
  */
-static int sctp_send_asconf_del_ip(struct sock         *sk,
+static int sctp_send_asconf_del_ip(struct net          *net,
+                                  struct sock          *sk,
                                   struct sockaddr      *addrs,
                                   int                  addrcnt)
 {
@@ -847,7 +851,7 @@ skip_mkasconf:
                list_for_each_entry(transport, &asoc->peer.transport_addr_list,
                                        transports) {
                        dst_release(transport->dst);
-                       sctp_transport_route(transport, NULL,
+                       sctp_transport_route(net, transport, NULL,
                                             sctp_sk(asoc->base.sk));
                }
 
@@ -861,7 +865,8 @@ out:
 }
 
 /* set addr events to assocs in the endpoint.  ep and addr_wq must be locked */
-int sctp_asconf_mgmt(struct sctp_sock *sp, struct sctp_sockaddr_entry *addrw)
+int sctp_asconf_mgmt(struct net *net, struct sctp_sock *sp,
+                    struct sctp_sockaddr_entry *addrw)
 {
        struct sock *sk = sctp_opt2sk(sp);
        union sctp_addr *addr;
@@ -877,9 +882,11 @@ int sctp_asconf_mgmt(struct sctp_sock *sp, struct 
sctp_sockaddr_entry *addrw)
                return -EINVAL;
 
        if (addrw->state == SCTP_ADDR_NEW)
-               return sctp_send_asconf_add_ip(sk, (struct sockaddr *)addr, 1);
+               return sctp_send_asconf_add_ip(net, sk,
+                                              (struct sockaddr *)addr, 1);
        else
-               return sctp_send_asconf_del_ip(sk, (struct sockaddr *)addr, 1);
+               return sctp_send_asconf_del_ip(net, sk,
+                                              (struct sockaddr *)addr, 1);
 }
 
 /* Helper for tunneling sctp_bindx() requests through sctp_setsockopt()
@@ -969,6 +976,7 @@ SCTP_STATIC int sctp_setsockopt_bindx(struct sock* sk,
        struct sockaddr *sa_addr;
        void *addr_buf;
        struct sctp_af *af;
+       struct net *net = sock_net(sk);
 
        SCTP_DEBUG_PRINTK("sctp_setsocktopt_bindx: sk %p addrs %p"
                          " addrs_size %d opt %d\n", sk, addrs, addrs_size, op);
@@ -1019,14 +1027,14 @@ SCTP_STATIC int sctp_setsockopt_bindx(struct sock* sk,
                err = sctp_bindx_add(sk, kaddrs, addrcnt);
                if (err)
                        goto out;
-               err = sctp_send_asconf_add_ip(sk, kaddrs, addrcnt);
+               err = sctp_send_asconf_add_ip(net, sk, kaddrs, addrcnt);
                break;
 
        case SCTP_BINDX_REM_ADDR:
                err = sctp_bindx_rem(sk, kaddrs, addrcnt);
                if (err)
                        goto out;
-               err = sctp_send_asconf_del_ip(sk, kaddrs, addrcnt);
+               err = sctp_send_asconf_del_ip(net, sk, kaddrs, addrcnt);
                break;
 
        default:
@@ -1170,8 +1178,9 @@ static int __sctp_connect(struct sock* sk,
                                goto out_free;
                        }
 
-                       err = sctp_assoc_set_bind_addr_from_ep(asoc, scope,
-                                                             GFP_KERNEL);
+                       err = sctp_assoc_set_bind_addr_from_ep(asoc,
+                                                       sock_net(sk),
+                                                       scope, GFP_KERNEL);
                        if (err < 0) {
                                goto out_free;
                        }
@@ -1797,7 +1806,8 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct 
sock *sk,
                        goto out_unlock;
                }
                asoc = new_asoc;
-               err = sctp_assoc_set_bind_addr_from_ep(asoc, scope, GFP_KERNEL);
+               err = sctp_assoc_set_bind_addr_from_ep(asoc, sock_net(sk),
+                                        scope, GFP_KERNEL);
                if (err < 0) {
                        err = -ENOMEM;
                        goto out_free;
@@ -2309,7 +2319,8 @@ static int sctp_setsockopt_autoclose(struct sock *sk, 
char __user *optval,
  *                     SPP_SACKDELAY_ENABLE, setting both will have undefined
  *                     results.
  */
-static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
+static int sctp_apply_peer_addr_params(struct net *net,
+                                      struct sctp_paddrparams *params,
                                       struct sctp_transport   *trans,
                                       struct sctp_association *asoc,
                                       struct sctp_sock        *sp,
@@ -2389,7 +2400,8 @@ static int sctp_apply_peer_addr_params(struct 
sctp_paddrparams *params,
                        trans->param_flags =
                                (trans->param_flags & ~SPP_PMTUD) | 
pmtud_change;
                        if (update) {
-                               sctp_transport_pmtu(trans, sctp_opt2sk(sp));
+                               sctp_transport_pmtu(net, trans,
+                                                   sctp_opt2sk(sp));
                                sctp_assoc_sync_pmtu(sctp_opt2sk(sp), asoc);
                        }
                } else if (asoc) {
@@ -2457,6 +2469,7 @@ static int sctp_setsockopt_peer_addr_params(struct sock 
*sk,
        struct sctp_transport   *trans = NULL;
        struct sctp_association *asoc = NULL;
        struct sctp_sock        *sp = sctp_sk(sk);
+       struct net              *net = sock_net(sk);
        int error;
        int hb_change, pmtud_change, sackdelay_change;
 
@@ -2504,7 +2517,7 @@ static int sctp_setsockopt_peer_addr_params(struct sock 
*sk,
                return -EINVAL;
 
        /* Process parameters. */
-       error = sctp_apply_peer_addr_params(&params, trans, asoc, sp,
+       error = sctp_apply_peer_addr_params(net, &params, trans, asoc, sp,
                                            hb_change, pmtud_change,
                                            sackdelay_change);
 
@@ -2517,8 +2530,8 @@ static int sctp_setsockopt_peer_addr_params(struct sock 
*sk,
        if (!trans && asoc) {
                list_for_each_entry(trans, &asoc->peer.transport_addr_list,
                                transports) {
-                       sctp_apply_peer_addr_params(&params, trans, asoc, sp,
-                                                   hb_change, pmtud_change,
+                       sctp_apply_peer_addr_params(net, &params, trans, asoc,
+                                                   sp, hb_change, pmtud_change,
                                                    sackdelay_change);
                }
        }
@@ -4653,9 +4666,11 @@ static int sctp_copy_laddrs(struct sock *sk, __u16 port, 
void *to,
        union sctp_addr temp;
        int cnt = 0;
        int addrlen;
+       struct sctp_net_params *net_params =
+               sctp_get_params(sock_net(sk));
 
        rcu_read_lock();
-       list_for_each_entry_rcu(addr, &sctp_local_addr_list, list) {
+       list_for_each_entry_rcu(addr, &net_params->local_addr_list, list) {
                if (!addr->valid)
                        continue;
 
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index c97472b..856ba86 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -214,12 +214,14 @@ void sctp_transport_set_owner(struct sctp_transport 
*transport,
 }
 
 /* Initialize the pmtu of a transport. */
-void sctp_transport_pmtu(struct sctp_transport *transport, struct sock *sk)
+void sctp_transport_pmtu(struct net *net, struct sctp_transport *transport,
+                        struct sock *sk)
 {
        /* If we don't have a fresh route, look one up */
        if (!transport->dst || transport->dst->obsolete) {
                dst_release(transport->dst);
-               transport->af_specific->get_dst(transport, &transport->saddr,
+               transport->af_specific->get_dst(net, transport,
+                                               &transport->saddr,
                                                &transport->fl, sk);
        }
 
@@ -247,27 +249,28 @@ void sctp_transport_update_pmtu(struct sock *sk, struct 
sctp_transport *t, u32 p
 
        dst = sctp_transport_dst_check(t);
        if (!dst)
-               t->af_specific->get_dst(t, &t->saddr, &t->fl, sk);
+               t->af_specific->get_dst(sock_net(sk), t, &t->saddr, &t->fl, sk);
 
        if (dst) {
                dst->ops->update_pmtu(dst, sk, NULL, pmtu);
 
                dst = sctp_transport_dst_check(t);
                if (!dst)
-                       t->af_specific->get_dst(t, &t->saddr, &t->fl, sk);
+                       t->af_specific->get_dst(sock_net(sk), t, &t->saddr,
+                                               &t->fl, sk);
        }
 }
 
 /* Caches the dst entry and source address for a transport's destination
  * address.
  */
-void sctp_transport_route(struct sctp_transport *transport,
+void sctp_transport_route(struct net *net, struct sctp_transport *transport,
                          union sctp_addr *saddr, struct sctp_sock *opt)
 {
        struct sctp_association *asoc = transport->asoc;
        struct sctp_af *af = transport->af_specific;
 
-       af->get_dst(transport, saddr, &transport->fl, sctp_opt2sk(opt));
+       af->get_dst(net, transport, saddr, &transport->fl, sctp_opt2sk(opt));
 
        if (saddr)
                memcpy(&transport->saddr, saddr, sizeof(union sctp_addr));
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to