Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Erin MacNeil and committed by
Jakub Kicinski
6fd1d51c 0e55546b

+56 -27
+2
arch/alpha/include/uapi/asm/socket.h
··· 135 135 136 136 #define SO_TXREHASH 74 137 137 138 + #define SO_RCVMARK 75 139 + 138 140 #if !defined(__KERNEL__) 139 141 140 142 #if __BITS_PER_LONG == 64
+2
arch/mips/include/uapi/asm/socket.h
··· 146 146 147 147 #define SO_TXREHASH 74 148 148 149 + #define SO_RCVMARK 75 150 + 149 151 #if !defined(__KERNEL__) 150 152 151 153 #if __BITS_PER_LONG == 64
+2
arch/parisc/include/uapi/asm/socket.h
··· 127 127 128 128 #define SO_TXREHASH 0x4048 129 129 130 + #define SO_RCVMARK 0x4049 131 + 130 132 #if !defined(__KERNEL__) 131 133 132 134 #if __BITS_PER_LONG == 64
+1
arch/sparc/include/uapi/asm/socket.h
··· 128 128 129 129 #define SO_TXREHASH 0x0053 130 130 131 + #define SO_RCVMARK 0x0054 131 132 132 133 #if !defined(__KERNEL__) 133 134
+10 -8
include/net/sock.h
··· 893 893 SOCK_TXTIME, 894 894 SOCK_XDP, /* XDP is attached */ 895 895 SOCK_TSTAMP_NEW, /* Indicates 64 bit timestamps always */ 896 + SOCK_RCVMARK, /* Receive SO_MARK ancillary data with packet */ 896 897 }; 897 898 898 899 #define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE)) ··· 2648 2647 __sock_recv_wifi_status(msg, sk, skb); 2649 2648 } 2650 2649 2651 - void __sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk, 2652 - struct sk_buff *skb); 2650 + void __sock_recv_cmsgs(struct msghdr *msg, struct sock *sk, 2651 + struct sk_buff *skb); 2653 2652 2654 2653 #define SK_DEFAULT_STAMP (-1L * NSEC_PER_SEC) 2655 - static inline void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk, 2656 - struct sk_buff *skb) 2654 + static inline void sock_recv_cmsgs(struct msghdr *msg, struct sock *sk, 2655 + struct sk_buff *skb) 2657 2656 { 2658 - #define FLAGS_TS_OR_DROPS ((1UL << SOCK_RXQ_OVFL) | \ 2659 - (1UL << SOCK_RCVTSTAMP)) 2657 + #define FLAGS_RECV_CMSGS ((1UL << SOCK_RXQ_OVFL) | \ 2658 + (1UL << SOCK_RCVTSTAMP) | \ 2659 + (1UL << SOCK_RCVMARK)) 2660 2660 #define TSFLAGS_ANY (SOF_TIMESTAMPING_SOFTWARE | \ 2661 2661 SOF_TIMESTAMPING_RAW_HARDWARE) 2662 2662 2663 - if (sk->sk_flags & FLAGS_TS_OR_DROPS || sk->sk_tsflags & TSFLAGS_ANY) 2664 - __sock_recv_ts_and_drops(msg, sk, skb); 2663 + if (sk->sk_flags & FLAGS_RECV_CMSGS || sk->sk_tsflags & TSFLAGS_ANY) 2664 + __sock_recv_cmsgs(msg, sk, skb); 2665 2665 else if (unlikely(sock_flag(sk, SOCK_TIMESTAMP))) 2666 2666 sock_write_timestamp(sk, skb->tstamp); 2667 2667 else if (unlikely(sk->sk_stamp == SK_DEFAULT_STAMP))
+2
include/uapi/asm-generic/socket.h
··· 130 130 131 131 #define SO_TXREHASH 74 132 132 133 + #define SO_RCVMARK 75 134 + 133 135 #if !defined(__KERNEL__) 134 136 135 137 #if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__))
+1 -1
net/atm/common.c
··· 553 553 error = skb_copy_datagram_msg(skb, 0, msg, copied); 554 554 if (error) 555 555 return error; 556 - sock_recv_ts_and_drops(msg, sk, skb); 556 + sock_recv_cmsgs(msg, sk, skb); 557 557 558 558 if (!(flags & MSG_PEEK)) { 559 559 pr_debug("%d -= %d\n", atomic_read(&sk->sk_rmem_alloc),
+2 -2
net/bluetooth/af_bluetooth.c
··· 280 280 skb_reset_transport_header(skb); 281 281 err = skb_copy_datagram_msg(skb, 0, msg, copied); 282 282 if (err == 0) { 283 - sock_recv_ts_and_drops(msg, sk, skb); 283 + sock_recv_cmsgs(msg, sk, skb); 284 284 285 285 if (msg->msg_name && bt_sk(sk)->skb_msg_name) 286 286 bt_sk(sk)->skb_msg_name(skb, msg->msg_name, ··· 384 384 copied += chunk; 385 385 size -= chunk; 386 386 387 - sock_recv_ts_and_drops(msg, sk, skb); 387 + sock_recv_cmsgs(msg, sk, skb); 388 388 389 389 if (!(flags & MSG_PEEK)) { 390 390 int skb_len = skb_headlen(skb);
+1 -1
net/can/bcm.c
··· 1647 1647 return err; 1648 1648 } 1649 1649 1650 - sock_recv_ts_and_drops(msg, sk, skb); 1650 + sock_recv_cmsgs(msg, sk, skb); 1651 1651 1652 1652 if (msg->msg_name) { 1653 1653 __sockaddr_check_size(BCM_MIN_NAMELEN);
+1 -1
net/can/j1939/socket.c
··· 841 841 paddr->can_addr.j1939.pgn = skcb->addr.pgn; 842 842 } 843 843 844 - sock_recv_ts_and_drops(msg, sk, skb); 844 + sock_recv_cmsgs(msg, sk, skb); 845 845 msg->msg_flags |= skcb->msg_flags; 846 846 skb_free_datagram(sk, skb); 847 847
+1 -1
net/can/raw.c
··· 866 866 return err; 867 867 } 868 868 869 - sock_recv_ts_and_drops(msg, sk, skb); 869 + sock_recv_cmsgs(msg, sk, skb); 870 870 871 871 if (msg->msg_name) { 872 872 __sockaddr_check_size(RAW_MIN_NAMELEN);
+7
net/core/sock.c
··· 1311 1311 1312 1312 __sock_set_mark(sk, val); 1313 1313 break; 1314 + case SO_RCVMARK: 1315 + sock_valbool_flag(sk, SOCK_RCVMARK, valbool); 1316 + break; 1314 1317 1315 1318 case SO_RXQ_OVFL: 1316 1319 sock_valbool_flag(sk, SOCK_RXQ_OVFL, valbool); ··· 1738 1735 1739 1736 case SO_MARK: 1740 1737 v.val = sk->sk_mark; 1738 + break; 1739 + 1740 + case SO_RCVMARK: 1741 + v.val = sock_flag(sk, SOCK_RCVMARK); 1741 1742 break; 1742 1743 1743 1744 case SO_RXQ_OVFL:
+2 -2
net/ieee802154/socket.c
··· 328 328 if (err) 329 329 goto done; 330 330 331 - sock_recv_ts_and_drops(msg, sk, skb); 331 + sock_recv_cmsgs(msg, sk, skb); 332 332 333 333 if (flags & MSG_TRUNC) 334 334 copied = skb->len; ··· 718 718 if (err) 719 719 goto done; 720 720 721 - sock_recv_ts_and_drops(msg, sk, skb); 721 + sock_recv_cmsgs(msg, sk, skb); 722 722 723 723 if (saddr) { 724 724 /* Clear the implicit padding in struct sockaddr_ieee802154
+1 -1
net/ipv4/raw.c
··· 783 783 if (err) 784 784 goto done; 785 785 786 - sock_recv_ts_and_drops(msg, sk, skb); 786 + sock_recv_cmsgs(msg, sk, skb); 787 787 788 788 /* Copy the address. */ 789 789 if (sin) {
+1 -1
net/ipv4/udp.c
··· 1909 1909 UDP_INC_STATS(sock_net(sk), 1910 1910 UDP_MIB_INDATAGRAMS, is_udplite); 1911 1911 1912 - sock_recv_ts_and_drops(msg, sk, skb); 1912 + sock_recv_cmsgs(msg, sk, skb); 1913 1913 1914 1914 /* Copy the address. */ 1915 1915 if (sin) {
+1 -1
net/ipv6/raw.c
··· 512 512 *addr_len = sizeof(*sin6); 513 513 } 514 514 515 - sock_recv_ts_and_drops(msg, sk, skb); 515 + sock_recv_cmsgs(msg, sk, skb); 516 516 517 517 if (np->rxopt.all) 518 518 ip6_datagram_recv_ctl(sk, msg, skb);
+1 -1
net/ipv6/udp.c
··· 391 391 if (!peeking) 392 392 SNMP_INC_STATS(mib, UDP_MIB_INDATAGRAMS); 393 393 394 - sock_recv_ts_and_drops(msg, sk, skb); 394 + sock_recv_cmsgs(msg, sk, skb); 395 395 396 396 /* Copy the address. */ 397 397 if (msg->msg_name) {
+1 -1
net/key/af_key.c
··· 3711 3711 if (err) 3712 3712 goto out_free; 3713 3713 3714 - sock_recv_ts_and_drops(msg, sk, skb); 3714 + sock_recv_cmsgs(msg, sk, skb); 3715 3715 3716 3716 err = (flags & MSG_TRUNC) ? skb->len : copied; 3717 3717
+1 -1
net/mctp/af_mctp.c
··· 238 238 if (rc < 0) 239 239 goto out_free; 240 240 241 - sock_recv_ts_and_drops(msg, sk, skb); 241 + sock_recv_cmsgs(msg, sk, skb); 242 242 243 243 if (addr) { 244 244 struct mctp_skb_cb *cb = mctp_cb(skb);
+1 -1
net/packet/af_packet.c
··· 3477 3477 sll->sll_protocol = skb->protocol; 3478 3478 } 3479 3479 3480 - sock_recv_ts_and_drops(msg, sk, skb); 3480 + sock_recv_cmsgs(msg, sk, skb); 3481 3481 3482 3482 if (msg->msg_name) { 3483 3483 const size_t max_len = min(sizeof(skb->cb),
+1 -1
net/sctp/socket.c
··· 2128 2128 head_skb = event->chunk->head_skb; 2129 2129 else 2130 2130 head_skb = skb; 2131 - sock_recv_ts_and_drops(msg, sk, head_skb); 2131 + sock_recv_cmsgs(msg, sk, head_skb); 2132 2132 if (sctp_ulpevent_is_notification(event)) { 2133 2133 msg->msg_flags |= MSG_NOTIFICATION; 2134 2134 sp->pf->event_msgname(event, msg->msg_name, addr_len);
+12 -3
net/socket.c
··· 930 930 sizeof(__u32), &SOCK_SKB_CB(skb)->dropcount); 931 931 } 932 932 933 - void __sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk, 934 - struct sk_buff *skb) 933 + static void sock_recv_mark(struct msghdr *msg, struct sock *sk, 934 + struct sk_buff *skb) 935 + { 936 + if (sock_flag(sk, SOCK_RCVMARK) && skb) 937 + put_cmsg(msg, SOL_SOCKET, SO_MARK, sizeof(__u32), 938 + &skb->mark); 939 + } 940 + 941 + void __sock_recv_cmsgs(struct msghdr *msg, struct sock *sk, 942 + struct sk_buff *skb) 935 943 { 936 944 sock_recv_timestamp(msg, sk, skb); 937 945 sock_recv_drops(msg, sk, skb); 946 + sock_recv_mark(msg, sk, skb); 938 947 } 939 - EXPORT_SYMBOL_GPL(__sock_recv_ts_and_drops); 948 + EXPORT_SYMBOL_GPL(__sock_recv_cmsgs); 940 949 941 950 INDIRECT_CALLABLE_DECLARE(int inet_recvmsg(struct socket *, struct msghdr *, 942 951 size_t, int));
+2
tools/include/uapi/asm-generic/socket.h
··· 119 119 120 120 #define SO_DETACH_REUSEPORT_BPF 68 121 121 122 + #define SO_RCVMARK 75 123 + 122 124 #if !defined(__KERNEL__) 123 125 124 126 #if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__))