From 5462843f51b66f157d64c3519daeaa3eaa82b64e Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Thu, 14 Jan 2010 20:58:20 -0500 Subject: [PATCH] gre: Workarounds for large packets over GRE The first change is to not propagate the IP DF bit from the inner packet to the outer packet. Large TCP packets can get segmented first which will set the DF bit. However these segmented packets might still be too large after the GRE header is added, requiring fragmentation. The second change is to raise the MTU of the GRE tunnel device. This prevents packets from being dropped in the datapath before they can be fragmented. Since the datapath is layer 2 it does not do any fragmentation and drops any packets that are too large. Both of these are temporary workarounds that need to be addressed more carefully in the future. Bug #2379 --- datapath/linux-2.6/compat-2.6/ip_gre.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/datapath/linux-2.6/compat-2.6/ip_gre.c b/datapath/linux-2.6/compat-2.6/ip_gre.c index 246e864e..5a4b98ba 100644 --- a/datapath/linux-2.6/compat-2.6/ip_gre.c +++ b/datapath/linux-2.6/compat-2.6/ip_gre.c @@ -815,6 +815,9 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev if (skb_dst(skb)) skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); + /* XXX: Temporarily allow fragmentation since DF doesn't + * do the right thing with bridging. */ +/* if (skb->protocol == htons(ETH_P_IP)) { df |= (old_iph->frag_off&htons(IP_DF)); @@ -845,7 +848,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev } } #endif - +*/ if (tunnel->err_count > 0) { if (time_before(jiffies, tunnel->err_time + IPTUNNEL_ERR_TIMEO)) { @@ -1008,6 +1011,10 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev) if (mtu < 68) mtu = 68; + /* XXX: Set MTU to the maximum possible value. If we are bridged to a + * device with a larger MTU then packets will be dropped. */ + mtu = 65482; + return mtu; } -- 2.30.2