ipv4: Fix packet size calculation in __ip_append_data
Subsystems (3)
PATCH v2 1/2 ipv4: Fix packet size calculation in __ip_append_data
Git commit 59104f06 (ip: take care of last fragment in ip_append_data) added a check to see if we exceed the mtu when we add trailer_len. However, the mtu is already subtracted by the trailer length when the xfrm transfomation bundles are set up. So IPsec packets with mtu size get fragmented, or if the DF bit is set the packets will not be send even though they match the mtu perfectly fine. This patch actually reverts commit 59104f06.
--- net/ipv4/ip_output.c | 7 ++----- 1 files changed, 2 insertions(+), 5 deletions(-)
net/ipv4/ip_output.c +2 -5
@@ -888,12 +888,9 @@ alloc_new_skb:* because we have no idea what fragment will be * the last. */ -if (datalen == length + fraggap) { +if (datalen == length + fraggap) alloclen += rt->dst.trailer_len; -/* make sure mtu is not reached */ -if (datalen > mtu - fragheaderlen - rt->dst.trailer_len) - datalen -=ALIGN (rt->dst.trailer_len,8 ); - } +if (transhdrlen) { skb = sock_alloc_send_skb(sk, alloclen + hh_len + 15,
Signature · 1 line
1.7.0.4
PATCH 2/2 ipv4: Fix IPsec slowpath fragmentation problem
ip_append_data() builds packets based on the mtu from dst_mtu(rt->dst.path). On IPsec the effective mtu is lower because we need to add the protocol headers and trailers later when we do the IPsec transformations. So after the IPsec transformations the packet might be too big, which leads to a slowpath fragmentation then. This patch fixes this by building the packets based on the lower IPsec mtu from dst_mtu(&rt->dst) and adapts the exthdr handling to this.
--- net/ipv4/ip_output.c | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-)
net/ipv4/ip_output.c +5 -5
@@ -802,8 +802,6 @@ static int __ip_append_data(struct sock *sk, skb =skb_peek_tail (queue); exthdrlen = !skb ? rt->dst.header_len :0 ; - length += exthdrlen; - transhdrlen += exthdrlen; mtu = cork->fragsize; hh_len =LL_RESERVED_SPACE (rt->dst.dev);
@@ -883,6 +881,8 @@ alloc_new_skb:else alloclen = fraglen; + alloclen += exthdrlen; +/* The last fragment gets additional space at tail. * Note, with MSG_MORE we overallocate on fragments, * because we have no idea what fragment will be
@@ -923,11 +923,11 @@ alloc_new_skb:/* * Find where to start putting bytes. */ - data =skb_put (skb, fraglen); + data =skb_put (skb, fraglen + exthdrlen);skb_set_network_header (skb, exthdrlen); skb->transport_header = (skb->network_header + fragheaderlen); - data += fragheaderlen; + data += fragheaderlen + exthdrlen;if (fraggap) { skb->csum = skb_copy_and_csum_bits(
@@ -1061,7 +1061,7 @@ static int ip_setup_cork(struct sock *sk, struct inet_cork *cork,*/ *rtp =NULL ; cork->fragsize = inet->pmtudisc ==IP_PMTUDISC_PROBE ? - rt->dst.dev->mtu :dst_mtu (rt->dst.path); + rt->dst.dev->mtu :dst_mtu (&rt->dst); cork->dst = &rt->dst; cork->length =0 ; cork->tx_flags = ipc->tx_flags;
Signature · 1 line
1.7.0.4
Re: [PATCH 2/2] ipv4: Fix IPsec slowpath fragmentation problem
From: Steffen Klassert <[email protected]>
Date: Wed, 22 Jun 2011 13:05:37 +0200
Quoted 9 lines
ip_append_data()builds packets based on the mtu fromdst_mtu(rt->dst.path). On IPsec the effective mtu is lower because we need to add the protocol headers and trailers later when we do the IPsec transformations. So after the IPsec transformations the packet might be too big, which leads to a slowpath fragmentation then. This patch fixes this by building the packets based on the lower IPsec mtu fromdst_mtu(&rt->dst)and adapts the exthdr handling to this.Signed-off-by Steffen Klassert <[email protected]>
Applied.
From: Steffen Klassert <[email protected]>
Date: Wed, 22 Jun 2011 13:04:37 +0200
Quoted 9 lines
Git commit
59104f06(ip: take care of last fragment inip_append_data) added a check to see if we exceed the mtu when we addtrailer_len. However, the mtu is already subtracted by the trailer length when the xfrm transfomation bundles are set up. So IPsec packets with mtu size get fragmented, or if the DF bit is set the packets will not be send even though they match the mtu perfectly fine. This patch actually reverts commit59104f06.Signed-off-by Steffen Klassert <[email protected]>
Applied.