aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorBenjamin Poirier <bpoirier@suse.de>2012-05-24 07:32:38 -0400
committerDavid S. Miller <davem@davemloft.net>2012-05-27 01:08:29 -0400
commit91657eafb64b4cb53ec3a2fbc4afc3497f735788 (patch)
treef56665f166dc09e0a2969ee17adb745c5fc89459 /net/ipv4
parentf0d1b3c2bcc5de8a17af5f2274f7fcde8292b5fc (diff)
xfrm: take net hdr len into account for esp payload size calculation
Corrects the function that determines the esp payload size. The calculations done in esp{4,6}_get_mtu() lead to overlength frames in transport mode for certain mtu values and suboptimal frames for others. According to what is done, mainly in esp{,6}_output() and tcp_mtu_to_mss(), net_header_len must be taken into account before doing the alignment calculation. Signed-off-by: Benjamin Poirier <bpoirier@suse.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/esp4.c24
1 files changed, 9 insertions, 15 deletions
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 89a47b35905d..cb982a61536f 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -459,28 +459,22 @@ static u32 esp4_get_mtu(struct xfrm_state *x, int mtu)
459 struct esp_data *esp = x->data; 459 struct esp_data *esp = x->data;
460 u32 blksize = ALIGN(crypto_aead_blocksize(esp->aead), 4); 460 u32 blksize = ALIGN(crypto_aead_blocksize(esp->aead), 4);
461 u32 align = max_t(u32, blksize, esp->padlen); 461 u32 align = max_t(u32, blksize, esp->padlen);
462 u32 rem; 462 unsigned int net_adj;
463
464 mtu -= x->props.header_len + crypto_aead_authsize(esp->aead);
465 rem = mtu & (align - 1);
466 mtu &= ~(align - 1);
467 463
468 switch (x->props.mode) { 464 switch (x->props.mode) {
469 case XFRM_MODE_TUNNEL:
470 break;
471 default:
472 case XFRM_MODE_TRANSPORT: 465 case XFRM_MODE_TRANSPORT:
473 /* The worst case */
474 mtu -= blksize - 4;
475 mtu += min_t(u32, blksize - 4, rem);
476 break;
477 case XFRM_MODE_BEET: 466 case XFRM_MODE_BEET:
478 /* The worst case. */ 467 net_adj = sizeof(struct iphdr);
479 mtu += min_t(u32, IPV4_BEET_PHMAXLEN, rem);
480 break; 468 break;
469 case XFRM_MODE_TUNNEL:
470 net_adj = 0;
471 break;
472 default:
473 BUG();
481 } 474 }
482 475
483 return mtu - 2; 476 return ((mtu - x->props.header_len - crypto_aead_authsize(esp->aead) -
477 net_adj) & ~(align - 1)) + (net_adj - 2);
484} 478}
485 479
486static void esp4_err(struct sk_buff *skb, u32 info) 480static void esp4_err(struct sk_buff *skb, u32 info)