Commit 4db67e80 authored by Eric W. Biederman's avatar Eric W. Biederman Committed by David S. Miller

sctp: Make the address lists per network namespace

- Move the address lists into struct net
- Add per network namespace initialization and cleanup
- Pass around struct net so it is everywhere I need it.
- Rename all of the global variable references into references
  to the variables moved into struct net
Signed-off-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
Acked-by: default avatarVlad Yasevich <vyasevich@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4110cc25
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <net/netns/packet.h> #include <net/netns/packet.h>
#include <net/netns/ipv4.h> #include <net/netns/ipv4.h>
#include <net/netns/ipv6.h> #include <net/netns/ipv6.h>
#include <net/netns/sctp.h>
#include <net/netns/dccp.h> #include <net/netns/dccp.h>
#include <net/netns/x_tables.h> #include <net/netns/x_tables.h>
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
...@@ -81,6 +82,9 @@ struct net { ...@@ -81,6 +82,9 @@ struct net {
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
struct netns_ipv6 ipv6; struct netns_ipv6 ipv6;
#endif #endif
#if defined(CONFIG_IP_SCTP) || defined(CONFIG_IP_SCTP_MODULE)
struct netns_sctp sctp;
#endif
#if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE) #if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE)
struct netns_dccp dccp; struct netns_dccp dccp;
#endif #endif
......
#ifndef __NETNS_SCTP_H__
#define __NETNS_SCTP_H__
struct netns_sctp {
/* This is the global local address list.
* We actively maintain this complete list of addresses on
* the system by catching address add/delete events.
*
* It is a list of sctp_sockaddr_entry.
*/
struct list_head local_addr_list;
struct list_head addr_waitq;
struct timer_list addr_wq_timer;
struct list_head auto_asconf_splist;
spinlock_t addr_wq_lock;
/* Lock that protects the local_addr_list writers */
spinlock_t local_addr_lock;
};
#endif /* __NETNS_SCTP_H__ */
...@@ -115,12 +115,12 @@ ...@@ -115,12 +115,12 @@
* sctp/protocol.c * sctp/protocol.c
*/ */
extern struct sock *sctp_get_ctl_sock(void); extern struct sock *sctp_get_ctl_sock(void);
extern int sctp_copy_local_addr_list(struct sctp_bind_addr *, extern int sctp_copy_local_addr_list(struct net *, struct sctp_bind_addr *,
sctp_scope_t, gfp_t gfp, sctp_scope_t, gfp_t gfp,
int flags); int flags);
extern struct sctp_pf *sctp_get_pf_specific(sa_family_t family); extern struct sctp_pf *sctp_get_pf_specific(sa_family_t family);
extern int sctp_register_pf(struct sctp_pf *, sa_family_t); 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 * sctp/socket.c
......
...@@ -205,21 +205,7 @@ extern struct sctp_globals { ...@@ -205,21 +205,7 @@ extern struct sctp_globals {
int port_hashsize; int port_hashsize;
struct sctp_bind_hashbucket *port_hashtable; struct sctp_bind_hashbucket *port_hashtable;
/* This is the global local address list.
* We actively maintain this complete list of addresses on
* the system by catching address add/delete events.
*
* It is a list of sctp_sockaddr_entry.
*/
struct list_head local_addr_list;
int default_auto_asconf; int default_auto_asconf;
struct list_head addr_waitq;
struct timer_list addr_wq_timer;
struct list_head auto_asconf_splist;
spinlock_t addr_wq_lock;
/* Lock that protects the local_addr_list writers */
spinlock_t addr_list_lock;
/* Flag to indicate if addip is enabled. */ /* Flag to indicate if addip is enabled. */
int addip_enable; int addip_enable;
...@@ -278,12 +264,6 @@ extern struct sctp_globals { ...@@ -278,12 +264,6 @@ extern struct sctp_globals {
#define sctp_assoc_hashtable (sctp_globals.assoc_hashtable) #define sctp_assoc_hashtable (sctp_globals.assoc_hashtable)
#define sctp_port_hashsize (sctp_globals.port_hashsize) #define sctp_port_hashsize (sctp_globals.port_hashsize)
#define sctp_port_hashtable (sctp_globals.port_hashtable) #define sctp_port_hashtable (sctp_globals.port_hashtable)
#define sctp_local_addr_list (sctp_globals.local_addr_list)
#define sctp_local_addr_lock (sctp_globals.addr_list_lock)
#define sctp_auto_asconf_splist (sctp_globals.auto_asconf_splist)
#define sctp_addr_waitq (sctp_globals.addr_waitq)
#define sctp_addr_wq_timer (sctp_globals.addr_wq_timer)
#define sctp_addr_wq_lock (sctp_globals.addr_wq_lock)
#define sctp_default_auto_asconf (sctp_globals.default_auto_asconf) #define sctp_default_auto_asconf (sctp_globals.default_auto_asconf)
#define sctp_scope_policy (sctp_globals.ipv4_scope_policy) #define sctp_scope_policy (sctp_globals.ipv4_scope_policy)
#define sctp_addip_enable (sctp_globals.addip_enable) #define sctp_addip_enable (sctp_globals.addip_enable)
...@@ -1241,7 +1221,7 @@ struct sctp_bind_addr { ...@@ -1241,7 +1221,7 @@ struct sctp_bind_addr {
void sctp_bind_addr_init(struct sctp_bind_addr *, __u16 port); void sctp_bind_addr_init(struct sctp_bind_addr *, __u16 port);
void sctp_bind_addr_free(struct sctp_bind_addr *); void sctp_bind_addr_free(struct sctp_bind_addr *);
int sctp_bind_addr_copy(struct sctp_bind_addr *dest, int sctp_bind_addr_copy(struct net *net, struct sctp_bind_addr *dest,
const struct sctp_bind_addr *src, const struct sctp_bind_addr *src,
sctp_scope_t scope, gfp_t gfp, sctp_scope_t scope, gfp_t gfp,
int flags); int flags);
......
...@@ -1544,7 +1544,8 @@ int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc, ...@@ -1544,7 +1544,8 @@ int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc,
if (asoc->peer.ipv6_address) if (asoc->peer.ipv6_address)
flags |= SCTP_ADDR6_PEERSUPP; flags |= SCTP_ADDR6_PEERSUPP;
return sctp_bind_addr_copy(&asoc->base.bind_addr, return sctp_bind_addr_copy(sock_net(asoc->base.sk),
&asoc->base.bind_addr,
&asoc->ep->base.bind_addr, &asoc->ep->base.bind_addr,
scope, gfp, flags); scope, gfp, flags);
} }
......
...@@ -52,8 +52,8 @@ ...@@ -52,8 +52,8 @@
#include <net/sctp/sm.h> #include <net/sctp/sm.h>
/* Forward declarations for internal helpers. */ /* Forward declarations for internal helpers. */
static int sctp_copy_one_addr(struct sctp_bind_addr *, union sctp_addr *, static int sctp_copy_one_addr(struct net *, struct sctp_bind_addr *,
sctp_scope_t scope, gfp_t gfp, union sctp_addr *, sctp_scope_t scope, gfp_t gfp,
int flags); int flags);
static void sctp_bind_addr_clean(struct sctp_bind_addr *); static void sctp_bind_addr_clean(struct sctp_bind_addr *);
...@@ -62,7 +62,7 @@ static void sctp_bind_addr_clean(struct sctp_bind_addr *); ...@@ -62,7 +62,7 @@ static void sctp_bind_addr_clean(struct sctp_bind_addr *);
/* Copy 'src' to 'dest' taking 'scope' into account. Omit addresses /* Copy 'src' to 'dest' taking 'scope' into account. Omit addresses
* in 'src' which have a broader scope than 'scope'. * in 'src' which have a broader scope than 'scope'.
*/ */
int sctp_bind_addr_copy(struct sctp_bind_addr *dest, int sctp_bind_addr_copy(struct net *net, struct sctp_bind_addr *dest,
const struct sctp_bind_addr *src, const struct sctp_bind_addr *src,
sctp_scope_t scope, gfp_t gfp, sctp_scope_t scope, gfp_t gfp,
int flags) int flags)
...@@ -75,7 +75,7 @@ int sctp_bind_addr_copy(struct sctp_bind_addr *dest, ...@@ -75,7 +75,7 @@ int sctp_bind_addr_copy(struct sctp_bind_addr *dest,
/* Extract the addresses which are relevant for this scope. */ /* Extract the addresses which are relevant for this scope. */
list_for_each_entry(addr, &src->address_list, list) { list_for_each_entry(addr, &src->address_list, list) {
error = sctp_copy_one_addr(dest, &addr->a, scope, error = sctp_copy_one_addr(net, dest, &addr->a, scope,
gfp, flags); gfp, flags);
if (error < 0) if (error < 0)
goto out; goto out;
...@@ -87,7 +87,7 @@ int sctp_bind_addr_copy(struct sctp_bind_addr *dest, ...@@ -87,7 +87,7 @@ int sctp_bind_addr_copy(struct sctp_bind_addr *dest,
*/ */
if (list_empty(&dest->address_list) && (SCTP_SCOPE_GLOBAL == scope)) { if (list_empty(&dest->address_list) && (SCTP_SCOPE_GLOBAL == scope)) {
list_for_each_entry(addr, &src->address_list, list) { list_for_each_entry(addr, &src->address_list, list) {
error = sctp_copy_one_addr(dest, &addr->a, error = sctp_copy_one_addr(net, dest, &addr->a,
SCTP_SCOPE_LINK, gfp, SCTP_SCOPE_LINK, gfp,
flags); flags);
if (error < 0) if (error < 0)
...@@ -448,7 +448,7 @@ union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr *bp, ...@@ -448,7 +448,7 @@ union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr *bp,
} }
/* Copy out addresses from the global local address list. */ /* Copy out addresses from the global local address list. */
static int sctp_copy_one_addr(struct sctp_bind_addr *dest, static int sctp_copy_one_addr(struct net *net, struct sctp_bind_addr *dest,
union sctp_addr *addr, union sctp_addr *addr,
sctp_scope_t scope, gfp_t gfp, sctp_scope_t scope, gfp_t gfp,
int flags) int flags)
...@@ -456,7 +456,7 @@ static int sctp_copy_one_addr(struct sctp_bind_addr *dest, ...@@ -456,7 +456,7 @@ static int sctp_copy_one_addr(struct sctp_bind_addr *dest,
int error = 0; int error = 0;
if (sctp_is_any(NULL, addr)) { if (sctp_is_any(NULL, addr)) {
error = sctp_copy_local_addr_list(dest, scope, gfp, flags); error = sctp_copy_local_addr_list(net, dest, scope, gfp, flags);
} else if (sctp_in_scope(addr, scope)) { } else if (sctp_in_scope(addr, scope)) {
/* Now that the address is in scope, check to see if /* Now that the address is in scope, check to see if
* the address type is supported by local sock as * the address type is supported by local sock as
......
...@@ -99,6 +99,7 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev, ...@@ -99,6 +99,7 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev,
struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr; struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
struct sctp_sockaddr_entry *addr = NULL; struct sctp_sockaddr_entry *addr = NULL;
struct sctp_sockaddr_entry *temp; struct sctp_sockaddr_entry *temp;
struct net *net = dev_net(ifa->idev->dev);
int found = 0; int found = 0;
switch (ev) { switch (ev) {
...@@ -110,27 +111,27 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev, ...@@ -110,27 +111,27 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev,
addr->a.v6.sin6_addr = ifa->addr; addr->a.v6.sin6_addr = ifa->addr;
addr->a.v6.sin6_scope_id = ifa->idev->dev->ifindex; addr->a.v6.sin6_scope_id = ifa->idev->dev->ifindex;
addr->valid = 1; addr->valid = 1;
spin_lock_bh(&sctp_local_addr_lock); spin_lock_bh(&net->sctp.local_addr_lock);
list_add_tail_rcu(&addr->list, &sctp_local_addr_list); list_add_tail_rcu(&addr->list, &net->sctp.local_addr_list);
sctp_addr_wq_mgmt(addr, SCTP_ADDR_NEW); sctp_addr_wq_mgmt(net, addr, SCTP_ADDR_NEW);
spin_unlock_bh(&sctp_local_addr_lock); spin_unlock_bh(&net->sctp.local_addr_lock);
} }
break; break;
case NETDEV_DOWN: case NETDEV_DOWN:
spin_lock_bh(&sctp_local_addr_lock); spin_lock_bh(&net->sctp.local_addr_lock);
list_for_each_entry_safe(addr, temp, list_for_each_entry_safe(addr, temp,
&sctp_local_addr_list, list) { &net->sctp.local_addr_list, list) {
if (addr->a.sa.sa_family == AF_INET6 && if (addr->a.sa.sa_family == AF_INET6 &&
ipv6_addr_equal(&addr->a.v6.sin6_addr, ipv6_addr_equal(&addr->a.v6.sin6_addr,
&ifa->addr)) { &ifa->addr)) {
sctp_addr_wq_mgmt(addr, SCTP_ADDR_DEL); sctp_addr_wq_mgmt(net, addr, SCTP_ADDR_DEL);
found = 1; found = 1;
addr->valid = 0; addr->valid = 0;
list_del_rcu(&addr->list); list_del_rcu(&addr->list);
break; break;
} }
} }
spin_unlock_bh(&sctp_local_addr_lock); spin_unlock_bh(&net->sctp.local_addr_lock);
if (found) if (found)
kfree_rcu(addr, rcu); kfree_rcu(addr, rcu);
break; break;
......
This diff is collapsed.
...@@ -3471,7 +3471,7 @@ static int sctp_setsockopt_auto_asconf(struct sock *sk, char __user *optval, ...@@ -3471,7 +3471,7 @@ static int sctp_setsockopt_auto_asconf(struct sock *sk, char __user *optval,
sp->do_auto_asconf = 0; sp->do_auto_asconf = 0;
} else if (val && !sp->do_auto_asconf) { } else if (val && !sp->do_auto_asconf) {
list_add_tail(&sp->auto_asconf_list, list_add_tail(&sp->auto_asconf_list,
&sctp_auto_asconf_splist); &sock_net(sk)->sctp.auto_asconf_splist);
sp->do_auto_asconf = 1; sp->do_auto_asconf = 1;
} }
return 0; return 0;
...@@ -3964,7 +3964,7 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) ...@@ -3964,7 +3964,7 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
if (sctp_default_auto_asconf) { if (sctp_default_auto_asconf) {
list_add_tail(&sp->auto_asconf_list, list_add_tail(&sp->auto_asconf_list,
&sctp_auto_asconf_splist); &sock_net(sk)->sctp.auto_asconf_splist);
sp->do_auto_asconf = 1; sp->do_auto_asconf = 1;
} else } else
sp->do_auto_asconf = 0; sp->do_auto_asconf = 0;
...@@ -4653,9 +4653,10 @@ static int sctp_copy_laddrs(struct sock *sk, __u16 port, void *to, ...@@ -4653,9 +4653,10 @@ static int sctp_copy_laddrs(struct sock *sk, __u16 port, void *to,
union sctp_addr temp; union sctp_addr temp;
int cnt = 0; int cnt = 0;
int addrlen; int addrlen;
struct net *net = sock_net(sk);
rcu_read_lock(); rcu_read_lock();
list_for_each_entry_rcu(addr, &sctp_local_addr_list, list) { list_for_each_entry_rcu(addr, &net->sctp.local_addr_list, list) {
if (!addr->valid) if (!addr->valid)
continue; continue;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment