Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4ae9fbee authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller
Browse files

netlink: add RX/TX-ring support to netlink diag



Based on AF_PACKET.

Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent cd1df525
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -25,9 +25,18 @@ struct netlink_diag_msg {
	__u32	ndiag_cookie[2];
};

struct netlink_diag_ring {
	__u32	ndr_block_size;
	__u32	ndr_block_nr;
	__u32	ndr_frame_size;
	__u32	ndr_frame_nr;
};

enum {
	NETLINK_DIAG_MEMINFO,
	NETLINK_DIAG_GROUPS,
	NETLINK_DIAG_RX_RING,
	NETLINK_DIAG_TX_RING,

	__NETLINK_DIAG_MAX,
};
@@ -38,5 +47,6 @@ enum {

#define NDIAG_SHOW_MEMINFO	0x00000001 /* show memory info of a socket */
#define NDIAG_SHOW_GROUPS	0x00000002 /* show groups of a netlink socket */
#define NDIAG_SHOW_RING_CFG	0x00000004 /* show ring configuration */

#endif
+32 −0
Original line number Diff line number Diff line
@@ -7,6 +7,34 @@

#include "af_netlink.h"

static int sk_diag_put_ring(struct netlink_ring *ring, int nl_type,
			    struct sk_buff *nlskb)
{
	struct netlink_diag_ring ndr;

	ndr.ndr_block_size = ring->pg_vec_pages << PAGE_SHIFT;
	ndr.ndr_block_nr   = ring->pg_vec_len;
	ndr.ndr_frame_size = ring->frame_size;
	ndr.ndr_frame_nr   = ring->frame_max + 1;

	return nla_put(nlskb, nl_type, sizeof(ndr), &ndr);
}

static int sk_diag_put_rings_cfg(struct sock *sk, struct sk_buff *nlskb)
{
	struct netlink_sock *nlk = nlk_sk(sk);
	int ret;

	mutex_lock(&nlk->pg_vec_lock);
	ret = sk_diag_put_ring(&nlk->rx_ring, NETLINK_DIAG_RX_RING, nlskb);
	if (!ret)
		ret = sk_diag_put_ring(&nlk->tx_ring, NETLINK_DIAG_TX_RING,
				       nlskb);
	mutex_unlock(&nlk->pg_vec_lock);

	return ret;
}

static int sk_diag_dump_groups(struct sock *sk, struct sk_buff *nlskb)
{
	struct netlink_sock *nlk = nlk_sk(sk);
@@ -51,6 +79,10 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb,
	    sock_diag_put_meminfo(sk, skb, NETLINK_DIAG_MEMINFO))
		goto out_nlmsg_trim;

	if ((req->ndiag_show & NDIAG_SHOW_RING_CFG) &&
	    sk_diag_put_rings_cfg(sk, skb))
		goto out_nlmsg_trim;

	return nlmsg_end(skb, nlh);

out_nlmsg_trim: