aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/socket.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2012-08-06 04:39:38 -0400
committerDavid S. Miller <davem@davemloft.net>2012-08-15 01:44:12 -0400
commitf1f4376307ca45558eb22487022aefceed7385e8 (patch)
treeeb4a61a314b8a5176ff5f17ab803c5fd0c9579f5 /net/sctp/socket.c
parenteea68e2f1a0061e09265992b91fdc0014930ae92 (diff)
sctp: Make the port hash table use struct net in it's key.
- Add struct net into the port hash table hash calculation - Add struct net inot the struct sctp_bind_bucket so there is a memory of which network namespace a port is allocated in. No need for a ref count because sctp_bind_bucket only exists when there are sockets in the hash table and sockets can not change their network namspace, and sockets already ref count their network namespace. - Add struct net into the key comparison when we are testing to see if we have found the port hash table entry we are looking for. With these changes lookups in the port hash table becomes safe to use in multiple network namespaces. Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> Acked-by: Vlad Yasevich <vyasevich@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r--net/sctp/socket.c22
1 files changed, 13 insertions, 9 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 5e259817a7f3..4316b0f988d4 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -5769,7 +5769,7 @@ static void sctp_unhash(struct sock *sk)
5769 * a fastreuse flag (FIXME: NPI ipg). 5769 * a fastreuse flag (FIXME: NPI ipg).
5770 */ 5770 */
5771static struct sctp_bind_bucket *sctp_bucket_create( 5771static struct sctp_bind_bucket *sctp_bucket_create(
5772 struct sctp_bind_hashbucket *head, unsigned short snum); 5772 struct sctp_bind_hashbucket *head, struct net *, unsigned short snum);
5773 5773
5774static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr) 5774static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr)
5775{ 5775{
@@ -5799,11 +5799,12 @@ static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr)
5799 rover = low; 5799 rover = low;
5800 if (inet_is_reserved_local_port(rover)) 5800 if (inet_is_reserved_local_port(rover))
5801 continue; 5801 continue;
5802 index = sctp_phashfn(rover); 5802 index = sctp_phashfn(sock_net(sk), rover);
5803 head = &sctp_port_hashtable[index]; 5803 head = &sctp_port_hashtable[index];
5804 sctp_spin_lock(&head->lock); 5804 sctp_spin_lock(&head->lock);
5805 sctp_for_each_hentry(pp, node, &head->chain) 5805 sctp_for_each_hentry(pp, node, &head->chain)
5806 if (pp->port == rover) 5806 if ((pp->port == rover) &&
5807 net_eq(sock_net(sk), pp->net))
5807 goto next; 5808 goto next;
5808 break; 5809 break;
5809 next: 5810 next:
@@ -5827,10 +5828,10 @@ static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr)
5827 * to the port number (snum) - we detect that with the 5828 * to the port number (snum) - we detect that with the
5828 * port iterator, pp being NULL. 5829 * port iterator, pp being NULL.
5829 */ 5830 */
5830 head = &sctp_port_hashtable[sctp_phashfn(snum)]; 5831 head = &sctp_port_hashtable[sctp_phashfn(sock_net(sk), snum)];
5831 sctp_spin_lock(&head->lock); 5832 sctp_spin_lock(&head->lock);
5832 sctp_for_each_hentry(pp, node, &head->chain) { 5833 sctp_for_each_hentry(pp, node, &head->chain) {
5833 if (pp->port == snum) 5834 if ((pp->port == snum) && net_eq(pp->net, sock_net(sk)))
5834 goto pp_found; 5835 goto pp_found;
5835 } 5836 }
5836 } 5837 }
@@ -5881,7 +5882,7 @@ pp_found:
5881pp_not_found: 5882pp_not_found:
5882 /* If there was a hash table miss, create a new port. */ 5883 /* If there was a hash table miss, create a new port. */
5883 ret = 1; 5884 ret = 1;
5884 if (!pp && !(pp = sctp_bucket_create(head, snum))) 5885 if (!pp && !(pp = sctp_bucket_create(head, sock_net(sk), snum)))
5885 goto fail_unlock; 5886 goto fail_unlock;
5886 5887
5887 /* In either case (hit or miss), make sure fastreuse is 1 only 5888 /* In either case (hit or miss), make sure fastreuse is 1 only
@@ -6113,7 +6114,7 @@ unsigned int sctp_poll(struct file *file, struct socket *sock, poll_table *wait)
6113 ********************************************************************/ 6114 ********************************************************************/
6114 6115
6115static struct sctp_bind_bucket *sctp_bucket_create( 6116static struct sctp_bind_bucket *sctp_bucket_create(
6116 struct sctp_bind_hashbucket *head, unsigned short snum) 6117 struct sctp_bind_hashbucket *head, struct net *net, unsigned short snum)
6117{ 6118{
6118 struct sctp_bind_bucket *pp; 6119 struct sctp_bind_bucket *pp;
6119 6120
@@ -6123,6 +6124,7 @@ static struct sctp_bind_bucket *sctp_bucket_create(
6123 pp->port = snum; 6124 pp->port = snum;
6124 pp->fastreuse = 0; 6125 pp->fastreuse = 0;
6125 INIT_HLIST_HEAD(&pp->owner); 6126 INIT_HLIST_HEAD(&pp->owner);
6127 pp->net = net;
6126 hlist_add_head(&pp->node, &head->chain); 6128 hlist_add_head(&pp->node, &head->chain);
6127 } 6129 }
6128 return pp; 6130 return pp;
@@ -6142,7 +6144,8 @@ static void sctp_bucket_destroy(struct sctp_bind_bucket *pp)
6142static inline void __sctp_put_port(struct sock *sk) 6144static inline void __sctp_put_port(struct sock *sk)
6143{ 6145{
6144 struct sctp_bind_hashbucket *head = 6146 struct sctp_bind_hashbucket *head =
6145 &sctp_port_hashtable[sctp_phashfn(inet_sk(sk)->inet_num)]; 6147 &sctp_port_hashtable[sctp_phashfn(sock_net(sk),
6148 inet_sk(sk)->inet_num)];
6146 struct sctp_bind_bucket *pp; 6149 struct sctp_bind_bucket *pp;
6147 6150
6148 sctp_spin_lock(&head->lock); 6151 sctp_spin_lock(&head->lock);
@@ -6809,7 +6812,8 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
6809 newsp->hmac = NULL; 6812 newsp->hmac = NULL;
6810 6813
6811 /* Hook this new socket in to the bind_hash list. */ 6814 /* Hook this new socket in to the bind_hash list. */
6812 head = &sctp_port_hashtable[sctp_phashfn(inet_sk(oldsk)->inet_num)]; 6815 head = &sctp_port_hashtable[sctp_phashfn(sock_net(oldsk),
6816 inet_sk(oldsk)->inet_num)];
6813 sctp_local_bh_disable(); 6817 sctp_local_bh_disable();
6814 sctp_spin_lock(&head->lock); 6818 sctp_spin_lock(&head->lock);
6815 pp = sctp_sk(oldsk)->bind_hash; 6819 pp = sctp_sk(oldsk)->bind_hash;