diff options
-rw-r--r-- | include/uapi/linux/netlink_diag.h | 10 | ||||
-rw-r--r-- | net/netlink/diag.c | 32 |
2 files changed, 42 insertions, 0 deletions
diff --git a/include/uapi/linux/netlink_diag.h b/include/uapi/linux/netlink_diag.h index 88009a31cd06..4e31db4eea41 100644 --- a/include/uapi/linux/netlink_diag.h +++ b/include/uapi/linux/netlink_diag.h | |||
@@ -25,9 +25,18 @@ struct netlink_diag_msg { | |||
25 | __u32 ndiag_cookie[2]; | 25 | __u32 ndiag_cookie[2]; |
26 | }; | 26 | }; |
27 | 27 | ||
28 | struct netlink_diag_ring { | ||
29 | __u32 ndr_block_size; | ||
30 | __u32 ndr_block_nr; | ||
31 | __u32 ndr_frame_size; | ||
32 | __u32 ndr_frame_nr; | ||
33 | }; | ||
34 | |||
28 | enum { | 35 | enum { |
29 | NETLINK_DIAG_MEMINFO, | 36 | NETLINK_DIAG_MEMINFO, |
30 | NETLINK_DIAG_GROUPS, | 37 | NETLINK_DIAG_GROUPS, |
38 | NETLINK_DIAG_RX_RING, | ||
39 | NETLINK_DIAG_TX_RING, | ||
31 | 40 | ||
32 | __NETLINK_DIAG_MAX, | 41 | __NETLINK_DIAG_MAX, |
33 | }; | 42 | }; |
@@ -38,5 +47,6 @@ enum { | |||
38 | 47 | ||
39 | #define NDIAG_SHOW_MEMINFO 0x00000001 /* show memory info of a socket */ | 48 | #define NDIAG_SHOW_MEMINFO 0x00000001 /* show memory info of a socket */ |
40 | #define NDIAG_SHOW_GROUPS 0x00000002 /* show groups of a netlink socket */ | 49 | #define NDIAG_SHOW_GROUPS 0x00000002 /* show groups of a netlink socket */ |
50 | #define NDIAG_SHOW_RING_CFG 0x00000004 /* show ring configuration */ | ||
41 | 51 | ||
42 | #endif | 52 | #endif |
diff --git a/net/netlink/diag.c b/net/netlink/diag.c index 5ffb1d1cf402..4e4aa471cd05 100644 --- a/net/netlink/diag.c +++ b/net/netlink/diag.c | |||
@@ -7,6 +7,34 @@ | |||
7 | 7 | ||
8 | #include "af_netlink.h" | 8 | #include "af_netlink.h" |
9 | 9 | ||
10 | static int sk_diag_put_ring(struct netlink_ring *ring, int nl_type, | ||
11 | struct sk_buff *nlskb) | ||
12 | { | ||
13 | struct netlink_diag_ring ndr; | ||
14 | |||
15 | ndr.ndr_block_size = ring->pg_vec_pages << PAGE_SHIFT; | ||
16 | ndr.ndr_block_nr = ring->pg_vec_len; | ||
17 | ndr.ndr_frame_size = ring->frame_size; | ||
18 | ndr.ndr_frame_nr = ring->frame_max + 1; | ||
19 | |||
20 | return nla_put(nlskb, nl_type, sizeof(ndr), &ndr); | ||
21 | } | ||
22 | |||
23 | static int sk_diag_put_rings_cfg(struct sock *sk, struct sk_buff *nlskb) | ||
24 | { | ||
25 | struct netlink_sock *nlk = nlk_sk(sk); | ||
26 | int ret; | ||
27 | |||
28 | mutex_lock(&nlk->pg_vec_lock); | ||
29 | ret = sk_diag_put_ring(&nlk->rx_ring, NETLINK_DIAG_RX_RING, nlskb); | ||
30 | if (!ret) | ||
31 | ret = sk_diag_put_ring(&nlk->tx_ring, NETLINK_DIAG_TX_RING, | ||
32 | nlskb); | ||
33 | mutex_unlock(&nlk->pg_vec_lock); | ||
34 | |||
35 | return ret; | ||
36 | } | ||
37 | |||
10 | static int sk_diag_dump_groups(struct sock *sk, struct sk_buff *nlskb) | 38 | static int sk_diag_dump_groups(struct sock *sk, struct sk_buff *nlskb) |
11 | { | 39 | { |
12 | struct netlink_sock *nlk = nlk_sk(sk); | 40 | struct netlink_sock *nlk = nlk_sk(sk); |
@@ -51,6 +79,10 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, | |||
51 | sock_diag_put_meminfo(sk, skb, NETLINK_DIAG_MEMINFO)) | 79 | sock_diag_put_meminfo(sk, skb, NETLINK_DIAG_MEMINFO)) |
52 | goto out_nlmsg_trim; | 80 | goto out_nlmsg_trim; |
53 | 81 | ||
82 | if ((req->ndiag_show & NDIAG_SHOW_RING_CFG) && | ||
83 | sk_diag_put_rings_cfg(sk, skb)) | ||
84 | goto out_nlmsg_trim; | ||
85 | |||
54 | return nlmsg_end(skb, nlh); | 86 | return nlmsg_end(skb, nlh); |
55 | 87 | ||
56 | out_nlmsg_trim: | 88 | out_nlmsg_trim: |