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

Commit b73c8bfd authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'skb_to_full_sk'



Eric Dumazet says:

====================
net: add skb_to_full_sk() helper

Many contexts need to reach listener socket from skb attached
to a request socket. This patch series add skb_to_full_sk() to
clearly express this need and use it where appropriate.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents fb9a10d9 3aed8225
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -210,6 +210,18 @@ struct inet_sock {
#define IP_CMSG_ORIGDSTADDR	BIT(6)
#define IP_CMSG_CHECKSUM	BIT(7)

/* SYNACK messages might be attached to request sockets.
 * Some places want to reach the listener in this case.
 */
static inline struct sock *skb_to_full_sk(const struct sk_buff *skb)
{
	struct sock *sk = skb->sk;

	if (sk && sk->sk_state == TCP_NEW_SYN_RECV)
		sk = inet_reqsk(sk)->rsk_listener;
	return sk;
}

static inline struct inet_sock *inet_sk(const struct sock *sk)
{
	return (struct inet_sock *)sk;
+20 −16
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ void nft_meta_get_eval(const struct nft_expr *expr,
	const struct nft_meta *priv = nft_expr_priv(expr);
	const struct sk_buff *skb = pkt->skb;
	const struct net_device *in = pkt->in, *out = pkt->out;
	struct sock *sk;
	u32 *dest = &regs->data[priv->dreg];

	switch (priv->key) {
@@ -86,33 +87,35 @@ void nft_meta_get_eval(const struct nft_expr *expr,
		*(u16 *)dest = out->type;
		break;
	case NFT_META_SKUID:
		if (skb->sk == NULL || !sk_fullsock(skb->sk))
		sk = skb_to_full_sk(skb);
		if (!sk || !sk_fullsock(sk))
			goto err;

		read_lock_bh(&skb->sk->sk_callback_lock);
		if (skb->sk->sk_socket == NULL ||
		    skb->sk->sk_socket->file == NULL) {
			read_unlock_bh(&skb->sk->sk_callback_lock);
		read_lock_bh(&sk->sk_callback_lock);
		if (sk->sk_socket == NULL ||
		    sk->sk_socket->file == NULL) {
			read_unlock_bh(&sk->sk_callback_lock);
			goto err;
		}

		*dest =	from_kuid_munged(&init_user_ns,
				skb->sk->sk_socket->file->f_cred->fsuid);
		read_unlock_bh(&skb->sk->sk_callback_lock);
				sk->sk_socket->file->f_cred->fsuid);
		read_unlock_bh(&sk->sk_callback_lock);
		break;
	case NFT_META_SKGID:
		if (skb->sk == NULL || !sk_fullsock(skb->sk))
		sk = skb_to_full_sk(skb);
		if (!sk || !sk_fullsock(sk))
			goto err;

		read_lock_bh(&skb->sk->sk_callback_lock);
		if (skb->sk->sk_socket == NULL ||
		    skb->sk->sk_socket->file == NULL) {
			read_unlock_bh(&skb->sk->sk_callback_lock);
		read_lock_bh(&sk->sk_callback_lock);
		if (sk->sk_socket == NULL ||
		    sk->sk_socket->file == NULL) {
			read_unlock_bh(&sk->sk_callback_lock);
			goto err;
		}
		*dest =	from_kgid_munged(&init_user_ns,
				 skb->sk->sk_socket->file->f_cred->fsgid);
		read_unlock_bh(&skb->sk->sk_callback_lock);
				 sk->sk_socket->file->f_cred->fsgid);
		read_unlock_bh(&sk->sk_callback_lock);
		break;
#ifdef CONFIG_IP_ROUTE_CLASSID
	case NFT_META_RTCLASSID: {
@@ -168,9 +171,10 @@ void nft_meta_get_eval(const struct nft_expr *expr,
		break;
#ifdef CONFIG_CGROUP_NET_CLASSID
	case NFT_META_CGROUP:
		if (skb->sk == NULL || !sk_fullsock(skb->sk))
		sk = skb_to_full_sk(skb);
		if (!sk || !sk_fullsock(sk))
			goto err;
		*dest = skb->sk->sk_classid;
		*dest = sk->sk_classid;
		break;
#endif
	default:
+4 −2
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <linux/skbuff.h>
#include <linux/file.h>
#include <net/sock.h>
#include <net/inet_sock.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_owner.h>

@@ -33,8 +34,9 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
{
	const struct xt_owner_match_info *info = par->matchinfo;
	const struct file *filp;
	struct sock *sk = skb_to_full_sk(skb);

	if (skb->sk == NULL || skb->sk->sk_socket == NULL)
	if (sk == NULL || sk->sk_socket == NULL)
		return (info->match ^ info->invert) == 0;
	else if (info->match & info->invert & XT_OWNER_SOCKET)
		/*
@@ -43,7 +45,7 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
		 */
		return false;

	filp = skb->sk->sk_socket->file;
	filp = sk->sk_socket->file;
	if (filp == NULL)
		return ((info->match ^ info->invert) &
		       (XT_OWNER_UID | XT_OWNER_GID)) == 0;
+11 −4
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <linux/if_vlan.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <net/inet_sock.h>

#include <net/pkt_cls.h>
#include <net/ip.h>
@@ -197,8 +198,11 @@ static u32 flow_get_rtclassid(const struct sk_buff *skb)

static u32 flow_get_skuid(const struct sk_buff *skb)
{
	if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) {
		kuid_t skuid = skb->sk->sk_socket->file->f_cred->fsuid;
	struct sock *sk = skb_to_full_sk(skb);

	if (sk && sk->sk_socket && sk->sk_socket->file) {
		kuid_t skuid = sk->sk_socket->file->f_cred->fsuid;

		return from_kuid(&init_user_ns, skuid);
	}
	return 0;
@@ -206,8 +210,11 @@ static u32 flow_get_skuid(const struct sk_buff *skb)

static u32 flow_get_skgid(const struct sk_buff *skb)
{
	if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) {
		kgid_t skgid = skb->sk->sk_socket->file->f_cred->fsgid;
	struct sock *sk = skb_to_full_sk(skb);

	if (sk && sk->sk_socket && sk->sk_socket->file) {
		kgid_t skgid = sk->sk_socket->file->f_cred->fsgid;

		return from_kgid(&init_user_ns, skgid);
	}
	return 0;
+92 −46
Original line number Diff line number Diff line
@@ -343,119 +343,145 @@ META_COLLECTOR(int_sk_refcnt)

META_COLLECTOR(int_sk_rcvbuf)
{
	if (skip_nonlocal(skb)) {
	const struct sock *sk = skb_to_full_sk(skb);

	if (!sk) {
		*err = -1;
		return;
	}
	dst->value = skb->sk->sk_rcvbuf;
	dst->value = sk->sk_rcvbuf;
}

META_COLLECTOR(int_sk_shutdown)
{
	if (skip_nonlocal(skb)) {
	const struct sock *sk = skb_to_full_sk(skb);

	if (!sk) {
		*err = -1;
		return;
	}
	dst->value = skb->sk->sk_shutdown;
	dst->value = sk->sk_shutdown;
}

META_COLLECTOR(int_sk_proto)
{
	if (skip_nonlocal(skb)) {
	const struct sock *sk = skb_to_full_sk(skb);

	if (!sk) {
		*err = -1;
		return;
	}
	dst->value = skb->sk->sk_protocol;
	dst->value = sk->sk_protocol;
}

META_COLLECTOR(int_sk_type)
{
	if (skip_nonlocal(skb)) {
	const struct sock *sk = skb_to_full_sk(skb);

	if (!sk) {
		*err = -1;
		return;
	}
	dst->value = skb->sk->sk_type;
	dst->value = sk->sk_type;
}

META_COLLECTOR(int_sk_rmem_alloc)
{
	if (skip_nonlocal(skb)) {
	const struct sock *sk = skb_to_full_sk(skb);

	if (!sk) {
		*err = -1;
		return;
	}
	dst->value = sk_rmem_alloc_get(skb->sk);
	dst->value = sk_rmem_alloc_get(sk);
}

META_COLLECTOR(int_sk_wmem_alloc)
{
	if (skip_nonlocal(skb)) {
	const struct sock *sk = skb_to_full_sk(skb);

	if (!sk) {
		*err = -1;
		return;
	}
	dst->value = sk_wmem_alloc_get(skb->sk);
	dst->value = sk_wmem_alloc_get(sk);
}

META_COLLECTOR(int_sk_omem_alloc)
{
	if (skip_nonlocal(skb)) {
	const struct sock *sk = skb_to_full_sk(skb);

	if (!sk) {
		*err = -1;
		return;
	}
	dst->value = atomic_read(&skb->sk->sk_omem_alloc);
	dst->value = atomic_read(&sk->sk_omem_alloc);
}

META_COLLECTOR(int_sk_rcv_qlen)
{
	if (skip_nonlocal(skb)) {
	const struct sock *sk = skb_to_full_sk(skb);

	if (!sk) {
		*err = -1;
		return;
	}
	dst->value = skb->sk->sk_receive_queue.qlen;
	dst->value = sk->sk_receive_queue.qlen;
}

META_COLLECTOR(int_sk_snd_qlen)
{
	if (skip_nonlocal(skb)) {
	const struct sock *sk = skb_to_full_sk(skb);

	if (!sk) {
		*err = -1;
		return;
	}
	dst->value = skb->sk->sk_write_queue.qlen;
	dst->value = sk->sk_write_queue.qlen;
}

META_COLLECTOR(int_sk_wmem_queued)
{
	if (skip_nonlocal(skb)) {
	const struct sock *sk = skb_to_full_sk(skb);

	if (!sk) {
		*err = -1;
		return;
	}
	dst->value = skb->sk->sk_wmem_queued;
	dst->value = sk->sk_wmem_queued;
}

META_COLLECTOR(int_sk_fwd_alloc)
{
	if (skip_nonlocal(skb)) {
	const struct sock *sk = skb_to_full_sk(skb);

	if (!sk) {
		*err = -1;
		return;
	}
	dst->value = skb->sk->sk_forward_alloc;
	dst->value = sk->sk_forward_alloc;
}

META_COLLECTOR(int_sk_sndbuf)
{
	if (skip_nonlocal(skb)) {
	const struct sock *sk = skb_to_full_sk(skb);

	if (!sk) {
		*err = -1;
		return;
	}
	dst->value = skb->sk->sk_sndbuf;
	dst->value = sk->sk_sndbuf;
}

META_COLLECTOR(int_sk_alloc)
{
	if (skip_nonlocal(skb)) {
	const struct sock *sk = skb_to_full_sk(skb);

	if (!sk) {
		*err = -1;
		return;
	}
	dst->value = (__force int) skb->sk->sk_allocation;
	dst->value = (__force int) sk->sk_allocation;
}

META_COLLECTOR(int_sk_hash)
@@ -469,92 +495,112 @@ META_COLLECTOR(int_sk_hash)

META_COLLECTOR(int_sk_lingertime)
{
	if (skip_nonlocal(skb)) {
	const struct sock *sk = skb_to_full_sk(skb);

	if (!sk) {
		*err = -1;
		return;
	}
	dst->value = skb->sk->sk_lingertime / HZ;
	dst->value = sk->sk_lingertime / HZ;
}

META_COLLECTOR(int_sk_err_qlen)
{
	if (skip_nonlocal(skb)) {
	const struct sock *sk = skb_to_full_sk(skb);

	if (!sk) {
		*err = -1;
		return;
	}
	dst->value = skb->sk->sk_error_queue.qlen;
	dst->value = sk->sk_error_queue.qlen;
}

META_COLLECTOR(int_sk_ack_bl)
{
	if (skip_nonlocal(skb)) {
	const struct sock *sk = skb_to_full_sk(skb);

	if (!sk) {
		*err = -1;
		return;
	}
	dst->value = skb->sk->sk_ack_backlog;
	dst->value = sk->sk_ack_backlog;
}

META_COLLECTOR(int_sk_max_ack_bl)
{
	if (skip_nonlocal(skb)) {
	const struct sock *sk = skb_to_full_sk(skb);

	if (!sk) {
		*err = -1;
		return;
	}
	dst->value = skb->sk->sk_max_ack_backlog;
	dst->value = sk->sk_max_ack_backlog;
}

META_COLLECTOR(int_sk_prio)
{
	if (skip_nonlocal(skb)) {
	const struct sock *sk = skb_to_full_sk(skb);

	if (!sk) {
		*err = -1;
		return;
	}
	dst->value = skb->sk->sk_priority;
	dst->value = sk->sk_priority;
}

META_COLLECTOR(int_sk_rcvlowat)
{
	if (skip_nonlocal(skb)) {
	const struct sock *sk = skb_to_full_sk(skb);

	if (!sk) {
		*err = -1;
		return;
	}
	dst->value = skb->sk->sk_rcvlowat;
	dst->value = sk->sk_rcvlowat;
}

META_COLLECTOR(int_sk_rcvtimeo)
{
	if (skip_nonlocal(skb)) {
	const struct sock *sk = skb_to_full_sk(skb);

	if (!sk) {
		*err = -1;
		return;
	}
	dst->value = skb->sk->sk_rcvtimeo / HZ;
	dst->value = sk->sk_rcvtimeo / HZ;
}

META_COLLECTOR(int_sk_sndtimeo)
{
	if (skip_nonlocal(skb)) {
	const struct sock *sk = skb_to_full_sk(skb);

	if (!sk) {
		*err = -1;
		return;
	}
	dst->value = skb->sk->sk_sndtimeo / HZ;
	dst->value = sk->sk_sndtimeo / HZ;
}

META_COLLECTOR(int_sk_sendmsg_off)
{
	if (skip_nonlocal(skb)) {
	const struct sock *sk = skb_to_full_sk(skb);

	if (!sk) {
		*err = -1;
		return;
	}
	dst->value = skb->sk->sk_frag.offset;
	dst->value = sk->sk_frag.offset;
}

META_COLLECTOR(int_sk_write_pend)
{
	if (skip_nonlocal(skb)) {
	const struct sock *sk = skb_to_full_sk(skb);

	if (!sk) {
		*err = -1;
		return;
	}
	dst->value = skb->sk->sk_write_pending;
	dst->value = sk->sk_write_pending;
}

/**************************************************************************
Loading