@@ -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
@@ -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
@@ -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));
@@ -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;