diff options
| author | Florian Westphal <fw@strlen.de> | 2019-03-29 16:16:32 -0400 |
|---|---|---|
| committer | Steffen Klassert <steffen.klassert@secunet.com> | 2019-04-08 03:15:28 -0400 |
| commit | c9500d7b7de8ff6ac88ee3e38b782889f1616593 (patch) | |
| tree | 02e6040b32b9686f0f909e5e592dab6690be9275 /net/xfrm | |
| parent | 4c145dce26013763490df88f2473714f5bc7857d (diff) | |
xfrm: store xfrm_mode directly, not its address
This structure is now only 4 bytes, so its more efficient
to cache a copy rather than its address.
No significant size difference in allmodconfig vmlinux.
With non-modular kernel that has all XFRM options enabled, this
series reduces vmlinux image size by ~11kb. All xfrm_mode
indirections are gone and all modes are built-in.
before (ipsec-next master):
text data bss dec filename
21071494 7233140 11104324 39408958 vmlinux.master
after this series:
21066448 7226772 11104324 39397544 vmlinux.patched
With allmodconfig kernel, the size increase is only 362 bytes,
even all the xfrm config options removed in this series are
modular.
before:
text data bss dec filename
15731286 6936912 4046908 26715106 vmlinux.master
after this series:
15731492 6937068 4046908 26715468 vmlinux
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Diffstat (limited to 'net/xfrm')
| -rw-r--r-- | net/xfrm/xfrm_device.c | 10 | ||||
| -rw-r--r-- | net/xfrm/xfrm_input.c | 14 | ||||
| -rw-r--r-- | net/xfrm/xfrm_interface.c | 2 | ||||
| -rw-r--r-- | net/xfrm/xfrm_output.c | 20 | ||||
| -rw-r--r-- | net/xfrm/xfrm_policy.c | 2 | ||||
| -rw-r--r-- | net/xfrm/xfrm_state.c | 16 |
6 files changed, 32 insertions, 32 deletions
diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c index a20f376fe71f..b24cd86a02c3 100644 --- a/net/xfrm/xfrm_device.c +++ b/net/xfrm/xfrm_device.c | |||
| @@ -53,20 +53,20 @@ static void __xfrm_mode_tunnel_prep(struct xfrm_state *x, struct sk_buff *skb, | |||
| 53 | /* Adjust pointers into the packet when IPsec is done at layer2 */ | 53 | /* Adjust pointers into the packet when IPsec is done at layer2 */ |
| 54 | static void xfrm_outer_mode_prep(struct xfrm_state *x, struct sk_buff *skb) | 54 | static void xfrm_outer_mode_prep(struct xfrm_state *x, struct sk_buff *skb) |
| 55 | { | 55 | { |
| 56 | switch (x->outer_mode->encap) { | 56 | switch (x->outer_mode.encap) { |
| 57 | case XFRM_MODE_TUNNEL: | 57 | case XFRM_MODE_TUNNEL: |
| 58 | if (x->outer_mode->family == AF_INET) | 58 | if (x->outer_mode.family == AF_INET) |
| 59 | return __xfrm_mode_tunnel_prep(x, skb, | 59 | return __xfrm_mode_tunnel_prep(x, skb, |
| 60 | sizeof(struct iphdr)); | 60 | sizeof(struct iphdr)); |
| 61 | if (x->outer_mode->family == AF_INET6) | 61 | if (x->outer_mode.family == AF_INET6) |
| 62 | return __xfrm_mode_tunnel_prep(x, skb, | 62 | return __xfrm_mode_tunnel_prep(x, skb, |
| 63 | sizeof(struct ipv6hdr)); | 63 | sizeof(struct ipv6hdr)); |
| 64 | break; | 64 | break; |
| 65 | case XFRM_MODE_TRANSPORT: | 65 | case XFRM_MODE_TRANSPORT: |
| 66 | if (x->outer_mode->family == AF_INET) | 66 | if (x->outer_mode.family == AF_INET) |
| 67 | return __xfrm_transport_prep(x, skb, | 67 | return __xfrm_transport_prep(x, skb, |
| 68 | sizeof(struct iphdr)); | 68 | sizeof(struct iphdr)); |
| 69 | if (x->outer_mode->family == AF_INET6) | 69 | if (x->outer_mode.family == AF_INET6) |
| 70 | return __xfrm_transport_prep(x, skb, | 70 | return __xfrm_transport_prep(x, skb, |
| 71 | sizeof(struct ipv6hdr)); | 71 | sizeof(struct ipv6hdr)); |
| 72 | break; | 72 | break; |
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index b5a31c8e2088..314973aaa414 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c | |||
| @@ -351,12 +351,12 @@ xfrm_inner_mode_encap_remove(struct xfrm_state *x, | |||
| 351 | 351 | ||
| 352 | static int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb) | 352 | static int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb) |
| 353 | { | 353 | { |
| 354 | const struct xfrm_mode *inner_mode = x->inner_mode; | 354 | const struct xfrm_mode *inner_mode = &x->inner_mode; |
| 355 | const struct xfrm_state_afinfo *afinfo; | 355 | const struct xfrm_state_afinfo *afinfo; |
| 356 | int err = -EAFNOSUPPORT; | 356 | int err = -EAFNOSUPPORT; |
| 357 | 357 | ||
| 358 | rcu_read_lock(); | 358 | rcu_read_lock(); |
| 359 | afinfo = xfrm_state_afinfo_get_rcu(x->outer_mode->family); | 359 | afinfo = xfrm_state_afinfo_get_rcu(x->outer_mode.family); |
| 360 | if (likely(afinfo)) | 360 | if (likely(afinfo)) |
| 361 | err = afinfo->extract_input(x, skb); | 361 | err = afinfo->extract_input(x, skb); |
| 362 | 362 | ||
| @@ -482,7 +482,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) | |||
| 482 | goto drop; | 482 | goto drop; |
| 483 | } | 483 | } |
| 484 | 484 | ||
| 485 | family = x->outer_mode->family; | 485 | family = x->outer_mode.family; |
| 486 | 486 | ||
| 487 | /* An encap_type of -1 indicates async resumption. */ | 487 | /* An encap_type of -1 indicates async resumption. */ |
| 488 | if (encap_type == -1) { | 488 | if (encap_type == -1) { |
| @@ -666,7 +666,7 @@ resume: | |||
| 666 | 666 | ||
| 667 | XFRM_MODE_SKB_CB(skb)->protocol = nexthdr; | 667 | XFRM_MODE_SKB_CB(skb)->protocol = nexthdr; |
| 668 | 668 | ||
| 669 | inner_mode = x->inner_mode; | 669 | inner_mode = &x->inner_mode; |
| 670 | 670 | ||
| 671 | if (x->sel.family == AF_UNSPEC) { | 671 | if (x->sel.family == AF_UNSPEC) { |
| 672 | inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol); | 672 | inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol); |
| @@ -681,7 +681,7 @@ resume: | |||
| 681 | goto drop; | 681 | goto drop; |
| 682 | } | 682 | } |
| 683 | 683 | ||
| 684 | if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) { | 684 | if (x->outer_mode.flags & XFRM_MODE_FLAG_TUNNEL) { |
| 685 | decaps = 1; | 685 | decaps = 1; |
| 686 | break; | 686 | break; |
| 687 | } | 687 | } |
| @@ -691,7 +691,7 @@ resume: | |||
| 691 | * transport mode so the outer address is identical. | 691 | * transport mode so the outer address is identical. |
| 692 | */ | 692 | */ |
| 693 | daddr = &x->id.daddr; | 693 | daddr = &x->id.daddr; |
| 694 | family = x->outer_mode->family; | 694 | family = x->outer_mode.family; |
| 695 | 695 | ||
| 696 | err = xfrm_parse_spi(skb, nexthdr, &spi, &seq); | 696 | err = xfrm_parse_spi(skb, nexthdr, &spi, &seq); |
| 697 | if (err < 0) { | 697 | if (err < 0) { |
| @@ -721,7 +721,7 @@ resume: | |||
| 721 | 721 | ||
| 722 | err = -EAFNOSUPPORT; | 722 | err = -EAFNOSUPPORT; |
| 723 | rcu_read_lock(); | 723 | rcu_read_lock(); |
| 724 | afinfo = xfrm_state_afinfo_get_rcu(x->inner_mode->family); | 724 | afinfo = xfrm_state_afinfo_get_rcu(x->inner_mode.family); |
| 725 | if (likely(afinfo)) | 725 | if (likely(afinfo)) |
| 726 | err = afinfo->transport_finish(skb, xfrm_gro || async); | 726 | err = afinfo->transport_finish(skb, xfrm_gro || async); |
| 727 | rcu_read_unlock(); | 727 | rcu_read_unlock(); |
diff --git a/net/xfrm/xfrm_interface.c b/net/xfrm/xfrm_interface.c index 4fc49dbf3edf..b9f118530db6 100644 --- a/net/xfrm/xfrm_interface.c +++ b/net/xfrm/xfrm_interface.c | |||
| @@ -273,7 +273,7 @@ static int xfrmi_rcv_cb(struct sk_buff *skb, int err) | |||
| 273 | xnet = !net_eq(xi->net, dev_net(skb->dev)); | 273 | xnet = !net_eq(xi->net, dev_net(skb->dev)); |
| 274 | 274 | ||
| 275 | if (xnet) { | 275 | if (xnet) { |
| 276 | inner_mode = x->inner_mode; | 276 | inner_mode = &x->inner_mode; |
| 277 | 277 | ||
| 278 | if (x->sel.family == AF_UNSPEC) { | 278 | if (x->sel.family == AF_UNSPEC) { |
| 279 | inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol); | 279 | inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol); |
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c index 3cb2a328a8ab..a55510f9ff35 100644 --- a/net/xfrm/xfrm_output.c +++ b/net/xfrm/xfrm_output.c | |||
| @@ -334,7 +334,7 @@ static int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb) | |||
| 334 | IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE; | 334 | IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE; |
| 335 | skb->protocol = htons(ETH_P_IP); | 335 | skb->protocol = htons(ETH_P_IP); |
| 336 | 336 | ||
| 337 | switch (x->outer_mode->encap) { | 337 | switch (x->outer_mode.encap) { |
| 338 | case XFRM_MODE_BEET: | 338 | case XFRM_MODE_BEET: |
| 339 | return xfrm4_beet_encap_add(x, skb); | 339 | return xfrm4_beet_encap_add(x, skb); |
| 340 | case XFRM_MODE_TUNNEL: | 340 | case XFRM_MODE_TUNNEL: |
| @@ -357,7 +357,7 @@ static int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb) | |||
| 357 | skb->ignore_df = 1; | 357 | skb->ignore_df = 1; |
| 358 | skb->protocol = htons(ETH_P_IPV6); | 358 | skb->protocol = htons(ETH_P_IPV6); |
| 359 | 359 | ||
| 360 | switch (x->outer_mode->encap) { | 360 | switch (x->outer_mode.encap) { |
| 361 | case XFRM_MODE_BEET: | 361 | case XFRM_MODE_BEET: |
| 362 | return xfrm6_beet_encap_add(x, skb); | 362 | return xfrm6_beet_encap_add(x, skb); |
| 363 | case XFRM_MODE_TUNNEL: | 363 | case XFRM_MODE_TUNNEL: |
| @@ -373,22 +373,22 @@ static int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb) | |||
| 373 | 373 | ||
| 374 | static int xfrm_outer_mode_output(struct xfrm_state *x, struct sk_buff *skb) | 374 | static int xfrm_outer_mode_output(struct xfrm_state *x, struct sk_buff *skb) |
| 375 | { | 375 | { |
| 376 | switch (x->outer_mode->encap) { | 376 | switch (x->outer_mode.encap) { |
| 377 | case XFRM_MODE_BEET: | 377 | case XFRM_MODE_BEET: |
| 378 | case XFRM_MODE_TUNNEL: | 378 | case XFRM_MODE_TUNNEL: |
| 379 | if (x->outer_mode->family == AF_INET) | 379 | if (x->outer_mode.family == AF_INET) |
| 380 | return xfrm4_prepare_output(x, skb); | 380 | return xfrm4_prepare_output(x, skb); |
| 381 | if (x->outer_mode->family == AF_INET6) | 381 | if (x->outer_mode.family == AF_INET6) |
| 382 | return xfrm6_prepare_output(x, skb); | 382 | return xfrm6_prepare_output(x, skb); |
| 383 | break; | 383 | break; |
| 384 | case XFRM_MODE_TRANSPORT: | 384 | case XFRM_MODE_TRANSPORT: |
| 385 | if (x->outer_mode->family == AF_INET) | 385 | if (x->outer_mode.family == AF_INET) |
| 386 | return xfrm4_transport_output(x, skb); | 386 | return xfrm4_transport_output(x, skb); |
| 387 | if (x->outer_mode->family == AF_INET6) | 387 | if (x->outer_mode.family == AF_INET6) |
| 388 | return xfrm6_transport_output(x, skb); | 388 | return xfrm6_transport_output(x, skb); |
| 389 | break; | 389 | break; |
| 390 | case XFRM_MODE_ROUTEOPTIMIZATION: | 390 | case XFRM_MODE_ROUTEOPTIMIZATION: |
| 391 | if (x->outer_mode->family == AF_INET6) | 391 | if (x->outer_mode.family == AF_INET6) |
| 392 | return xfrm6_ro_output(x, skb); | 392 | return xfrm6_ro_output(x, skb); |
| 393 | WARN_ON_ONCE(1); | 393 | WARN_ON_ONCE(1); |
| 394 | break; | 394 | break; |
| @@ -489,7 +489,7 @@ resume: | |||
| 489 | } | 489 | } |
| 490 | skb_dst_set(skb, dst); | 490 | skb_dst_set(skb, dst); |
| 491 | x = dst->xfrm; | 491 | x = dst->xfrm; |
| 492 | } while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL)); | 492 | } while (x && !(x->outer_mode.flags & XFRM_MODE_FLAG_TUNNEL)); |
| 493 | 493 | ||
| 494 | return 0; | 494 | return 0; |
| 495 | 495 | ||
| @@ -626,7 +626,7 @@ static int xfrm_inner_extract_output(struct xfrm_state *x, struct sk_buff *skb) | |||
| 626 | inner_mode = xfrm_ip2inner_mode(x, | 626 | inner_mode = xfrm_ip2inner_mode(x, |
| 627 | xfrm_af2proto(skb_dst(skb)->ops->family)); | 627 | xfrm_af2proto(skb_dst(skb)->ops->family)); |
| 628 | else | 628 | else |
| 629 | inner_mode = x->inner_mode; | 629 | inner_mode = &x->inner_mode; |
| 630 | 630 | ||
| 631 | if (inner_mode == NULL) | 631 | if (inner_mode == NULL) |
| 632 | return -EAFNOSUPPORT; | 632 | return -EAFNOSUPPORT; |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 1a5fd2296556..16e70fc547b1 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
| @@ -2595,7 +2595,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy, | |||
| 2595 | goto put_states; | 2595 | goto put_states; |
| 2596 | } | 2596 | } |
| 2597 | } else | 2597 | } else |
| 2598 | inner_mode = xfrm[i]->inner_mode; | 2598 | inner_mode = &xfrm[i]->inner_mode; |
| 2599 | 2599 | ||
| 2600 | xdst->route = dst; | 2600 | xdst->route = dst; |
| 2601 | dst_copy_metrics(dst1, dst); | 2601 | dst_copy_metrics(dst1, dst); |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index ace26f6dc790..d3d87c409f44 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
| @@ -551,8 +551,6 @@ struct xfrm_state *xfrm_state_alloc(struct net *net) | |||
| 551 | x->lft.hard_packet_limit = XFRM_INF; | 551 | x->lft.hard_packet_limit = XFRM_INF; |
| 552 | x->replay_maxage = 0; | 552 | x->replay_maxage = 0; |
| 553 | x->replay_maxdiff = 0; | 553 | x->replay_maxdiff = 0; |
| 554 | x->inner_mode = NULL; | ||
| 555 | x->inner_mode_iaf = NULL; | ||
| 556 | spin_lock_init(&x->lock); | 554 | spin_lock_init(&x->lock); |
| 557 | } | 555 | } |
| 558 | return x; | 556 | return x; |
| @@ -2204,8 +2202,9 @@ int xfrm_state_mtu(struct xfrm_state *x, int mtu) | |||
| 2204 | 2202 | ||
| 2205 | int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload) | 2203 | int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload) |
| 2206 | { | 2204 | { |
| 2207 | const struct xfrm_mode *inner_mode; | ||
| 2208 | const struct xfrm_state_afinfo *afinfo; | 2205 | const struct xfrm_state_afinfo *afinfo; |
| 2206 | const struct xfrm_mode *inner_mode; | ||
| 2207 | const struct xfrm_mode *outer_mode; | ||
| 2209 | int family = x->props.family; | 2208 | int family = x->props.family; |
| 2210 | int err; | 2209 | int err; |
| 2211 | 2210 | ||
| @@ -2234,7 +2233,7 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload) | |||
| 2234 | family != x->sel.family) | 2233 | family != x->sel.family) |
| 2235 | goto error; | 2234 | goto error; |
| 2236 | 2235 | ||
| 2237 | x->inner_mode = inner_mode; | 2236 | x->inner_mode = *inner_mode; |
| 2238 | } else { | 2237 | } else { |
| 2239 | const struct xfrm_mode *inner_mode_iaf; | 2238 | const struct xfrm_mode *inner_mode_iaf; |
| 2240 | int iafamily = AF_INET; | 2239 | int iafamily = AF_INET; |
| @@ -2246,7 +2245,7 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload) | |||
| 2246 | if (!(inner_mode->flags & XFRM_MODE_FLAG_TUNNEL)) | 2245 | if (!(inner_mode->flags & XFRM_MODE_FLAG_TUNNEL)) |
| 2247 | goto error; | 2246 | goto error; |
| 2248 | 2247 | ||
| 2249 | x->inner_mode = inner_mode; | 2248 | x->inner_mode = *inner_mode; |
| 2250 | 2249 | ||
| 2251 | if (x->props.family == AF_INET) | 2250 | if (x->props.family == AF_INET) |
| 2252 | iafamily = AF_INET6; | 2251 | iafamily = AF_INET6; |
| @@ -2254,7 +2253,7 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload) | |||
| 2254 | inner_mode_iaf = xfrm_get_mode(x->props.mode, iafamily); | 2253 | inner_mode_iaf = xfrm_get_mode(x->props.mode, iafamily); |
| 2255 | if (inner_mode_iaf) { | 2254 | if (inner_mode_iaf) { |
| 2256 | if (inner_mode_iaf->flags & XFRM_MODE_FLAG_TUNNEL) | 2255 | if (inner_mode_iaf->flags & XFRM_MODE_FLAG_TUNNEL) |
| 2257 | x->inner_mode_iaf = inner_mode_iaf; | 2256 | x->inner_mode_iaf = *inner_mode_iaf; |
| 2258 | } | 2257 | } |
| 2259 | } | 2258 | } |
| 2260 | 2259 | ||
| @@ -2268,12 +2267,13 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload) | |||
| 2268 | if (err) | 2267 | if (err) |
| 2269 | goto error; | 2268 | goto error; |
| 2270 | 2269 | ||
| 2271 | x->outer_mode = xfrm_get_mode(x->props.mode, family); | 2270 | outer_mode = xfrm_get_mode(x->props.mode, family); |
| 2272 | if (x->outer_mode == NULL) { | 2271 | if (!outer_mode) { |
| 2273 | err = -EPROTONOSUPPORT; | 2272 | err = -EPROTONOSUPPORT; |
| 2274 | goto error; | 2273 | goto error; |
| 2275 | } | 2274 | } |
| 2276 | 2275 | ||
| 2276 | x->outer_mode = *outer_mode; | ||
| 2277 | if (init_replay) { | 2277 | if (init_replay) { |
| 2278 | err = xfrm_init_replay(x); | 2278 | err = xfrm_init_replay(x); |
| 2279 | if (err) | 2279 | if (err) |
