aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv4/esp4.c24
-rw-r--r--net/ipv6/esp6.c18
2 files changed, 16 insertions, 26 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)
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 1e62b7557b00..db1521fcda5b 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -413,19 +413,15 @@ static u32 esp6_get_mtu(struct xfrm_state *x, int mtu)
413 struct esp_data *esp = x->data; 413 struct esp_data *esp = x->data;
414 u32 blksize = ALIGN(crypto_aead_blocksize(esp->aead), 4); 414 u32 blksize = ALIGN(crypto_aead_blocksize(esp->aead), 4);
415 u32 align = max_t(u32, blksize, esp->padlen); 415 u32 align = max_t(u32, blksize, esp->padlen);
416 u32 rem; 416 unsigned int net_adj;
417 417
418 mtu -= x->props.header_len + crypto_aead_authsize(esp->aead); 418 if (x->props.mode != XFRM_MODE_TUNNEL)
419 rem = mtu & (align - 1); 419 net_adj = sizeof(struct ipv6hdr);
420 mtu &= ~(align - 1); 420 else
421 421 net_adj = 0;
422 if (x->props.mode != XFRM_MODE_TUNNEL) {
423 u32 padsize = ((blksize - 1) & 7) + 1;
424 mtu -= blksize - padsize;
425 mtu += min_t(u32, blksize - padsize, rem);
426 }
427 422
428 return mtu - 2; 423 return ((mtu - x->props.header_len - crypto_aead_authsize(esp->aead) -
424 net_adj) & ~(align - 1)) + (net_adj - 2);
429} 425}
430 426
431static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 427static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,