mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2024-12-29 17:22:07 +00: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
@ -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);
|
||||||
|
15
net/socket.c
15
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)
|
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)
|
||||||
{
|
{
|
||||||
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 New Issue
Block a user