| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* SCTP kernel implementation |
|---|
| 2 | 3 | * (C) Copyright Red Hat Inc. 2017 |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * This file is part of the SCTP kernel implementation |
|---|
| 5 | 6 | * |
|---|
| 6 | 7 | * These functions implement sctp diag support. |
|---|
| 7 | | - * |
|---|
| 8 | | - * This SCTP implementation is free software; |
|---|
| 9 | | - * you can redistribute it and/or modify it under the terms of |
|---|
| 10 | | - * the GNU General Public License as published by |
|---|
| 11 | | - * the Free Software Foundation; either version 2, or (at your option) |
|---|
| 12 | | - * any later version. |
|---|
| 13 | | - * |
|---|
| 14 | | - * This SCTP implementation is distributed in the hope that it |
|---|
| 15 | | - * will be useful, but WITHOUT ANY WARRANTY; without even the implied |
|---|
| 16 | | - * ************************ |
|---|
| 17 | | - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|---|
| 18 | | - * See the GNU General Public License for more details. |
|---|
| 19 | | - * |
|---|
| 20 | | - * You should have received a copy of the GNU General Public License |
|---|
| 21 | | - * along with GNU CC; see the file COPYING. If not, see |
|---|
| 22 | | - * <http://www.gnu.org/licenses/>. |
|---|
| 23 | 8 | * |
|---|
| 24 | 9 | * Please send any bug reports or fixes you make to the |
|---|
| 25 | 10 | * email addresched(es): |
|---|
| .. | .. |
|---|
| 76 | 61 | r->idiag_timer = SCTP_EVENT_TIMEOUT_T3_RTX; |
|---|
| 77 | 62 | r->idiag_retrans = asoc->rtx_data_chunks; |
|---|
| 78 | 63 | r->idiag_expires = jiffies_to_msecs(t3_rtx->expires - jiffies); |
|---|
| 79 | | - } else { |
|---|
| 80 | | - r->idiag_timer = 0; |
|---|
| 81 | | - r->idiag_retrans = 0; |
|---|
| 82 | | - r->idiag_expires = 0; |
|---|
| 83 | 64 | } |
|---|
| 84 | 65 | } |
|---|
| 85 | 66 | |
|---|
| .. | .. |
|---|
| 159 | 140 | r = nlmsg_data(nlh); |
|---|
| 160 | 141 | BUG_ON(!sk_fullsock(sk)); |
|---|
| 161 | 142 | |
|---|
| 143 | + r->idiag_timer = 0; |
|---|
| 144 | + r->idiag_retrans = 0; |
|---|
| 145 | + r->idiag_expires = 0; |
|---|
| 162 | 146 | if (asoc) { |
|---|
| 163 | 147 | inet_diag_msg_sctpasoc_fill(r, sk, asoc); |
|---|
| 164 | 148 | } else { |
|---|
| 165 | 149 | inet_diag_msg_common_fill(r, sk); |
|---|
| 166 | 150 | r->idiag_state = sk->sk_state; |
|---|
| 167 | | - r->idiag_timer = 0; |
|---|
| 168 | | - r->idiag_retrans = 0; |
|---|
| 169 | 151 | } |
|---|
| 170 | 152 | |
|---|
| 171 | 153 | if (inet_diag_msg_attrs_fill(sk, skb, r, ext, user_ns, net_admin)) |
|---|
| .. | .. |
|---|
| 190 | 172 | mem[SK_MEMINFO_FWD_ALLOC] = sk->sk_forward_alloc; |
|---|
| 191 | 173 | mem[SK_MEMINFO_WMEM_QUEUED] = sk->sk_wmem_queued; |
|---|
| 192 | 174 | mem[SK_MEMINFO_OPTMEM] = atomic_read(&sk->sk_omem_alloc); |
|---|
| 193 | | - mem[SK_MEMINFO_BACKLOG] = sk->sk_backlog.len; |
|---|
| 175 | + mem[SK_MEMINFO_BACKLOG] = READ_ONCE(sk->sk_backlog.len); |
|---|
| 194 | 176 | mem[SK_MEMINFO_DROPS] = atomic_read(&sk->sk_drops); |
|---|
| 195 | 177 | |
|---|
| 196 | 178 | if (nla_put(skb, INET_DIAG_SKMEMINFO, sizeof(mem), &mem) < 0) |
|---|
| .. | .. |
|---|
| 367 | 349 | struct sctp_comm_param *commp = p; |
|---|
| 368 | 350 | struct sock *sk = ep->base.sk; |
|---|
| 369 | 351 | const struct inet_diag_req_v2 *r = commp->r; |
|---|
| 370 | | - struct sctp_association *assoc = |
|---|
| 371 | | - list_entry(ep->asocs.next, struct sctp_association, asocs); |
|---|
| 372 | 352 | |
|---|
| 373 | 353 | /* find the ep only once through the transports by this condition */ |
|---|
| 374 | | - if (tsp->asoc != assoc) |
|---|
| 354 | + if (!list_is_first(&tsp->asoc->asocs, &ep->asocs)) |
|---|
| 375 | 355 | return 0; |
|---|
| 376 | 356 | |
|---|
| 377 | 357 | if (r->sdiag_family != AF_UNSPEC && sk->sk_family != r->sdiag_family) |
|---|
| .. | .. |
|---|
| 436 | 416 | r->idiag_rqueue = atomic_read(&infox->asoc->rmem_alloc); |
|---|
| 437 | 417 | r->idiag_wqueue = infox->asoc->sndbuf_used; |
|---|
| 438 | 418 | } else { |
|---|
| 439 | | - r->idiag_rqueue = sk->sk_ack_backlog; |
|---|
| 440 | | - r->idiag_wqueue = sk->sk_max_ack_backlog; |
|---|
| 419 | + r->idiag_rqueue = READ_ONCE(sk->sk_ack_backlog); |
|---|
| 420 | + r->idiag_wqueue = READ_ONCE(sk->sk_max_ack_backlog); |
|---|
| 441 | 421 | } |
|---|
| 442 | 422 | if (infox->sctpinfo) |
|---|
| 443 | 423 | sctp_get_sctp_info(sk, infox->asoc, infox->sctpinfo); |
|---|
| 444 | 424 | } |
|---|
| 445 | 425 | |
|---|
| 446 | | -static int sctp_diag_dump_one(struct sk_buff *in_skb, |
|---|
| 447 | | - const struct nlmsghdr *nlh, |
|---|
| 426 | +static int sctp_diag_dump_one(struct netlink_callback *cb, |
|---|
| 448 | 427 | const struct inet_diag_req_v2 *req) |
|---|
| 449 | 428 | { |
|---|
| 429 | + struct sk_buff *in_skb = cb->skb; |
|---|
| 450 | 430 | struct net *net = sock_net(in_skb->sk); |
|---|
| 431 | + const struct nlmsghdr *nlh = cb->nlh; |
|---|
| 451 | 432 | union sctp_addr laddr, paddr; |
|---|
| 452 | 433 | struct sctp_comm_param commp = { |
|---|
| 453 | 434 | .skb = in_skb, |
|---|
| .. | .. |
|---|
| 481 | 462 | } |
|---|
| 482 | 463 | |
|---|
| 483 | 464 | static void sctp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, |
|---|
| 484 | | - const struct inet_diag_req_v2 *r, struct nlattr *bc) |
|---|
| 465 | + const struct inet_diag_req_v2 *r) |
|---|
| 485 | 466 | { |
|---|
| 486 | 467 | u32 idiag_states = r->idiag_states; |
|---|
| 487 | 468 | struct net *net = sock_net(skb->sk); |
|---|