mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	net: SO_RCVMARK socket option for SO_MARK with recvmsg()
Adding a new socket option, SO_RCVMARK, to indicate that SO_MARK should be included in the ancillary data returned by recvmsg(). Renamed the sock_recv_ts_and_drops() function to sock_recv_cmsgs(). Signed-off-by: Erin MacNeil <lnx.erin@gmail.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Reviewed-by: David Ahern <dsahern@kernel.org> Acked-by: Marc Kleine-Budde <mkl@pengutronix.de> Link: https://lore.kernel.org/r/20220427200259.2564-1-lnx.erin@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
		
							parent
							
								
									0e55546b18
								
							
						
					
					
						commit
						6fd1d51cfa
					
				
					 23 changed files with 56 additions and 27 deletions
				
			
		| 
						 | 
					@ -135,6 +135,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SO_TXREHASH		74
 | 
					#define SO_TXREHASH		74
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SO_RCVMARK		75
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if !defined(__KERNEL__)
 | 
					#if !defined(__KERNEL__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if __BITS_PER_LONG == 64
 | 
					#if __BITS_PER_LONG == 64
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -146,6 +146,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SO_TXREHASH		74
 | 
					#define SO_TXREHASH		74
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SO_RCVMARK		75
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if !defined(__KERNEL__)
 | 
					#if !defined(__KERNEL__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if __BITS_PER_LONG == 64
 | 
					#if __BITS_PER_LONG == 64
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -127,6 +127,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SO_TXREHASH		0x4048
 | 
					#define SO_TXREHASH		0x4048
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SO_RCVMARK		0x4049
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if !defined(__KERNEL__)
 | 
					#if !defined(__KERNEL__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if __BITS_PER_LONG == 64
 | 
					#if __BITS_PER_LONG == 64
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -128,6 +128,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SO_TXREHASH              0x0053
 | 
					#define SO_TXREHASH              0x0053
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SO_RCVMARK               0x0054
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if !defined(__KERNEL__)
 | 
					#if !defined(__KERNEL__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -893,6 +893,7 @@ enum sock_flags {
 | 
				
			||||||
	SOCK_TXTIME,
 | 
						SOCK_TXTIME,
 | 
				
			||||||
	SOCK_XDP, /* XDP is attached */
 | 
						SOCK_XDP, /* XDP is attached */
 | 
				
			||||||
	SOCK_TSTAMP_NEW, /* Indicates 64 bit timestamps always */
 | 
						SOCK_TSTAMP_NEW, /* Indicates 64 bit timestamps always */
 | 
				
			||||||
 | 
						SOCK_RCVMARK, /* Receive SO_MARK  ancillary data with packet */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE))
 | 
					#define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE))
 | 
				
			||||||
| 
						 | 
					@ -2647,20 +2648,21 @@ sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
		__sock_recv_wifi_status(msg, sk, skb);
 | 
							__sock_recv_wifi_status(msg, sk, skb);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void __sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,
 | 
					void __sock_recv_cmsgs(struct msghdr *msg, struct sock *sk,
 | 
				
			||||||
		       struct sk_buff *skb);
 | 
							       struct sk_buff *skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SK_DEFAULT_STAMP (-1L * NSEC_PER_SEC)
 | 
					#define SK_DEFAULT_STAMP (-1L * NSEC_PER_SEC)
 | 
				
			||||||
static inline void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,
 | 
					static inline void sock_recv_cmsgs(struct msghdr *msg, struct sock *sk,
 | 
				
			||||||
				   struct sk_buff *skb)
 | 
									   struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#define FLAGS_TS_OR_DROPS ((1UL << SOCK_RXQ_OVFL)			| \
 | 
					#define FLAGS_RECV_CMSGS ((1UL << SOCK_RXQ_OVFL)			| \
 | 
				
			||||||
			   (1UL << SOCK_RCVTSTAMP))
 | 
								   (1UL << SOCK_RCVTSTAMP)			| \
 | 
				
			||||||
 | 
								   (1UL << SOCK_RCVMARK))
 | 
				
			||||||
#define TSFLAGS_ANY	  (SOF_TIMESTAMPING_SOFTWARE			| \
 | 
					#define TSFLAGS_ANY	  (SOF_TIMESTAMPING_SOFTWARE			| \
 | 
				
			||||||
			   SOF_TIMESTAMPING_RAW_HARDWARE)
 | 
								   SOF_TIMESTAMPING_RAW_HARDWARE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (sk->sk_flags & FLAGS_TS_OR_DROPS || sk->sk_tsflags & TSFLAGS_ANY)
 | 
						if (sk->sk_flags & FLAGS_RECV_CMSGS || sk->sk_tsflags & TSFLAGS_ANY)
 | 
				
			||||||
		__sock_recv_ts_and_drops(msg, sk, skb);
 | 
							__sock_recv_cmsgs(msg, sk, skb);
 | 
				
			||||||
	else if (unlikely(sock_flag(sk, SOCK_TIMESTAMP)))
 | 
						else if (unlikely(sock_flag(sk, SOCK_TIMESTAMP)))
 | 
				
			||||||
		sock_write_timestamp(sk, skb->tstamp);
 | 
							sock_write_timestamp(sk, skb->tstamp);
 | 
				
			||||||
	else if (unlikely(sk->sk_stamp == SK_DEFAULT_STAMP))
 | 
						else if (unlikely(sk->sk_stamp == SK_DEFAULT_STAMP))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -130,6 +130,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SO_TXREHASH		74
 | 
					#define SO_TXREHASH		74
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SO_RCVMARK		75
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if !defined(__KERNEL__)
 | 
					#if !defined(__KERNEL__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__))
 | 
					#if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -553,7 +553,7 @@ int vcc_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
 | 
				
			||||||
	error = skb_copy_datagram_msg(skb, 0, msg, copied);
 | 
						error = skb_copy_datagram_msg(skb, 0, msg, copied);
 | 
				
			||||||
	if (error)
 | 
						if (error)
 | 
				
			||||||
		return error;
 | 
							return error;
 | 
				
			||||||
	sock_recv_ts_and_drops(msg, sk, skb);
 | 
						sock_recv_cmsgs(msg, sk, skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!(flags & MSG_PEEK)) {
 | 
						if (!(flags & MSG_PEEK)) {
 | 
				
			||||||
		pr_debug("%d -= %d\n", atomic_read(&sk->sk_rmem_alloc),
 | 
							pr_debug("%d -= %d\n", atomic_read(&sk->sk_rmem_alloc),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -280,7 +280,7 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 | 
				
			||||||
	skb_reset_transport_header(skb);
 | 
						skb_reset_transport_header(skb);
 | 
				
			||||||
	err = skb_copy_datagram_msg(skb, 0, msg, copied);
 | 
						err = skb_copy_datagram_msg(skb, 0, msg, copied);
 | 
				
			||||||
	if (err == 0) {
 | 
						if (err == 0) {
 | 
				
			||||||
		sock_recv_ts_and_drops(msg, sk, skb);
 | 
							sock_recv_cmsgs(msg, sk, skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (msg->msg_name && bt_sk(sk)->skb_msg_name)
 | 
							if (msg->msg_name && bt_sk(sk)->skb_msg_name)
 | 
				
			||||||
			bt_sk(sk)->skb_msg_name(skb, msg->msg_name,
 | 
								bt_sk(sk)->skb_msg_name(skb, msg->msg_name,
 | 
				
			||||||
| 
						 | 
					@ -384,7 +384,7 @@ int bt_sock_stream_recvmsg(struct socket *sock, struct msghdr *msg,
 | 
				
			||||||
		copied += chunk;
 | 
							copied += chunk;
 | 
				
			||||||
		size   -= chunk;
 | 
							size   -= chunk;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		sock_recv_ts_and_drops(msg, sk, skb);
 | 
							sock_recv_cmsgs(msg, sk, skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!(flags & MSG_PEEK)) {
 | 
							if (!(flags & MSG_PEEK)) {
 | 
				
			||||||
			int skb_len = skb_headlen(skb);
 | 
								int skb_len = skb_headlen(skb);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1647,7 +1647,7 @@ static int bcm_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sock_recv_ts_and_drops(msg, sk, skb);
 | 
						sock_recv_cmsgs(msg, sk, skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (msg->msg_name) {
 | 
						if (msg->msg_name) {
 | 
				
			||||||
		__sockaddr_check_size(BCM_MIN_NAMELEN);
 | 
							__sockaddr_check_size(BCM_MIN_NAMELEN);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -841,7 +841,7 @@ static int j1939_sk_recvmsg(struct socket *sock, struct msghdr *msg,
 | 
				
			||||||
		paddr->can_addr.j1939.pgn = skcb->addr.pgn;
 | 
							paddr->can_addr.j1939.pgn = skcb->addr.pgn;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sock_recv_ts_and_drops(msg, sk, skb);
 | 
						sock_recv_cmsgs(msg, sk, skb);
 | 
				
			||||||
	msg->msg_flags |= skcb->msg_flags;
 | 
						msg->msg_flags |= skcb->msg_flags;
 | 
				
			||||||
	skb_free_datagram(sk, skb);
 | 
						skb_free_datagram(sk, skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -866,7 +866,7 @@ static int raw_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sock_recv_ts_and_drops(msg, sk, skb);
 | 
						sock_recv_cmsgs(msg, sk, skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (msg->msg_name) {
 | 
						if (msg->msg_name) {
 | 
				
			||||||
		__sockaddr_check_size(RAW_MIN_NAMELEN);
 | 
							__sockaddr_check_size(RAW_MIN_NAMELEN);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1311,6 +1311,9 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		__sock_set_mark(sk, val);
 | 
							__sock_set_mark(sk, val);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
						case SO_RCVMARK:
 | 
				
			||||||
 | 
							sock_valbool_flag(sk, SOCK_RCVMARK, valbool);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case SO_RXQ_OVFL:
 | 
						case SO_RXQ_OVFL:
 | 
				
			||||||
		sock_valbool_flag(sk, SOCK_RXQ_OVFL, valbool);
 | 
							sock_valbool_flag(sk, SOCK_RXQ_OVFL, valbool);
 | 
				
			||||||
| 
						 | 
					@ -1737,6 +1740,10 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
 | 
				
			||||||
		v.val = sk->sk_mark;
 | 
							v.val = sk->sk_mark;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case SO_RCVMARK:
 | 
				
			||||||
 | 
							v.val = sock_flag(sk, SOCK_RCVMARK);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case SO_RXQ_OVFL:
 | 
						case SO_RXQ_OVFL:
 | 
				
			||||||
		v.val = sock_flag(sk, SOCK_RXQ_OVFL);
 | 
							v.val = sock_flag(sk, SOCK_RXQ_OVFL);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -328,7 +328,7 @@ static int raw_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 | 
				
			||||||
	if (err)
 | 
						if (err)
 | 
				
			||||||
		goto done;
 | 
							goto done;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sock_recv_ts_and_drops(msg, sk, skb);
 | 
						sock_recv_cmsgs(msg, sk, skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (flags & MSG_TRUNC)
 | 
						if (flags & MSG_TRUNC)
 | 
				
			||||||
		copied = skb->len;
 | 
							copied = skb->len;
 | 
				
			||||||
| 
						 | 
					@ -718,7 +718,7 @@ static int dgram_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 | 
				
			||||||
	if (err)
 | 
						if (err)
 | 
				
			||||||
		goto done;
 | 
							goto done;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sock_recv_ts_and_drops(msg, sk, skb);
 | 
						sock_recv_cmsgs(msg, sk, skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (saddr) {
 | 
						if (saddr) {
 | 
				
			||||||
		/* Clear the implicit padding in struct sockaddr_ieee802154
 | 
							/* Clear the implicit padding in struct sockaddr_ieee802154
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -783,7 +783,7 @@ static int raw_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 | 
				
			||||||
	if (err)
 | 
						if (err)
 | 
				
			||||||
		goto done;
 | 
							goto done;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sock_recv_ts_and_drops(msg, sk, skb);
 | 
						sock_recv_cmsgs(msg, sk, skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Copy the address. */
 | 
						/* Copy the address. */
 | 
				
			||||||
	if (sin) {
 | 
						if (sin) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1909,7 +1909,7 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags,
 | 
				
			||||||
		UDP_INC_STATS(sock_net(sk),
 | 
							UDP_INC_STATS(sock_net(sk),
 | 
				
			||||||
			      UDP_MIB_INDATAGRAMS, is_udplite);
 | 
								      UDP_MIB_INDATAGRAMS, is_udplite);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sock_recv_ts_and_drops(msg, sk, skb);
 | 
						sock_recv_cmsgs(msg, sk, skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Copy the address. */
 | 
						/* Copy the address. */
 | 
				
			||||||
	if (sin) {
 | 
						if (sin) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -512,7 +512,7 @@ static int rawv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 | 
				
			||||||
		*addr_len = sizeof(*sin6);
 | 
							*addr_len = sizeof(*sin6);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sock_recv_ts_and_drops(msg, sk, skb);
 | 
						sock_recv_cmsgs(msg, sk, skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (np->rxopt.all)
 | 
						if (np->rxopt.all)
 | 
				
			||||||
		ip6_datagram_recv_ctl(sk, msg, skb);
 | 
							ip6_datagram_recv_ctl(sk, msg, skb);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -391,7 +391,7 @@ int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 | 
				
			||||||
	if (!peeking)
 | 
						if (!peeking)
 | 
				
			||||||
		SNMP_INC_STATS(mib, UDP_MIB_INDATAGRAMS);
 | 
							SNMP_INC_STATS(mib, UDP_MIB_INDATAGRAMS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sock_recv_ts_and_drops(msg, sk, skb);
 | 
						sock_recv_cmsgs(msg, sk, skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Copy the address. */
 | 
						/* Copy the address. */
 | 
				
			||||||
	if (msg->msg_name) {
 | 
						if (msg->msg_name) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3711,7 +3711,7 @@ static int pfkey_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 | 
				
			||||||
	if (err)
 | 
						if (err)
 | 
				
			||||||
		goto out_free;
 | 
							goto out_free;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sock_recv_ts_and_drops(msg, sk, skb);
 | 
						sock_recv_cmsgs(msg, sk, skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = (flags & MSG_TRUNC) ? skb->len : copied;
 | 
						err = (flags & MSG_TRUNC) ? skb->len : copied;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -238,7 +238,7 @@ static int mctp_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 | 
				
			||||||
	if (rc < 0)
 | 
						if (rc < 0)
 | 
				
			||||||
		goto out_free;
 | 
							goto out_free;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sock_recv_ts_and_drops(msg, sk, skb);
 | 
						sock_recv_cmsgs(msg, sk, skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (addr) {
 | 
						if (addr) {
 | 
				
			||||||
		struct mctp_skb_cb *cb = mctp_cb(skb);
 | 
							struct mctp_skb_cb *cb = mctp_cb(skb);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3477,7 +3477,7 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 | 
				
			||||||
		sll->sll_protocol = skb->protocol;
 | 
							sll->sll_protocol = skb->protocol;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sock_recv_ts_and_drops(msg, sk, skb);
 | 
						sock_recv_cmsgs(msg, sk, skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (msg->msg_name) {
 | 
						if (msg->msg_name) {
 | 
				
			||||||
		const size_t max_len = min(sizeof(skb->cb),
 | 
							const size_t max_len = min(sizeof(skb->cb),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2128,7 +2128,7 @@ static int sctp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 | 
				
			||||||
		head_skb = event->chunk->head_skb;
 | 
							head_skb = event->chunk->head_skb;
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		head_skb = skb;
 | 
							head_skb = skb;
 | 
				
			||||||
	sock_recv_ts_and_drops(msg, sk, head_skb);
 | 
						sock_recv_cmsgs(msg, sk, head_skb);
 | 
				
			||||||
	if (sctp_ulpevent_is_notification(event)) {
 | 
						if (sctp_ulpevent_is_notification(event)) {
 | 
				
			||||||
		msg->msg_flags |= MSG_NOTIFICATION;
 | 
							msg->msg_flags |= MSG_NOTIFICATION;
 | 
				
			||||||
		sp->pf->event_msgname(event, msg->msg_name, addr_len);
 | 
							sp->pf->event_msgname(event, msg->msg_name, addr_len);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										13
									
								
								net/socket.c
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								net/socket.c
									
									
									
									
									
								
							| 
						 | 
					@ -930,13 +930,22 @@ static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk,
 | 
				
			||||||
			sizeof(__u32), &SOCK_SKB_CB(skb)->dropcount);
 | 
								sizeof(__u32), &SOCK_SKB_CB(skb)->dropcount);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void __sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,
 | 
					static void sock_recv_mark(struct msghdr *msg, struct sock *sk,
 | 
				
			||||||
 | 
								   struct sk_buff *skb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (sock_flag(sk, SOCK_RCVMARK) && skb)
 | 
				
			||||||
 | 
							put_cmsg(msg, SOL_SOCKET, SO_MARK, sizeof(__u32),
 | 
				
			||||||
 | 
								 &skb->mark);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void __sock_recv_cmsgs(struct msghdr *msg, struct sock *sk,
 | 
				
			||||||
		       struct sk_buff *skb)
 | 
							       struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	sock_recv_timestamp(msg, sk, skb);
 | 
						sock_recv_timestamp(msg, sk, skb);
 | 
				
			||||||
	sock_recv_drops(msg, sk, skb);
 | 
						sock_recv_drops(msg, sk, skb);
 | 
				
			||||||
 | 
						sock_recv_mark(msg, sk, skb);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(__sock_recv_ts_and_drops);
 | 
					EXPORT_SYMBOL_GPL(__sock_recv_cmsgs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
INDIRECT_CALLABLE_DECLARE(int inet_recvmsg(struct socket *, struct msghdr *,
 | 
					INDIRECT_CALLABLE_DECLARE(int inet_recvmsg(struct socket *, struct msghdr *,
 | 
				
			||||||
					   size_t, int));
 | 
										   size_t, int));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -119,6 +119,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SO_DETACH_REUSEPORT_BPF 68
 | 
					#define SO_DETACH_REUSEPORT_BPF 68
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SO_RCVMARK		75
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if !defined(__KERNEL__)
 | 
					#if !defined(__KERNEL__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__))
 | 
					#if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue