sctp: move hlist_node and hashent out of sctp_ep_common
[ Upstream commit3d3b2f57d4
] Struct sctp_ep_common is included in both asoc and ep, but hlist_node and hashent are only needed by ep after asoc_hashtable was dropped by Commitb5eff71283
("sctp: drop the old assoc hashtable of sctp"). So it is better to move hlist_node and hashent from sctp_ep_common to sctp_endpoint, and it saves some space for each asoc. Signed-off-by: Xin Long <lucien.xin@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net> Stable-dep-of: 9ab0faa7f9ff ("sctp: Fix null-ptr-deref in reuseport_add_sock().") Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Родитель
e0c647c1c8
Коммит
83f1d094e8
|
@ -509,8 +509,8 @@ static inline int sctp_ep_hashfn(struct net *net, __u16 lport)
|
|||
return (net_hash_mix(net) + lport) & (sctp_ep_hashsize - 1);
|
||||
}
|
||||
|
||||
#define sctp_for_each_hentry(epb, head) \
|
||||
hlist_for_each_entry(epb, head, node)
|
||||
#define sctp_for_each_hentry(ep, head) \
|
||||
hlist_for_each_entry(ep, head, node)
|
||||
|
||||
/* Is a socket of this style? */
|
||||
#define sctp_style(sk, style) __sctp_style((sk), (SCTP_SOCKET_##style))
|
||||
|
|
|
@ -1244,10 +1244,6 @@ enum sctp_endpoint_type {
|
|||
*/
|
||||
|
||||
struct sctp_ep_common {
|
||||
/* Fields to help us manage our entries in the hash tables. */
|
||||
struct hlist_node node;
|
||||
int hashent;
|
||||
|
||||
/* Runtime type information. What kind of endpoint is this? */
|
||||
enum sctp_endpoint_type type;
|
||||
|
||||
|
@ -1299,6 +1295,10 @@ struct sctp_endpoint {
|
|||
/* Common substructure for endpoint and association. */
|
||||
struct sctp_ep_common base;
|
||||
|
||||
/* Fields to help us manage our entries in the hash tables. */
|
||||
struct hlist_node node;
|
||||
int hashent;
|
||||
|
||||
/* Associations: A list of current associations and mappings
|
||||
* to the data consumers for each association. This
|
||||
* may be in the form of a hash table or other
|
||||
|
|
|
@ -748,23 +748,21 @@ static int __sctp_hash_endpoint(struct sctp_endpoint *ep)
|
|||
struct sock *sk = ep->base.sk;
|
||||
struct net *net = sock_net(sk);
|
||||
struct sctp_hashbucket *head;
|
||||
struct sctp_ep_common *epb;
|
||||
|
||||
epb = &ep->base;
|
||||
epb->hashent = sctp_ep_hashfn(net, epb->bind_addr.port);
|
||||
head = &sctp_ep_hashtable[epb->hashent];
|
||||
ep->hashent = sctp_ep_hashfn(net, ep->base.bind_addr.port);
|
||||
head = &sctp_ep_hashtable[ep->hashent];
|
||||
|
||||
if (sk->sk_reuseport) {
|
||||
bool any = sctp_is_ep_boundall(sk);
|
||||
struct sctp_ep_common *epb2;
|
||||
struct sctp_endpoint *ep2;
|
||||
struct list_head *list;
|
||||
int cnt = 0, err = 1;
|
||||
|
||||
list_for_each(list, &ep->base.bind_addr.address_list)
|
||||
cnt++;
|
||||
|
||||
sctp_for_each_hentry(epb2, &head->chain) {
|
||||
struct sock *sk2 = epb2->sk;
|
||||
sctp_for_each_hentry(ep2, &head->chain) {
|
||||
struct sock *sk2 = ep2->base.sk;
|
||||
|
||||
if (!net_eq(sock_net(sk2), net) || sk2 == sk ||
|
||||
!uid_eq(sock_i_uid(sk2), sock_i_uid(sk)) ||
|
||||
|
@ -791,7 +789,7 @@ static int __sctp_hash_endpoint(struct sctp_endpoint *ep)
|
|||
}
|
||||
|
||||
write_lock(&head->lock);
|
||||
hlist_add_head(&epb->node, &head->chain);
|
||||
hlist_add_head(&ep->node, &head->chain);
|
||||
write_unlock(&head->lock);
|
||||
return 0;
|
||||
}
|
||||
|
@ -813,19 +811,16 @@ static void __sctp_unhash_endpoint(struct sctp_endpoint *ep)
|
|||
{
|
||||
struct sock *sk = ep->base.sk;
|
||||
struct sctp_hashbucket *head;
|
||||
struct sctp_ep_common *epb;
|
||||
|
||||
epb = &ep->base;
|
||||
ep->hashent = sctp_ep_hashfn(sock_net(sk), ep->base.bind_addr.port);
|
||||
|
||||
epb->hashent = sctp_ep_hashfn(sock_net(sk), epb->bind_addr.port);
|
||||
|
||||
head = &sctp_ep_hashtable[epb->hashent];
|
||||
head = &sctp_ep_hashtable[ep->hashent];
|
||||
|
||||
if (rcu_access_pointer(sk->sk_reuseport_cb))
|
||||
reuseport_detach_sock(sk);
|
||||
|
||||
write_lock(&head->lock);
|
||||
hlist_del_init(&epb->node);
|
||||
hlist_del_init(&ep->node);
|
||||
write_unlock(&head->lock);
|
||||
}
|
||||
|
||||
|
@ -858,7 +853,6 @@ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(
|
|||
const union sctp_addr *paddr)
|
||||
{
|
||||
struct sctp_hashbucket *head;
|
||||
struct sctp_ep_common *epb;
|
||||
struct sctp_endpoint *ep;
|
||||
struct sock *sk;
|
||||
__be16 lport;
|
||||
|
@ -868,8 +862,7 @@ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(
|
|||
hash = sctp_ep_hashfn(net, ntohs(lport));
|
||||
head = &sctp_ep_hashtable[hash];
|
||||
read_lock(&head->lock);
|
||||
sctp_for_each_hentry(epb, &head->chain) {
|
||||
ep = sctp_ep(epb);
|
||||
sctp_for_each_hentry(ep, &head->chain) {
|
||||
if (sctp_endpoint_is_match(ep, net, laddr))
|
||||
goto hit;
|
||||
}
|
||||
|
|
|
@ -161,7 +161,6 @@ static void *sctp_eps_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
|||
static int sctp_eps_seq_show(struct seq_file *seq, void *v)
|
||||
{
|
||||
struct sctp_hashbucket *head;
|
||||
struct sctp_ep_common *epb;
|
||||
struct sctp_endpoint *ep;
|
||||
struct sock *sk;
|
||||
int hash = *(loff_t *)v;
|
||||
|
@ -171,18 +170,17 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v)
|
|||
|
||||
head = &sctp_ep_hashtable[hash];
|
||||
read_lock_bh(&head->lock);
|
||||
sctp_for_each_hentry(epb, &head->chain) {
|
||||
ep = sctp_ep(epb);
|
||||
sk = epb->sk;
|
||||
sctp_for_each_hentry(ep, &head->chain) {
|
||||
sk = ep->base.sk;
|
||||
if (!net_eq(sock_net(sk), seq_file_net(seq)))
|
||||
continue;
|
||||
seq_printf(seq, "%8pK %8pK %-3d %-3d %-4d %-5d %5u %5lu ", ep, sk,
|
||||
sctp_sk(sk)->type, sk->sk_state, hash,
|
||||
epb->bind_addr.port,
|
||||
ep->base.bind_addr.port,
|
||||
from_kuid_munged(seq_user_ns(seq), sock_i_uid(sk)),
|
||||
sock_i_ino(sk));
|
||||
|
||||
sctp_seq_dump_local_addrs(seq, epb);
|
||||
sctp_seq_dump_local_addrs(seq, &ep->base);
|
||||
seq_printf(seq, "\n");
|
||||
}
|
||||
read_unlock_bh(&head->lock);
|
||||
|
|
|
@ -5303,14 +5303,14 @@ int sctp_for_each_endpoint(int (*cb)(struct sctp_endpoint *, void *),
|
|||
void *p) {
|
||||
int err = 0;
|
||||
int hash = 0;
|
||||
struct sctp_ep_common *epb;
|
||||
struct sctp_endpoint *ep;
|
||||
struct sctp_hashbucket *head;
|
||||
|
||||
for (head = sctp_ep_hashtable; hash < sctp_ep_hashsize;
|
||||
hash++, head++) {
|
||||
read_lock_bh(&head->lock);
|
||||
sctp_for_each_hentry(epb, &head->chain) {
|
||||
err = cb(sctp_ep(epb), p);
|
||||
sctp_for_each_hentry(ep, &head->chain) {
|
||||
err = cb(ep, p);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче