Skip to content

Commit 83f73c5

Browse files
zeildavem330
authored andcommitted
inet_diag: return classid for all socket types
In commit 1ec17db ("inet_diag: fix reporting cgroup classid and fallback to priority") croup classid reporting was fixed. But this works only for TCP sockets because for other socket types icsk parameter can be NULL and classid code path is skipped. This change moves classid handling to inet_diag_msg_attrs_fill() function. Also inet_diag_msg_attrs_size() helper was added and addends in nlmsg_new() were reordered to save order from inet_sk_diag_fill(). Fixes: 1ec17db ("inet_diag: fix reporting cgroup classid and fallback to priority") Signed-off-by: Dmitry Yakunin <zeil@yandex-team.ru> Reviewed-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent b723bd9 commit 83f73c5

File tree

5 files changed

+40
-40
lines changed

5 files changed

+40
-40
lines changed

include/linux/inet_diag.h

+12-6
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,10 @@
22
#ifndef _INET_DIAG_H_
33
#define _INET_DIAG_H_ 1
44

5+
#include <net/netlink.h>
56
#include <uapi/linux/inet_diag.h>
67

7-
struct net;
8-
struct sock;
98
struct inet_hashinfo;
10-
struct nlattr;
11-
struct nlmsghdr;
12-
struct sk_buff;
13-
struct netlink_callback;
149

1510
struct inet_diag_handler {
1611
void (*dump)(struct sk_buff *skb,
@@ -62,6 +57,17 @@ int inet_diag_bc_sk(const struct nlattr *_bc, struct sock *sk);
6257

6358
void inet_diag_msg_common_fill(struct inet_diag_msg *r, struct sock *sk);
6459

60+
static inline size_t inet_diag_msg_attrs_size(void)
61+
{
62+
return nla_total_size(1) /* INET_DIAG_SHUTDOWN */
63+
+ nla_total_size(1) /* INET_DIAG_TOS */
64+
#if IS_ENABLED(CONFIG_IPV6)
65+
+ nla_total_size(1) /* INET_DIAG_TCLASS */
66+
+ nla_total_size(1) /* INET_DIAG_SKV6ONLY */
67+
#endif
68+
+ nla_total_size(4) /* INET_DIAG_MARK */
69+
+ nla_total_size(4); /* INET_DIAG_CLASS_ID */
70+
}
6571
int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb,
6672
struct inet_diag_msg *r, int ext,
6773
struct user_namespace *user_ns, bool net_admin);

net/ipv4/inet_diag.c

+20-24
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,9 @@ static size_t inet_sk_attr_size(struct sock *sk,
100100
aux = handler->idiag_get_aux_size(sk, net_admin);
101101

102102
return nla_total_size(sizeof(struct tcp_info))
103-
+ nla_total_size(1) /* INET_DIAG_SHUTDOWN */
104-
+ nla_total_size(1) /* INET_DIAG_TOS */
105-
+ nla_total_size(1) /* INET_DIAG_TCLASS */
106-
+ nla_total_size(4) /* INET_DIAG_MARK */
107-
+ nla_total_size(4) /* INET_DIAG_CLASS_ID */
108-
+ nla_total_size(sizeof(struct inet_diag_meminfo))
109103
+ nla_total_size(sizeof(struct inet_diag_msg))
104+
+ inet_diag_msg_attrs_size()
105+
+ nla_total_size(sizeof(struct inet_diag_meminfo))
110106
+ nla_total_size(SK_MEMINFO_VARS * sizeof(u32))
111107
+ nla_total_size(TCP_CA_NAME_MAX)
112108
+ nla_total_size(sizeof(struct tcpvegas_info))
@@ -147,6 +143,24 @@ int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb,
147143
if (net_admin && nla_put_u32(skb, INET_DIAG_MARK, sk->sk_mark))
148144
goto errout;
149145

146+
if (ext & (1 << (INET_DIAG_CLASS_ID - 1)) ||
147+
ext & (1 << (INET_DIAG_TCLASS - 1))) {
148+
u32 classid = 0;
149+
150+
#ifdef CONFIG_SOCK_CGROUP_DATA
151+
classid = sock_cgroup_classid(&sk->sk_cgrp_data);
152+
#endif
153+
/* Fallback to socket priority if class id isn't set.
154+
* Classful qdiscs use it as direct reference to class.
155+
* For cgroup2 classid is always zero.
156+
*/
157+
if (!classid)
158+
classid = sk->sk_priority;
159+
160+
if (nla_put_u32(skb, INET_DIAG_CLASS_ID, classid))
161+
goto errout;
162+
}
163+
150164
r->idiag_uid = from_kuid_munged(user_ns, sock_i_uid(sk));
151165
r->idiag_inode = sock_i_ino(sk);
152166

@@ -284,24 +298,6 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
284298
goto errout;
285299
}
286300

287-
if (ext & (1 << (INET_DIAG_CLASS_ID - 1)) ||
288-
ext & (1 << (INET_DIAG_TCLASS - 1))) {
289-
u32 classid = 0;
290-
291-
#ifdef CONFIG_SOCK_CGROUP_DATA
292-
classid = sock_cgroup_classid(&sk->sk_cgrp_data);
293-
#endif
294-
/* Fallback to socket priority if class id isn't set.
295-
* Classful qdiscs use it as direct reference to class.
296-
* For cgroup2 classid is always zero.
297-
*/
298-
if (!classid)
299-
classid = sk->sk_priority;
300-
301-
if (nla_put_u32(skb, INET_DIAG_CLASS_ID, classid))
302-
goto errout;
303-
}
304-
305301
out:
306302
nlmsg_end(skb, nlh);
307303
return 0;

net/ipv4/raw_diag.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,9 @@ static int raw_diag_dump_one(struct sk_buff *in_skb,
100100
if (IS_ERR(sk))
101101
return PTR_ERR(sk);
102102

103-
rep = nlmsg_new(sizeof(struct inet_diag_msg) +
104-
sizeof(struct inet_diag_meminfo) + 64,
103+
rep = nlmsg_new(nla_total_size(sizeof(struct inet_diag_msg)) +
104+
inet_diag_msg_attrs_size() +
105+
nla_total_size(sizeof(struct inet_diag_meminfo)) + 64,
105106
GFP_KERNEL);
106107
if (!rep) {
107108
sock_put(sk);

net/ipv4/udp_diag.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,9 @@ static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb,
6464
goto out;
6565

6666
err = -ENOMEM;
67-
rep = nlmsg_new(sizeof(struct inet_diag_msg) +
68-
sizeof(struct inet_diag_meminfo) + 64,
67+
rep = nlmsg_new(nla_total_size(sizeof(struct inet_diag_msg)) +
68+
inet_diag_msg_attrs_size() +
69+
nla_total_size(sizeof(struct inet_diag_meminfo)) + 64,
6970
GFP_KERNEL);
7071
if (!rep)
7172
goto out;

net/sctp/diag.c

+2-6
Original file line numberDiff line numberDiff line change
@@ -237,15 +237,11 @@ static size_t inet_assoc_attr_size(struct sctp_association *asoc)
237237
addrcnt++;
238238

239239
return nla_total_size(sizeof(struct sctp_info))
240-
+ nla_total_size(1) /* INET_DIAG_SHUTDOWN */
241-
+ nla_total_size(1) /* INET_DIAG_TOS */
242-
+ nla_total_size(1) /* INET_DIAG_TCLASS */
243-
+ nla_total_size(4) /* INET_DIAG_MARK */
244-
+ nla_total_size(4) /* INET_DIAG_CLASS_ID */
245240
+ nla_total_size(addrlen * asoc->peer.transport_count)
246241
+ nla_total_size(addrlen * addrcnt)
247-
+ nla_total_size(sizeof(struct inet_diag_meminfo))
248242
+ nla_total_size(sizeof(struct inet_diag_msg))
243+
+ inet_diag_msg_attrs_size()
244+
+ nla_total_size(sizeof(struct inet_diag_meminfo))
249245
+ 64;
250246
}
251247

0 commit comments

Comments
 (0)