[PATCH v5 net-next 24/36] net: Add MSG_DDP_CRC flag
From: Boris Pismenny <borisp@nvidia.com>
Date: 2021-07-22 11:40:43
Also in:
linux-nvme
Subsystem:
networking [general], networking [sockets], networking [tcp], the rest · Maintainers:
"David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Kuniyuki Iwashima, Willem de Bruijn, Neal Cardwell, Linus Torvalds
From: Yoray Zack <redacted> if the msg sent with this flag, turn up skb->ddp_crc bit. Signed-off-by: Yoray Zack <redacted> --- include/linux/socket.h | 1 + include/net/sock.h | 6 ++++++ net/core/sock.c | 7 +++++++ net/ipv4/tcp.c | 6 ++++++ 4 files changed, 20 insertions(+)
diff --git a/include/linux/socket.h b/include/linux/socket.h
index 0d8e3dcb7f88..640ec8535f43 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h@@ -310,6 +310,7 @@ struct ucred { * plain text and require encryption */ +#define MSG_DDP_CRC 0x200000 /* Skb pdu need crc offload */ #define MSG_ZEROCOPY 0x4000000 /* Use user data in kernel path */ #define MSG_FASTOPEN 0x20000000 /* Send data in TCP SYN */ #define MSG_CMSG_CLOEXEC 0x40000000 /* Set close_on_exec for file
diff --git a/include/net/sock.h b/include/net/sock.h
index 5fa2fd192d18..84141fdc3b80 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h@@ -2656,6 +2656,12 @@ static inline struct sk_buff *sk_validate_xmit_skb(struct sk_buff *skb, pr_warn_ratelimited("unencrypted skb with no associated socket - dropping\n"); kfree_skb(skb); skb = NULL; +#endif +#ifdef CONFIG_ULP_DDP + } else if (unlikely(skb->ddp_crc)) { + pr_warn_ratelimited("crc-offload skb with no associated socket - dropping\n"); + kfree_skb(skb); + skb = NULL; #endif } #endif
diff --git a/net/core/sock.c b/net/core/sock.c
index ba1c0f75cd45..616ffc523b5d 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c@@ -2160,6 +2160,13 @@ static bool can_skb_orphan_partial(const struct sk_buff *skb) */ if (skb->decrypted) return false; +#endif +#ifdef CONFIG_ULP_DDP + /* Drivers depend on in-order delivery for crc offload, + * partial orphan breaks out-of-order-OK logic. + */ + if (skb->ddp_crc) + return false; #endif return (skb->destructor == sock_wfree || (IS_ENABLED(CONFIG_INET) && skb->destructor == tcp_wfree));
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index d5ab5f243640..36c445ed8a30 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c@@ -984,6 +984,9 @@ struct sk_buff *tcp_build_frag(struct sock *sk, int size_goal, int flags, #ifdef CONFIG_TLS_DEVICE skb->decrypted = !!(flags & MSG_SENDPAGE_DECRYPTED); +#endif +#ifdef CONFIG_ULP_DDP + skb->ddp_crc = !!(flags & MSG_DDP_CRC); #endif skb_entail(sk, skb); copy = size_goal;
@@ -1311,6 +1314,9 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size) if (!skb) goto wait_for_space; +#ifdef CONFIG_ULP_DDP + skb->ddp_crc = !!(flags & MSG_DDP_CRC); +#endif process_backlog++; skb->ip_summed = CHECKSUM_PARTIAL;
--
2.24.1