net: SO_RCVMARK socket option for SO_MARK with recvmsg()
authorErin MacNeil <lnx.erin@gmail.com>
Wed, 27 Apr 2022 20:02:37 +0000 (16:02 -0400)
committerJakub Kicinski <kuba@kernel.org>
Thu, 28 Apr 2022 20:08:15 +0000 (13:08 -0700)
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>
23 files changed:
arch/alpha/include/uapi/asm/socket.h
arch/mips/include/uapi/asm/socket.h
arch/parisc/include/uapi/asm/socket.h
arch/sparc/include/uapi/asm/socket.h
include/net/sock.h
include/uapi/asm-generic/socket.h
net/atm/common.c
net/bluetooth/af_bluetooth.c
net/can/bcm.c
net/can/j1939/socket.c
net/can/raw.c
net/core/sock.c
net/ieee802154/socket.c
net/ipv4/raw.c
net/ipv4/udp.c
net/ipv6/raw.c
net/ipv6/udp.c
net/key/af_key.c
net/mctp/af_mctp.c
net/packet/af_packet.c
net/sctp/socket.c
net/socket.c
tools/include/uapi/asm-generic/socket.h

index 7d81535..739891b 100644 (file)
 
 #define SO_TXREHASH            74
 
+#define SO_RCVMARK             75
+
 #if !defined(__KERNEL__)
 
 #if __BITS_PER_LONG == 64
index 1d55e57..18f3d95 100644 (file)
 
 #define SO_TXREHASH            74
 
+#define SO_RCVMARK             75
+
 #if !defined(__KERNEL__)
 
 #if __BITS_PER_LONG == 64
index 654061e..f486d3d 100644 (file)
 
 #define SO_TXREHASH            0x4048
 
+#define SO_RCVMARK             0x4049
+
 #if !defined(__KERNEL__)
 
 #if __BITS_PER_LONG == 64
index 666f81e..2fda57a 100644 (file)
 
 #define SO_TXREHASH              0x0053
 
+#define SO_RCVMARK               0x0054
 
 #if !defined(__KERNEL__)
 
index f9f8eca..663041b 100644 (file)
@@ -893,6 +893,7 @@ enum sock_flags {
        SOCK_TXTIME,
        SOCK_XDP, /* XDP is attached */
        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))
@@ -2647,20 +2648,21 @@ sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
                __sock_recv_wifi_status(msg, sk, skb);
 }
 
-void __sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,
-                             struct sk_buff *skb);
+void __sock_recv_cmsgs(struct msghdr *msg, struct sock *sk,
+                      struct sk_buff *skb);
 
 #define SK_DEFAULT_STAMP (-1L * NSEC_PER_SEC)
-static inline void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,
-                                         struct sk_buff *skb)
+static inline void sock_recv_cmsgs(struct msghdr *msg, struct sock *sk,
+                                  struct sk_buff *skb)
 {
-#define FLAGS_TS_OR_DROPS ((1UL << SOCK_RXQ_OVFL)                      | \
-                          (1UL << SOCK_RCVTSTAMP))
+#define FLAGS_RECV_CMSGS ((1UL << SOCK_RXQ_OVFL)                       | \
+                          (1UL << SOCK_RCVTSTAMP)                      | \
+                          (1UL << SOCK_RCVMARK))
 #define TSFLAGS_ANY      (SOF_TIMESTAMPING_SOFTWARE                    | \
                           SOF_TIMESTAMPING_RAW_HARDWARE)
 
-       if (sk->sk_flags & FLAGS_TS_OR_DROPS || sk->sk_tsflags & TSFLAGS_ANY)
-               __sock_recv_ts_and_drops(msg, sk, skb);
+       if (sk->sk_flags & FLAGS_RECV_CMSGS || sk->sk_tsflags & TSFLAGS_ANY)
+               __sock_recv_cmsgs(msg, sk, skb);
        else if (unlikely(sock_flag(sk, SOCK_TIMESTAMP)))
                sock_write_timestamp(sk, skb->tstamp);
        else if (unlikely(sk->sk_stamp == SK_DEFAULT_STAMP))
index 467ca2f..6382308 100644 (file)
 
 #define SO_TXREHASH            74
 
+#define SO_RCVMARK             75
+
 #if !defined(__KERNEL__)
 
 #if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__))
index d0c8ab7..f7019df 100644 (file)
@@ -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);
        if (error)
                return error;
-       sock_recv_ts_and_drops(msg, sk, skb);
+       sock_recv_cmsgs(msg, sk, skb);
 
        if (!(flags & MSG_PEEK)) {
                pr_debug("%d -= %d\n", atomic_read(&sk->sk_rmem_alloc),
index 6270573..b506409 100644 (file)
@@ -280,7 +280,7 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
        skb_reset_transport_header(skb);
        err = skb_copy_datagram_msg(skb, 0, msg, copied);
        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)
                        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;
                size   -= chunk;
 
-               sock_recv_ts_and_drops(msg, sk, skb);
+               sock_recv_cmsgs(msg, sk, skb);
 
                if (!(flags & MSG_PEEK)) {
                        int skb_len = skb_headlen(skb);
index 64c07e6..65ee1b7 100644 (file)
@@ -1647,7 +1647,7 @@ static int bcm_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
                return err;
        }
 
-       sock_recv_ts_and_drops(msg, sk, skb);
+       sock_recv_cmsgs(msg, sk, skb);
 
        if (msg->msg_name) {
                __sockaddr_check_size(BCM_MIN_NAMELEN);
index 0bb4fd3..f5ecfdc 100644 (file)
@@ -841,7 +841,7 @@ static int j1939_sk_recvmsg(struct socket *sock, struct msghdr *msg,
                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;
        skb_free_datagram(sk, skb);
 
index 0cf728d..b7dbb57 100644 (file)
@@ -866,7 +866,7 @@ static int raw_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
                return err;
        }
 
-       sock_recv_ts_and_drops(msg, sk, skb);
+       sock_recv_cmsgs(msg, sk, skb);
 
        if (msg->msg_name) {
                __sockaddr_check_size(RAW_MIN_NAMELEN);
index a0f3989..770408f 100644 (file)
@@ -1311,6 +1311,9 @@ set_sndbuf:
 
                __sock_set_mark(sk, val);
                break;
+       case SO_RCVMARK:
+               sock_valbool_flag(sk, SOCK_RCVMARK, valbool);
+               break;
 
        case SO_RXQ_OVFL:
                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;
                break;
 
+       case SO_RCVMARK:
+               v.val = sock_flag(sk, SOCK_RCVMARK);
+               break;
+
        case SO_RXQ_OVFL:
                v.val = sock_flag(sk, SOCK_RXQ_OVFL);
                break;
index f248528..718fb77 100644 (file)
@@ -328,7 +328,7 @@ static int raw_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
        if (err)
                goto done;
 
-       sock_recv_ts_and_drops(msg, sk, skb);
+       sock_recv_cmsgs(msg, sk, skb);
 
        if (flags & MSG_TRUNC)
                copied = skb->len;
@@ -718,7 +718,7 @@ static int dgram_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
        if (err)
                goto done;
 
-       sock_recv_ts_and_drops(msg, sk, skb);
+       sock_recv_cmsgs(msg, sk, skb);
 
        if (saddr) {
                /* Clear the implicit padding in struct sockaddr_ieee802154
index 4056b0d..bbd7178 100644 (file)
@@ -783,7 +783,7 @@ static int raw_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
        if (err)
                goto done;
 
-       sock_recv_ts_and_drops(msg, sk, skb);
+       sock_recv_cmsgs(msg, sk, skb);
 
        /* Copy the address. */
        if (sin) {
index aa8545c..9d5071c 100644 (file)
@@ -1909,7 +1909,7 @@ try_again:
                UDP_INC_STATS(sock_net(sk),
                              UDP_MIB_INDATAGRAMS, is_udplite);
 
-       sock_recv_ts_and_drops(msg, sk, skb);
+       sock_recv_cmsgs(msg, sk, skb);
 
        /* Copy the address. */
        if (sin) {
index 0d7c13d..3b7cbd5 100644 (file)
@@ -512,7 +512,7 @@ static int rawv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
                *addr_len = sizeof(*sin6);
        }
 
-       sock_recv_ts_and_drops(msg, sk, skb);
+       sock_recv_cmsgs(msg, sk, skb);
 
        if (np->rxopt.all)
                ip6_datagram_recv_ctl(sk, msg, skb);
index 688af6f..3fc97d4 100644 (file)
@@ -391,7 +391,7 @@ try_again:
        if (!peeking)
                SNMP_INC_STATS(mib, UDP_MIB_INDATAGRAMS);
 
-       sock_recv_ts_and_drops(msg, sk, skb);
+       sock_recv_cmsgs(msg, sk, skb);
 
        /* Copy the address. */
        if (msg->msg_name) {
index d09ec26..175a162 100644 (file)
@@ -3711,7 +3711,7 @@ static int pfkey_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
        if (err)
                goto out_free;
 
-       sock_recv_ts_and_drops(msg, sk, skb);
+       sock_recv_cmsgs(msg, sk, skb);
 
        err = (flags & MSG_TRUNC) ? skb->len : copied;
 
index 221863a..c2fc2a7 100644 (file)
@@ -238,7 +238,7 @@ static int mctp_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
        if (rc < 0)
                goto out_free;
 
-       sock_recv_ts_and_drops(msg, sk, skb);
+       sock_recv_cmsgs(msg, sk, skb);
 
        if (addr) {
                struct mctp_skb_cb *cb = mctp_cb(skb);
index fd31334..677f9cf 100644 (file)
@@ -3477,7 +3477,7 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
                sll->sll_protocol = skb->protocol;
        }
 
-       sock_recv_ts_and_drops(msg, sk, skb);
+       sock_recv_cmsgs(msg, sk, skb);
 
        if (msg->msg_name) {
                const size_t max_len = min(sizeof(skb->cb),
index 3e3fe92..6d37d2d 100644 (file)
@@ -2128,7 +2128,7 @@ static int sctp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
                head_skb = event->chunk->head_skb;
        else
                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)) {
                msg->msg_flags |= MSG_NOTIFICATION;
                sp->pf->event_msgname(event, msg->msg_name, addr_len);
index 6887840..f0c39c8 100644 (file)
@@ -930,13 +930,22 @@ static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk,
                        sizeof(__u32), &SOCK_SKB_CB(skb)->dropcount);
 }
 
-void __sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,
-       struct sk_buff *skb)
+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)
 {
        sock_recv_timestamp(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 *,
                                           size_t, int));
index 77f7c16..8756df1 100644 (file)
 
 #define SO_DETACH_REUSEPORT_BPF 68
 
+#define SO_RCVMARK             75
+
 #if !defined(__KERNEL__)
 
 #if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__))