Skip to content

Commit 9ee6c5d

Browse files
hlrichardsondavem330
authored andcommitted
ipv4: allow local fragmentation in ip_finish_output_gso()
Some configurations (e.g. geneve interface with default MTU of 1500 over an ethernet interface with 1500 MTU) result in the transmission of packets that exceed the configured MTU. While this should be considered to be a "bad" configuration, it is still allowed and should not result in the sending of packets that exceed the configured MTU. Fix by dropping the assumption in ip_finish_output_gso() that locally originated gso packets will never need fragmentation. Basic testing using iperf (observing CPU usage and bandwidth) have shown no measurable performance impact for traffic not requiring fragmentation. Fixes: c7ba65d ("net: ip: push gso skb forwarding handling down the stack") Reported-by: Jan Tluka <[email protected]> Signed-off-by: Lance Richardson <[email protected]> Acked-by: Hannes Frederic Sowa <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent da96786 commit 9ee6c5d

File tree

5 files changed

+5
-19
lines changed

5 files changed

+5
-19
lines changed

include/net/ip.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,7 @@ struct inet_skb_parm {
4747
#define IPSKB_REROUTED BIT(4)
4848
#define IPSKB_DOREDIRECT BIT(5)
4949
#define IPSKB_FRAG_PMTU BIT(6)
50-
#define IPSKB_FRAG_SEGS BIT(7)
51-
#define IPSKB_L3SLAVE BIT(8)
50+
#define IPSKB_L3SLAVE BIT(7)
5251

5352
u16 frag_max_size;
5453
};

net/ipv4/ip_forward.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ int ip_forward(struct sk_buff *skb)
117117
if (opt->is_strictroute && rt->rt_uses_gateway)
118118
goto sr_failed;
119119

120-
IPCB(skb)->flags |= IPSKB_FORWARDED | IPSKB_FRAG_SEGS;
120+
IPCB(skb)->flags |= IPSKB_FORWARDED;
121121
mtu = ip_dst_mtu_maybe_forward(&rt->dst, true);
122122
if (ip_exceeds_mtu(skb, mtu)) {
123123
IP_INC_STATS(net, IPSTATS_MIB_FRAGFAILS);

net/ipv4/ip_output.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -239,11 +239,9 @@ static int ip_finish_output_gso(struct net *net, struct sock *sk,
239239
struct sk_buff *segs;
240240
int ret = 0;
241241

242-
/* common case: fragmentation of segments is not allowed,
243-
* or seglen is <= mtu
242+
/* common case: seglen is <= mtu
244243
*/
245-
if (((IPCB(skb)->flags & IPSKB_FRAG_SEGS) == 0) ||
246-
skb_gso_validate_mtu(skb, mtu))
244+
if (skb_gso_validate_mtu(skb, mtu))
247245
return ip_finish_output2(net, sk, skb);
248246

249247
/* Slowpath - GSO segment length is exceeding the dst MTU.

net/ipv4/ip_tunnel_core.c

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ void iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
6363
int pkt_len = skb->len - skb_inner_network_offset(skb);
6464
struct net *net = dev_net(rt->dst.dev);
6565
struct net_device *dev = skb->dev;
66-
int skb_iif = skb->skb_iif;
6766
struct iphdr *iph;
6867
int err;
6968

@@ -73,16 +72,6 @@ void iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
7372
skb_dst_set(skb, &rt->dst);
7473
memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
7574

76-
if (skb_iif && !(df & htons(IP_DF))) {
77-
/* Arrived from an ingress interface, got encapsulated, with
78-
* fragmentation of encapulating frames allowed.
79-
* If skb is gso, the resulting encapsulated network segments
80-
* may exceed dst mtu.
81-
* Allow IP Fragmentation of segments.
82-
*/
83-
IPCB(skb)->flags |= IPSKB_FRAG_SEGS;
84-
}
85-
8675
/* Push down and install the IP header. */
8776
skb_push(skb, sizeof(struct iphdr));
8877
skb_reset_network_header(skb);

net/ipv4/ipmr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1749,7 +1749,7 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt,
17491749
vif->dev->stats.tx_bytes += skb->len;
17501750
}
17511751

1752-
IPCB(skb)->flags |= IPSKB_FORWARDED | IPSKB_FRAG_SEGS;
1752+
IPCB(skb)->flags |= IPSKB_FORWARDED;
17531753

17541754
/* RFC1584 teaches, that DVMRP/PIM router must deliver packets locally
17551755
* not only before forwarding, but after forwarding on all output

0 commit comments

Comments
 (0)