| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * udp_diag.c Module for monitoring UDP transport protocols sockets. |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Authors: Pavel Emelyanov, <xemul@parallels.com> |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or |
|---|
| 7 | | - * modify it under the terms of the GNU General Public License |
|---|
| 8 | | - * as published by the Free Software Foundation; either version |
|---|
| 9 | | - * 2 of the License, or (at your option) any later version. |
|---|
| 10 | 6 | */ |
|---|
| 11 | 7 | |
|---|
| 12 | 8 | |
|---|
| .. | .. |
|---|
| 25 | 21 | if (!inet_diag_bc_sk(bc, sk)) |
|---|
| 26 | 22 | return 0; |
|---|
| 27 | 23 | |
|---|
| 28 | | - return inet_sk_diag_fill(sk, NULL, skb, req, |
|---|
| 29 | | - sk_user_ns(NETLINK_CB(cb->skb).sk), |
|---|
| 30 | | - NETLINK_CB(cb->skb).portid, |
|---|
| 31 | | - cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh, net_admin); |
|---|
| 24 | + return inet_sk_diag_fill(sk, NULL, skb, cb, req, NLM_F_MULTI, |
|---|
| 25 | + net_admin); |
|---|
| 32 | 26 | } |
|---|
| 33 | 27 | |
|---|
| 34 | | -static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb, |
|---|
| 35 | | - const struct nlmsghdr *nlh, |
|---|
| 28 | +static int udp_dump_one(struct udp_table *tbl, |
|---|
| 29 | + struct netlink_callback *cb, |
|---|
| 36 | 30 | const struct inet_diag_req_v2 *req) |
|---|
| 37 | 31 | { |
|---|
| 32 | + struct sk_buff *in_skb = cb->skb; |
|---|
| 38 | 33 | int err = -EINVAL; |
|---|
| 39 | 34 | struct sock *sk = NULL; |
|---|
| 40 | 35 | struct sk_buff *rep; |
|---|
| .. | .. |
|---|
| 42 | 37 | |
|---|
| 43 | 38 | rcu_read_lock(); |
|---|
| 44 | 39 | if (req->sdiag_family == AF_INET) |
|---|
| 40 | + /* src and dst are swapped for historical reasons */ |
|---|
| 45 | 41 | sk = __udp4_lib_lookup(net, |
|---|
| 46 | 42 | req->id.idiag_src[0], req->id.idiag_sport, |
|---|
| 47 | 43 | req->id.idiag_dst[0], req->id.idiag_dport, |
|---|
| .. | .. |
|---|
| 74 | 70 | if (!rep) |
|---|
| 75 | 71 | goto out; |
|---|
| 76 | 72 | |
|---|
| 77 | | - err = inet_sk_diag_fill(sk, NULL, rep, req, |
|---|
| 78 | | - sk_user_ns(NETLINK_CB(in_skb).sk), |
|---|
| 79 | | - NETLINK_CB(in_skb).portid, |
|---|
| 80 | | - nlh->nlmsg_seq, 0, nlh, |
|---|
| 81 | | - netlink_net_capable(in_skb, CAP_NET_ADMIN)); |
|---|
| 73 | + err = inet_sk_diag_fill(sk, NULL, rep, cb, req, 0, |
|---|
| 74 | + netlink_net_capable(in_skb, CAP_NET_ADMIN)); |
|---|
| 82 | 75 | if (err < 0) { |
|---|
| 83 | 76 | WARN_ON(err == -EMSGSIZE); |
|---|
| 84 | 77 | kfree_skb(rep); |
|---|
| .. | .. |
|---|
| 97 | 90 | |
|---|
| 98 | 91 | static void udp_dump(struct udp_table *table, struct sk_buff *skb, |
|---|
| 99 | 92 | struct netlink_callback *cb, |
|---|
| 100 | | - const struct inet_diag_req_v2 *r, struct nlattr *bc) |
|---|
| 93 | + const struct inet_diag_req_v2 *r) |
|---|
| 101 | 94 | { |
|---|
| 102 | 95 | bool net_admin = netlink_net_capable(cb->skb, CAP_NET_ADMIN); |
|---|
| 103 | 96 | struct net *net = sock_net(skb->sk); |
|---|
| 97 | + struct inet_diag_dump_data *cb_data; |
|---|
| 104 | 98 | int num, s_num, slot, s_slot; |
|---|
| 99 | + struct nlattr *bc; |
|---|
| 105 | 100 | |
|---|
| 101 | + cb_data = cb->data; |
|---|
| 102 | + bc = cb_data->inet_diag_nla_bc; |
|---|
| 106 | 103 | s_slot = cb->args[0]; |
|---|
| 107 | 104 | num = s_num = cb->args[1]; |
|---|
| 108 | 105 | |
|---|
| .. | .. |
|---|
| 150 | 147 | } |
|---|
| 151 | 148 | |
|---|
| 152 | 149 | static void udp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, |
|---|
| 153 | | - const struct inet_diag_req_v2 *r, struct nlattr *bc) |
|---|
| 150 | + const struct inet_diag_req_v2 *r) |
|---|
| 154 | 151 | { |
|---|
| 155 | | - udp_dump(&udp_table, skb, cb, r, bc); |
|---|
| 152 | + udp_dump(&udp_table, skb, cb, r); |
|---|
| 156 | 153 | } |
|---|
| 157 | 154 | |
|---|
| 158 | | -static int udp_diag_dump_one(struct sk_buff *in_skb, const struct nlmsghdr *nlh, |
|---|
| 155 | +static int udp_diag_dump_one(struct netlink_callback *cb, |
|---|
| 159 | 156 | const struct inet_diag_req_v2 *req) |
|---|
| 160 | 157 | { |
|---|
| 161 | | - return udp_dump_one(&udp_table, in_skb, nlh, req); |
|---|
| 158 | + return udp_dump_one(&udp_table, cb, req); |
|---|
| 162 | 159 | } |
|---|
| 163 | 160 | |
|---|
| 164 | 161 | static void udp_diag_get_info(struct sock *sk, struct inet_diag_msg *r, |
|---|
| .. | .. |
|---|
| 253 | 250 | }; |
|---|
| 254 | 251 | |
|---|
| 255 | 252 | static void udplite_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, |
|---|
| 256 | | - const struct inet_diag_req_v2 *r, |
|---|
| 257 | | - struct nlattr *bc) |
|---|
| 253 | + const struct inet_diag_req_v2 *r) |
|---|
| 258 | 254 | { |
|---|
| 259 | | - udp_dump(&udplite_table, skb, cb, r, bc); |
|---|
| 255 | + udp_dump(&udplite_table, skb, cb, r); |
|---|
| 260 | 256 | } |
|---|
| 261 | 257 | |
|---|
| 262 | | -static int udplite_diag_dump_one(struct sk_buff *in_skb, const struct nlmsghdr *nlh, |
|---|
| 258 | +static int udplite_diag_dump_one(struct netlink_callback *cb, |
|---|
| 263 | 259 | const struct inet_diag_req_v2 *req) |
|---|
| 264 | 260 | { |
|---|
| 265 | | - return udp_dump_one(&udplite_table, in_skb, nlh, req); |
|---|
| 261 | + return udp_dump_one(&udplite_table, cb, req); |
|---|
| 266 | 262 | } |
|---|
| 267 | 263 | |
|---|
| 268 | 264 | static const struct inet_diag_handler udplite_diag_handler = { |
|---|