Michal Kubecek 35166d
From: "David S. Miller" <davem@davemloft.net>
Michal Kubecek 35166d
Date: Mon, 3 Jul 2017 07:07:18 -0700
Michal Kubecek 35166d
Subject: inet: Stop generating UFO packets.
Michal Kubecek 35166d
Patch-mainline: v4.14-rc1
Michal Kubecek 35166d
Git-commit: 988cf74deb45bd6ee27433b7b5d1be6004d842b8
Michal Kubecek 35166d
References: bsc#1061739
Michal Kubecek 35166d
Michal Kubecek 35166d
Signed-off-by: David S. Miller <davem@davemloft.net>
Michal Kubecek 35166d
Acked-by: Michal Kubecek <mkubecek@suse.cz>
Michal Kubecek 35166d
Michal Kubecek 35166d
---
Michal Kubecek 35166d
 net/ipv4/ip_output.c  | 78 ---------------------------------------------------
Michal Kubecek 35166d
 net/ipv6/ip6_output.c | 77 --------------------------------------------------
Michal Kubecek 35166d
 2 files changed, 155 deletions(-)
Michal Kubecek 35166d
Michal Kubecek 35166d
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
Michal Kubecek 35166d
index e5948c0c9759..2d2fffc03b23 100644
Michal Kubecek 35166d
--- a/net/ipv4/ip_output.c
Michal Kubecek 35166d
+++ b/net/ipv4/ip_output.c
Michal Kubecek 35166d
@@ -852,61 +852,6 @@ csum_page(struct page *page, int offset, int copy)
Michal Kubecek 35166d
 	return csum;
Michal Kubecek 35166d
 }
Michal Kubecek 35166d
 
Michal Kubecek 35166d
-static inline int ip_ufo_append_data(struct sock *sk,
Michal Kubecek 35166d
-			struct sk_buff_head *queue,
Michal Kubecek 35166d
-			int getfrag(void *from, char *to, int offset, int len,
Michal Kubecek 35166d
-			       int odd, struct sk_buff *skb),
Michal Kubecek 35166d
-			void *from, int length, int hh_len, int fragheaderlen,
Michal Kubecek 35166d
-			int transhdrlen, int maxfraglen, unsigned int flags)
Michal Kubecek 35166d
-{
Michal Kubecek 35166d
-	struct sk_buff *skb;
Michal Kubecek 35166d
-	int err;
Michal Kubecek 35166d
-
Michal Kubecek 35166d
-	/* There is support for UDP fragmentation offload by network
Michal Kubecek 35166d
-	 * device, so create one single skb packet containing complete
Michal Kubecek 35166d
-	 * udp datagram
Michal Kubecek 35166d
-	 */
Michal Kubecek 35166d
-	skb = skb_peek_tail(queue);
Michal Kubecek 35166d
-	if (!skb) {
Michal Kubecek 35166d
-		skb = sock_alloc_send_skb(sk,
Michal Kubecek 35166d
-			hh_len + fragheaderlen + transhdrlen + 20,
Michal Kubecek 35166d
-			(flags & MSG_DONTWAIT), &err;;
Michal Kubecek 35166d
-
Michal Kubecek 35166d
-		if (!skb)
Michal Kubecek 35166d
-			return err;
Michal Kubecek 35166d
-
Michal Kubecek 35166d
-		/* reserve space for Hardware header */
Michal Kubecek 35166d
-		skb_reserve(skb, hh_len);
Michal Kubecek 35166d
-
Michal Kubecek 35166d
-		/* create space for UDP/IP header */
Michal Kubecek 35166d
-		skb_put(skb, fragheaderlen + transhdrlen);
Michal Kubecek 35166d
-
Michal Kubecek 35166d
-		/* initialize network header pointer */
Michal Kubecek 35166d
-		skb_reset_network_header(skb);
Michal Kubecek 35166d
-
Michal Kubecek 35166d
-		/* initialize protocol header pointer */
Michal Kubecek 35166d
-		skb->transport_header = skb->network_header + fragheaderlen;
Michal Kubecek 35166d
-
Michal Kubecek 35166d
-		skb->csum = 0;
Michal Kubecek 35166d
-
Michal Kubecek 35166d
-		if (flags & MSG_CONFIRM)
Michal Kubecek 35166d
-			skb_set_dst_pending_confirm(skb, 1);
Michal Kubecek 35166d
-
Michal Kubecek 35166d
-		__skb_queue_tail(queue, skb);
Michal Kubecek 35166d
-	} else if (skb_is_gso(skb)) {
Michal Kubecek 35166d
-		goto append;
Michal Kubecek 35166d
-	}
Michal Kubecek 35166d
-
Michal Kubecek 35166d
-	skb->ip_summed = CHECKSUM_PARTIAL;
Michal Kubecek 35166d
-	/* specify the length of each IP datagram fragment */
Michal Kubecek 35166d
-	skb_shinfo(skb)->gso_size = maxfraglen - fragheaderlen;
Michal Kubecek 35166d
-	skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
Michal Kubecek 35166d
-
Michal Kubecek 35166d
-append:
Michal Kubecek 35166d
-	return skb_append_datato_frags(sk, skb, getfrag, from,
Michal Kubecek 35166d
-				       (length - transhdrlen));
Michal Kubecek 35166d
-}
Michal Kubecek 35166d
-
Michal Kubecek 35166d
 static int __ip_append_data(struct sock *sk,
Michal Kubecek 35166d
 			    struct flowi4 *fl4,
Michal Kubecek 35166d
 			    struct sk_buff_head *queue,
Michal Kubecek 35166d
@@ -964,19 +909,6 @@ static int __ip_append_data(struct sock *sk,
Michal Kubecek 35166d
 		csummode = CHECKSUM_PARTIAL;
Michal Kubecek 35166d
 
Michal Kubecek 35166d
 	cork->length += length;
Michal Kubecek 35166d
-	if ((skb && skb_is_gso(skb)) ||
Michal Kubecek 35166d
-	    (((length + (skb ? skb->len : fragheaderlen)) > mtu) &&
Michal Kubecek 35166d
-	    (skb_queue_len(queue) <= 1) &&
Michal Kubecek 35166d
-	    (sk->sk_protocol == IPPROTO_UDP) &&
Michal Kubecek 35166d
-	    (rt->dst.dev->features & NETIF_F_UFO) && !dst_xfrm(&rt->dst) &&
Michal Kubecek 35166d
-	    (sk->sk_type == SOCK_DGRAM) && !sk->sk_no_check_tx)) {
Michal Kubecek 35166d
-		err = ip_ufo_append_data(sk, queue, getfrag, from, length,
Michal Kubecek 35166d
-					 hh_len, fragheaderlen, transhdrlen,
Michal Kubecek 35166d
-					 maxfraglen, flags);
Michal Kubecek 35166d
-		if (err)
Michal Kubecek 35166d
-			goto error;
Michal Kubecek 35166d
-		return 0;
Michal Kubecek 35166d
-	}
Michal Kubecek 35166d
 
Michal Kubecek 35166d
 	/* So, what's going on in the loop below?
Michal Kubecek 35166d
 	 *
Michal Kubecek 35166d
@@ -1287,16 +1219,6 @@ ssize_t	ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page,
Michal Kubecek 35166d
 	if (!skb)
Michal Kubecek 35166d
 		return -EINVAL;
Michal Kubecek 35166d
 
Michal Kubecek 35166d
-	if ((size + skb->len > mtu) &&
Michal Kubecek 35166d
-	    (skb_queue_len(&sk->sk_write_queue) == 1) &&
Michal Kubecek 35166d
-	    (sk->sk_protocol == IPPROTO_UDP) &&
Michal Kubecek 35166d
-	    (rt->dst.dev->features & NETIF_F_UFO)) {
Michal Kubecek 35166d
-		if (skb->ip_summed != CHECKSUM_PARTIAL)
Michal Kubecek 35166d
-			return -EOPNOTSUPP;
Michal Kubecek 35166d
-
Michal Kubecek 35166d
-		skb_shinfo(skb)->gso_size = mtu - fragheaderlen;
Michal Kubecek 35166d
-		skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
Michal Kubecek 35166d
-	}
Michal Kubecek 35166d
 	cork->length += size;
Michal Kubecek 35166d
 
Michal Kubecek 35166d
 	while (size > 0) {
Michal Kubecek 35166d
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
Michal Kubecek 35166d
index d4a2cf85357c..0530e8bbc06a 100644
Michal Kubecek 35166d
--- a/net/ipv6/ip6_output.c
Michal Kubecek 35166d
+++ b/net/ipv6/ip6_output.c
Michal Kubecek 35166d
@@ -1115,69 +1115,6 @@ struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
Michal Kubecek 35166d
 }
Michal Kubecek 35166d
 EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup_flow);
Michal Kubecek 35166d
 
Michal Kubecek 35166d
-static inline int ip6_ufo_append_data(struct sock *sk,
Michal Kubecek 35166d
-			struct sk_buff_head *queue,
Michal Kubecek 35166d
-			int getfrag(void *from, char *to, int offset, int len,
Michal Kubecek 35166d
-			int odd, struct sk_buff *skb),
Michal Kubecek 35166d
-			void *from, int length, int hh_len, int fragheaderlen,
Michal Kubecek 35166d
-			int exthdrlen, int transhdrlen, int mtu,
Michal Kubecek 35166d
-			unsigned int flags, const struct flowi6 *fl6)
Michal Kubecek 35166d
-
Michal Kubecek 35166d
-{
Michal Kubecek 35166d
-	struct sk_buff *skb;
Michal Kubecek 35166d
-	int err;
Michal Kubecek 35166d
-
Michal Kubecek 35166d
-	/* There is support for UDP large send offload by network
Michal Kubecek 35166d
-	 * device, so create one single skb packet containing complete
Michal Kubecek 35166d
-	 * udp datagram
Michal Kubecek 35166d
-	 */
Michal Kubecek 35166d
-	skb = skb_peek_tail(queue);
Michal Kubecek 35166d
-	if (!skb) {
Michal Kubecek 35166d
-		skb = sock_alloc_send_skb(sk,
Michal Kubecek 35166d
-			hh_len + fragheaderlen + transhdrlen + 20,
Michal Kubecek 35166d
-			(flags & MSG_DONTWAIT), &err;;
Michal Kubecek 35166d
-		if (!skb)
Michal Kubecek 35166d
-			return err;
Michal Kubecek 35166d
-
Michal Kubecek 35166d
-		/* reserve space for Hardware header */
Michal Kubecek 35166d
-		skb_reserve(skb, hh_len);
Michal Kubecek 35166d
-
Michal Kubecek 35166d
-		/* create space for UDP/IP header */
Michal Kubecek 35166d
-		skb_put(skb, fragheaderlen + transhdrlen);
Michal Kubecek 35166d
-
Michal Kubecek 35166d
-		/* initialize network header pointer */
Michal Kubecek 35166d
-		skb_set_network_header(skb, exthdrlen);
Michal Kubecek 35166d
-
Michal Kubecek 35166d
-		/* initialize protocol header pointer */
Michal Kubecek 35166d
-		skb->transport_header = skb->network_header + fragheaderlen;
Michal Kubecek 35166d
-
Michal Kubecek 35166d
-		skb->protocol = htons(ETH_P_IPV6);
Michal Kubecek 35166d
-		skb->csum = 0;
Michal Kubecek 35166d
-
Michal Kubecek 35166d
-		if (flags & MSG_CONFIRM)
Michal Kubecek 35166d
-			skb_set_dst_pending_confirm(skb, 1);
Michal Kubecek 35166d
-
Michal Kubecek 35166d
-		__skb_queue_tail(queue, skb);
Michal Kubecek 35166d
-	} else if (skb_is_gso(skb)) {
Michal Kubecek 35166d
-		goto append;
Michal Kubecek 35166d
-	}
Michal Kubecek 35166d
-
Michal Kubecek 35166d
-	skb->ip_summed = CHECKSUM_PARTIAL;
Michal Kubecek 35166d
-	/* Specify the length of each IPv6 datagram fragment.
Michal Kubecek 35166d
-	 * It has to be a multiple of 8.
Michal Kubecek 35166d
-	 */
Michal Kubecek 35166d
-	skb_shinfo(skb)->gso_size = (mtu - fragheaderlen -
Michal Kubecek 35166d
-				     sizeof(struct frag_hdr)) & ~7;
Michal Kubecek 35166d
-	skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
Michal Kubecek 35166d
-	skb_shinfo(skb)->ip6_frag_id = ipv6_select_ident(sock_net(sk),
Michal Kubecek 35166d
-							 &fl6->daddr,
Michal Kubecek 35166d
-							 &fl6->saddr);
Michal Kubecek 35166d
-
Michal Kubecek 35166d
-append:
Michal Kubecek 35166d
-	return skb_append_datato_frags(sk, skb, getfrag, from,
Michal Kubecek 35166d
-				       (length - transhdrlen));
Michal Kubecek 35166d
-}
Michal Kubecek 35166d
-
Michal Kubecek 35166d
 static inline struct ipv6_opt_hdr *ip6_opt_dup(struct ipv6_opt_hdr *src,
Michal Kubecek 35166d
 					       gfp_t gfp)
Michal Kubecek 35166d
 {
Michal Kubecek 35166d
@@ -1386,20 +1323,6 @@ static int __ip6_append_data(struct sock *sk,
Michal Kubecek 35166d
 	 */
Michal Kubecek 35166d
 
Michal Kubecek 35166d
 	cork->length += length;
Michal Kubecek 35166d
-	if ((skb && skb_is_gso(skb)) ||
Michal Kubecek 35166d
-	    (((length + (skb ? skb->len : headersize)) > mtu) &&
Michal Kubecek 35166d
-	    (skb_queue_len(queue) <= 1) &&
Michal Kubecek 35166d
-	    (sk->sk_protocol == IPPROTO_UDP) &&
Michal Kubecek 35166d
-	    (rt->dst.dev->features & NETIF_F_UFO) && !dst_xfrm(&rt->dst) &&
Michal Kubecek 35166d
-	    (sk->sk_type == SOCK_DGRAM) && !udp_get_no_check6_tx(sk))) {
Michal Kubecek 35166d
-		err = ip6_ufo_append_data(sk, queue, getfrag, from, length,
Michal Kubecek 35166d
-					  hh_len, fragheaderlen, exthdrlen,
Michal Kubecek 35166d
-					  transhdrlen, mtu, flags, fl6);
Michal Kubecek 35166d
-		if (err)
Michal Kubecek 35166d
-			goto error;
Michal Kubecek 35166d
-		return 0;
Michal Kubecek 35166d
-	}
Michal Kubecek 35166d
-
Michal Kubecek 35166d
 	if (!skb)
Michal Kubecek 35166d
 		goto alloc_new_skb;
Michal Kubecek 35166d
 
Michal Kubecek 35166d
-- 
Michal Kubecek 35166d
2.14.2
Michal Kubecek 35166d