aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2007-04-09 14:47:18 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-04-26 01:28:38 -0400
commitc5c2523893747f88a83376abad310c8ad13f7197 (patch)
tree58f1ab25ac9f7ca7460abbd24e9bab9c8683f6fd /net/ipv6
parent557922584d9c5b6b990bcfb2fec3134f0e73a05d (diff)
[XFRM]: Optimize MTU calculation
Replace the probing based MTU estimation, which usually takes 2-3 iterations to find a fitting value and may underestimate the MTU, by an exact calculation. Also fix underestimation of the XFRM trailer_len, which causes unnecessary reallocations. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/esp6.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 6b76c4c31137..7107bb7e2e62 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -235,22 +235,24 @@ out:
235 return ret; 235 return ret;
236} 236}
237 237
238static u32 esp6_get_max_size(struct xfrm_state *x, int mtu) 238static u32 esp6_get_mtu(struct xfrm_state *x, int mtu)
239{ 239{
240 struct esp_data *esp = x->data; 240 struct esp_data *esp = x->data;
241 u32 blksize = ALIGN(crypto_blkcipher_blocksize(esp->conf.tfm), 4); 241 u32 blksize = ALIGN(crypto_blkcipher_blocksize(esp->conf.tfm), 4);
242 u32 align = max_t(u32, blksize, esp->conf.padlen);
243 u32 rem;
242 244
243 if (x->props.mode == XFRM_MODE_TUNNEL) { 245 mtu -= x->props.header_len + esp->auth.icv_trunc_len;
244 mtu = ALIGN(mtu + 2, blksize); 246 rem = mtu & (align - 1);
245 } else { 247 mtu &= ~(align - 1);
246 /* The worst case. */ 248
249 if (x->props.mode != XFRM_MODE_TUNNEL) {
247 u32 padsize = ((blksize - 1) & 7) + 1; 250 u32 padsize = ((blksize - 1) & 7) + 1;
248 mtu = ALIGN(mtu + 2, padsize) + blksize - padsize; 251 mtu -= blksize - padsize;
252 mtu += min_t(u32, blksize - padsize, rem);
249 } 253 }
250 if (esp->conf.padlen)
251 mtu = ALIGN(mtu, esp->conf.padlen);
252 254
253 return mtu + x->props.header_len + esp->auth.icv_trunc_len; 255 return mtu - 2;
254} 256}
255 257
256static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 258static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
@@ -380,7 +382,7 @@ static struct xfrm_type esp6_type =
380 .proto = IPPROTO_ESP, 382 .proto = IPPROTO_ESP,
381 .init_state = esp6_init_state, 383 .init_state = esp6_init_state,
382 .destructor = esp6_destroy, 384 .destructor = esp6_destroy,
383 .get_max_size = esp6_get_max_size, 385 .get_mtu = esp6_get_mtu,
384 .input = esp6_input, 386 .input = esp6_input,
385 .output = esp6_output, 387 .output = esp6_output,
386 .hdr_offset = xfrm6_find_1stfragopt, 388 .hdr_offset = xfrm6_find_1stfragopt,