diff options
| -rw-r--r-- | include/net/sctp/sctp.h | 4 | ||||
| -rw-r--r-- | include/net/sctp/structs.h | 1 | ||||
| -rw-r--r-- | net/sctp/socket.c | 22 |
3 files changed, 16 insertions, 11 deletions
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index ff499640528b..7c0504034583 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h | |||
| @@ -632,9 +632,9 @@ static inline int sctp_sanity_check(void) | |||
| 632 | 632 | ||
| 633 | /* Warning: The following hash functions assume a power of two 'size'. */ | 633 | /* Warning: The following hash functions assume a power of two 'size'. */ |
| 634 | /* This is the hash function for the SCTP port hash table. */ | 634 | /* This is the hash function for the SCTP port hash table. */ |
| 635 | static inline int sctp_phashfn(__u16 lport) | 635 | static inline int sctp_phashfn(struct net *net, __u16 lport) |
| 636 | { | 636 | { |
| 637 | return lport & (sctp_port_hashsize - 1); | 637 | return (net_hash_mix(net) + lport) & (sctp_port_hashsize - 1); |
| 638 | } | 638 | } |
| 639 | 639 | ||
| 640 | /* This is the hash function for the endpoint hash table. */ | 640 | /* This is the hash function for the endpoint hash table. */ |
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index fc5e60016e37..c089bb12af77 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
| @@ -102,6 +102,7 @@ struct sctp_bind_bucket { | |||
| 102 | unsigned short fastreuse; | 102 | unsigned short fastreuse; |
| 103 | struct hlist_node node; | 103 | struct hlist_node node; |
| 104 | struct hlist_head owner; | 104 | struct hlist_head owner; |
| 105 | struct net *net; | ||
| 105 | }; | 106 | }; |
| 106 | 107 | ||
| 107 | struct sctp_bind_hashbucket { | 108 | struct sctp_bind_hashbucket { |
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 | */ |
| 5771 | static struct sctp_bind_bucket *sctp_bucket_create( | 5771 | static 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 | ||
| 5774 | static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr) | 5774 | static 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: | |||
| 5881 | pp_not_found: | 5882 | pp_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 | ||
| 6115 | static struct sctp_bind_bucket *sctp_bucket_create( | 6116 | static 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) | |||
| 6142 | static inline void __sctp_put_port(struct sock *sk) | 6144 | static 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; |
