]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.8.10/ipv4-allow-local-fragmentation-in-ip_finish_output_gso.patch
5.1-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.8.10 / ipv4-allow-local-fragmentation-in-ip_finish_output_gso.patch
1 From foo@baz Fri Nov 18 11:35:46 CET 2016
2 From: Lance Richardson <lrichard@redhat.com>
3 Date: Wed, 2 Nov 2016 16:36:17 -0400
4 Subject: ipv4: allow local fragmentation in ip_finish_output_gso()
5
6 From: Lance Richardson <lrichard@redhat.com>
7
8
9 [ Upstream commit 9ee6c5dc816aa8256257f2cd4008a9291ec7e985 ]
10
11 Some configurations (e.g. geneve interface with default
12 MTU of 1500 over an ethernet interface with 1500 MTU) result
13 in the transmission of packets that exceed the configured MTU.
14 While this should be considered to be a "bad" configuration,
15 it is still allowed and should not result in the sending
16 of packets that exceed the configured MTU.
17
18 Fix by dropping the assumption in ip_finish_output_gso() that
19 locally originated gso packets will never need fragmentation.
20 Basic testing using iperf (observing CPU usage and bandwidth)
21 have shown no measurable performance impact for traffic not
22 requiring fragmentation.
23
24 Fixes: c7ba65d7b649 ("net: ip: push gso skb forwarding handling down the stack")
25 Reported-by: Jan Tluka <jtluka@redhat.com>
26 Signed-off-by: Lance Richardson <lrichard@redhat.com>
27 Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
28 Signed-off-by: David S. Miller <davem@davemloft.net>
29 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
30 ---
31 include/net/ip.h | 1 -
32 net/ipv4/ip_forward.c | 2 +-
33 net/ipv4/ip_output.c | 6 ++----
34 net/ipv4/ip_tunnel_core.c | 11 -----------
35 net/ipv4/ipmr.c | 2 +-
36 5 files changed, 4 insertions(+), 18 deletions(-)
37
38 --- a/include/net/ip.h
39 +++ b/include/net/ip.h
40 @@ -47,7 +47,6 @@ struct inet_skb_parm {
41 #define IPSKB_REROUTED BIT(4)
42 #define IPSKB_DOREDIRECT BIT(5)
43 #define IPSKB_FRAG_PMTU BIT(6)
44 -#define IPSKB_FRAG_SEGS BIT(7)
45
46 u16 frag_max_size;
47 };
48 --- a/net/ipv4/ip_forward.c
49 +++ b/net/ipv4/ip_forward.c
50 @@ -117,7 +117,7 @@ int ip_forward(struct sk_buff *skb)
51 if (opt->is_strictroute && rt->rt_uses_gateway)
52 goto sr_failed;
53
54 - IPCB(skb)->flags |= IPSKB_FORWARDED | IPSKB_FRAG_SEGS;
55 + IPCB(skb)->flags |= IPSKB_FORWARDED;
56 mtu = ip_dst_mtu_maybe_forward(&rt->dst, true);
57 if (ip_exceeds_mtu(skb, mtu)) {
58 IP_INC_STATS(net, IPSTATS_MIB_FRAGFAILS);
59 --- a/net/ipv4/ip_output.c
60 +++ b/net/ipv4/ip_output.c
61 @@ -223,11 +223,9 @@ static int ip_finish_output_gso(struct n
62 struct sk_buff *segs;
63 int ret = 0;
64
65 - /* common case: fragmentation of segments is not allowed,
66 - * or seglen is <= mtu
67 + /* common case: seglen is <= mtu
68 */
69 - if (((IPCB(skb)->flags & IPSKB_FRAG_SEGS) == 0) ||
70 - skb_gso_validate_mtu(skb, mtu))
71 + if (skb_gso_validate_mtu(skb, mtu))
72 return ip_finish_output2(net, sk, skb);
73
74 /* Slowpath - GSO segment length is exceeding the dst MTU.
75 --- a/net/ipv4/ip_tunnel_core.c
76 +++ b/net/ipv4/ip_tunnel_core.c
77 @@ -63,7 +63,6 @@ void iptunnel_xmit(struct sock *sk, stru
78 int pkt_len = skb->len - skb_inner_network_offset(skb);
79 struct net *net = dev_net(rt->dst.dev);
80 struct net_device *dev = skb->dev;
81 - int skb_iif = skb->skb_iif;
82 struct iphdr *iph;
83 int err;
84
85 @@ -73,16 +72,6 @@ void iptunnel_xmit(struct sock *sk, stru
86 skb_dst_set(skb, &rt->dst);
87 memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
88
89 - if (skb_iif && !(df & htons(IP_DF))) {
90 - /* Arrived from an ingress interface, got encapsulated, with
91 - * fragmentation of encapulating frames allowed.
92 - * If skb is gso, the resulting encapsulated network segments
93 - * may exceed dst mtu.
94 - * Allow IP Fragmentation of segments.
95 - */
96 - IPCB(skb)->flags |= IPSKB_FRAG_SEGS;
97 - }
98 -
99 /* Push down and install the IP header. */
100 skb_push(skb, sizeof(struct iphdr));
101 skb_reset_network_header(skb);
102 --- a/net/ipv4/ipmr.c
103 +++ b/net/ipv4/ipmr.c
104 @@ -1749,7 +1749,7 @@ static void ipmr_queue_xmit(struct net *
105 vif->dev->stats.tx_bytes += skb->len;
106 }
107
108 - IPCB(skb)->flags |= IPSKB_FORWARDED | IPSKB_FRAG_SEGS;
109 + IPCB(skb)->flags |= IPSKB_FORWARDED;
110
111 /* RFC1584 teaches, that DVMRP/PIM router must deliver packets locally
112 * not only before forwarding, but after forwarding on all output