@@ -92,4 +92,6 @@
#define SO_ATTACH_BPF 50
#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_RCVMARK 51
+
#endif /* _UAPI_ASM_SOCKET_H */
@@ -85,4 +85,6 @@
#define SO_ATTACH_BPF 50
#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_RCVMARK 51
+
#endif /* _UAPI__ASM_AVR32_SOCKET_H */
@@ -87,6 +87,8 @@
#define SO_ATTACH_BPF 50
#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_RCVMARK 51
+
#endif /* _ASM_SOCKET_H */
@@ -85,5 +85,7 @@
#define SO_ATTACH_BPF 50
#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_RCVMARK 51
+
#endif /* _ASM_SOCKET_H */
@@ -94,4 +94,6 @@
#define SO_ATTACH_BPF 50
#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_RCVMARK 51
+
#endif /* _ASM_IA64_SOCKET_H */
@@ -85,4 +85,6 @@
#define SO_ATTACH_BPF 50
#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_RCVMARK 51
+
#endif /* _ASM_M32R_SOCKET_H */
@@ -103,4 +103,6 @@
#define SO_ATTACH_BPF 50
#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_RCVMARK 51
+
#endif /* _UAPI_ASM_SOCKET_H */
@@ -85,4 +85,6 @@
#define SO_ATTACH_BPF 50
#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_RCVMARK 51
+
#endif /* _ASM_SOCKET_H */
@@ -84,4 +84,6 @@
#define SO_ATTACH_BPF 0x402B
#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_RCVMARK 0x402C
+
#endif /* _UAPI_ASM_SOCKET_H */
@@ -92,4 +92,6 @@
#define SO_ATTACH_BPF 50
#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_RCVMARK 51
+
#endif /* _ASM_POWERPC_SOCKET_H */
@@ -91,4 +91,6 @@
#define SO_ATTACH_BPF 50
#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_RCVMARK 51
+
#endif /* _ASM_SOCKET_H */
@@ -81,6 +81,8 @@
#define SO_ATTACH_BPF 0x0034
#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_RCVMARK 0x0035
+
/* Security levels - as per NRL IPv6 - don't actually do anything */
#define SO_SECURITY_AUTHENTICATION 0x5001
#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002
@@ -96,4 +96,6 @@
#define SO_ATTACH_BPF 50
#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_RCVMARK 51
+
#endif /* _XTENSA_SOCKET_H */
@@ -719,6 +719,7 @@ enum sock_flags {
*/
SOCK_FILTER_LOCKED, /* Filter cannot be changed anymore */
SOCK_SELECT_ERR_QUEUE, /* Wake select on error queue */
+ SOCK_RCVMARK,
};
static inline void sock_copy_flags(struct sock *nsk, struct sock *osk)
@@ -2137,12 +2138,13 @@ void __sock_cmsg_recv(struct msghdr *msg, struct sock *sk,
static inline void sock_cmsg_recv(struct msghdr *msg, struct sock *sk,
struct sk_buff *skb)
{
-#define FLAGS_TS_OR_DROPS ((1UL << SOCK_RXQ_OVFL) | \
- (1UL << SOCK_RCVTSTAMP))
+#define FLAGS_CMSG_ANY ((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)
+ if (sk->sk_flags & FLAGS_CMSG_ANY || sk->sk_tsflags & TSFLAGS_ANY)
__sock_cmsg_recv(msg, sk, skb);
else
sk->sk_stamp = skb->tstamp;
@@ -87,4 +87,6 @@
#define SO_ATTACH_BPF 50
#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_RCVMARK 51
+
#endif /* __ASM_GENERIC_SOCKET_H */
@@ -928,6 +928,10 @@ set_rcvbuf:
sk->sk_mark = val;
break;
+ case SO_RCVMARK:
+ sock_valbool_flag(sk, SOCK_RCVMARK, valbool);
+ break;
+
/* We implement the SO_SNDLOWAT etc to
not be settable (1003.1g 5.3) */
case SO_RXQ_OVFL:
@@ -1179,6 +1183,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;
@@ -736,11 +736,20 @@ static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk,
sizeof(__u32), &SOCK_SKB_CB(skb)->dropcount);
}
+static inline 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_RCVMARK,
+ sizeof(__u32), &skb->mark);
+}
+
void __sock_cmsg_recv(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_cmsg_recv);
A userspace program may wish to receive the mark of packets it receives. Packets may be marked by Netfilter, by other userspace applications using the SO_MARK socket option, or by other kernel means. Receiving the mark in userspace is useful for example for distinguishing between different TPROXY diversion rules to the same userspace proxy socket. Signed-off-by: Eyal Birger <eyal.birger@gmail.com> --- arch/alpha/include/uapi/asm/socket.h | 2 ++ arch/avr32/include/uapi/asm/socket.h | 2 ++ arch/cris/include/uapi/asm/socket.h | 2 ++ arch/frv/include/uapi/asm/socket.h | 2 ++ arch/ia64/include/uapi/asm/socket.h | 2 ++ arch/m32r/include/uapi/asm/socket.h | 2 ++ arch/mips/include/uapi/asm/socket.h | 2 ++ arch/mn10300/include/uapi/asm/socket.h | 2 ++ arch/parisc/include/uapi/asm/socket.h | 2 ++ arch/powerpc/include/uapi/asm/socket.h | 2 ++ arch/s390/include/uapi/asm/socket.h | 2 ++ arch/sparc/include/uapi/asm/socket.h | 2 ++ arch/xtensa/include/uapi/asm/socket.h | 2 ++ include/net/sock.h | 8 +++++--- include/uapi/asm-generic/socket.h | 2 ++ net/core/sock.c | 8 ++++++++ net/socket.c | 9 +++++++++ 17 files changed, 50 insertions(+), 3 deletions(-)