aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2019-03-29 16:16:32 -0400
committerSteffen Klassert <steffen.klassert@secunet.com>2019-04-08 03:15:28 -0400
commitc9500d7b7de8ff6ac88ee3e38b782889f1616593 (patch)
tree02e6040b32b9686f0f909e5e592dab6690be9275 /net/xfrm
parent4c145dce26013763490df88f2473714f5bc7857d (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.c10
-rw-r--r--net/xfrm/xfrm_input.c14
-rw-r--r--net/xfrm/xfrm_interface.c2
-rw-r--r--net/xfrm/xfrm_output.c20
-rw-r--r--net/xfrm/xfrm_policy.c2
-rw-r--r--net/xfrm/xfrm_state.c16
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 */
54static void xfrm_outer_mode_prep(struct xfrm_state *x, struct sk_buff *skb) 54static 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
352static int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb) 352static 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
374static int xfrm_outer_mode_output(struct xfrm_state *x, struct sk_buff *skb) 374static 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
2205int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload) 2203int __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)