diff options
author | Florian Westphal <fw@strlen.de> | 2019-03-29 16:16:31 -0400 |
---|---|---|
committer | Steffen Klassert <steffen.klassert@secunet.com> | 2019-04-08 03:15:17 -0400 |
commit | 4c145dce26013763490df88f2473714f5bc7857d (patch) | |
tree | 4c04664251930847a954536f24e0a5f9bcb08768 | |
parent | 733a5fac2f15b55b9059230d098ed04341d2d884 (diff) |
xfrm: make xfrm modes builtin
after previous changes, xfrm_mode contains no function pointers anymore
and all modules defining such struct contain no code except an init/exit
functions to register the xfrm_mode struct with the xfrm core.
Just place the xfrm modes core and remove the modules,
the run-time xfrm_mode register/unregister functionality is removed.
Before:
text data bss dec filename
7523 200 2364 10087 net/xfrm/xfrm_input.o
40003 628 440 41071 net/xfrm/xfrm_state.o
15730338 6937080 4046908 26714326 vmlinux
7389 200 2364 9953 net/xfrm/xfrm_input.o
40574 656 440 41670 net/xfrm/xfrm_state.o
15730084 6937068 4046908 26714060 vmlinux
The xfrm*_mode_{transport,tunnel,beet} modules are gone.
v2: replace CONFIG_INET6_XFRM_MODE_* IS_ENABLED guards with CONFIG_IPV6
ones rather than removing them.
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
-rw-r--r-- | include/net/xfrm.h | 13 | ||||
-rw-r--r-- | net/ipv4/Kconfig | 29 | ||||
-rw-r--r-- | net/ipv4/Makefile | 3 | ||||
-rw-r--r-- | net/ipv4/ip_vti.c | 2 | ||||
-rw-r--r-- | net/ipv4/xfrm4_mode_beet.c | 41 | ||||
-rw-r--r-- | net/ipv4/xfrm4_mode_transport.c | 36 | ||||
-rw-r--r-- | net/ipv4/xfrm4_mode_tunnel.c | 38 | ||||
-rw-r--r-- | net/ipv6/Kconfig | 35 | ||||
-rw-r--r-- | net/ipv6/Makefile | 4 | ||||
-rw-r--r-- | net/ipv6/ip6_vti.c | 2 | ||||
-rw-r--r-- | net/ipv6/xfrm6_mode_beet.c | 42 | ||||
-rw-r--r-- | net/ipv6/xfrm6_mode_ro.c | 55 | ||||
-rw-r--r-- | net/ipv6/xfrm6_mode_transport.c | 37 | ||||
-rw-r--r-- | net/ipv6/xfrm6_mode_tunnel.c | 45 | ||||
-rw-r--r-- | net/xfrm/xfrm_input.c | 13 | ||||
-rw-r--r-- | net/xfrm/xfrm_interface.c | 2 | ||||
-rw-r--r-- | net/xfrm/xfrm_output.c | 15 | ||||
-rw-r--r-- | net/xfrm/xfrm_policy.c | 2 | ||||
-rw-r--r-- | net/xfrm/xfrm_state.c | 158 | ||||
-rw-r--r-- | tools/testing/selftests/net/config | 2 |
20 files changed, 81 insertions, 493 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 8d1c9506bcf6..4ca79cdc3460 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -234,9 +234,9 @@ struct xfrm_state { | |||
234 | /* Reference to data common to all the instances of this | 234 | /* Reference to data common to all the instances of this |
235 | * transformer. */ | 235 | * transformer. */ |
236 | const struct xfrm_type *type; | 236 | const struct xfrm_type *type; |
237 | struct xfrm_mode *inner_mode; | 237 | const struct xfrm_mode *inner_mode; |
238 | struct xfrm_mode *inner_mode_iaf; | 238 | const struct xfrm_mode *inner_mode_iaf; |
239 | struct xfrm_mode *outer_mode; | 239 | const struct xfrm_mode *outer_mode; |
240 | 240 | ||
241 | const struct xfrm_type_offload *type_offload; | 241 | const struct xfrm_type_offload *type_offload; |
242 | 242 | ||
@@ -347,7 +347,6 @@ struct xfrm_state_afinfo { | |||
347 | struct module *owner; | 347 | struct module *owner; |
348 | const struct xfrm_type *type_map[IPPROTO_MAX]; | 348 | const struct xfrm_type *type_map[IPPROTO_MAX]; |
349 | const struct xfrm_type_offload *type_offload_map[IPPROTO_MAX]; | 349 | const struct xfrm_type_offload *type_offload_map[IPPROTO_MAX]; |
350 | struct xfrm_mode *mode_map[XFRM_MODE_MAX]; | ||
351 | 350 | ||
352 | int (*init_flags)(struct xfrm_state *x); | 351 | int (*init_flags)(struct xfrm_state *x); |
353 | void (*init_tempsel)(struct xfrm_selector *sel, | 352 | void (*init_tempsel)(struct xfrm_selector *sel, |
@@ -423,7 +422,6 @@ int xfrm_register_type_offload(const struct xfrm_type_offload *type, unsigned sh | |||
423 | int xfrm_unregister_type_offload(const struct xfrm_type_offload *type, unsigned short family); | 422 | int xfrm_unregister_type_offload(const struct xfrm_type_offload *type, unsigned short family); |
424 | 423 | ||
425 | struct xfrm_mode { | 424 | struct xfrm_mode { |
426 | struct module *owner; | ||
427 | u8 encap; | 425 | u8 encap; |
428 | u8 family; | 426 | u8 family; |
429 | u8 flags; | 427 | u8 flags; |
@@ -434,9 +432,6 @@ enum { | |||
434 | XFRM_MODE_FLAG_TUNNEL = 1, | 432 | XFRM_MODE_FLAG_TUNNEL = 1, |
435 | }; | 433 | }; |
436 | 434 | ||
437 | int xfrm_register_mode(struct xfrm_mode *mode); | ||
438 | void xfrm_unregister_mode(struct xfrm_mode *mode); | ||
439 | |||
440 | static inline int xfrm_af2proto(unsigned int family) | 435 | static inline int xfrm_af2proto(unsigned int family) |
441 | { | 436 | { |
442 | switch(family) { | 437 | switch(family) { |
@@ -449,7 +444,7 @@ static inline int xfrm_af2proto(unsigned int family) | |||
449 | } | 444 | } |
450 | } | 445 | } |
451 | 446 | ||
452 | static inline struct xfrm_mode *xfrm_ip2inner_mode(struct xfrm_state *x, int ipproto) | 447 | static inline const struct xfrm_mode *xfrm_ip2inner_mode(struct xfrm_state *x, int ipproto) |
453 | { | 448 | { |
454 | if ((ipproto == IPPROTO_IPIP && x->props.family == AF_INET) || | 449 | if ((ipproto == IPPROTO_IPIP && x->props.family == AF_INET) || |
455 | (ipproto == IPPROTO_IPV6 && x->props.family == AF_INET6)) | 450 | (ipproto == IPPROTO_IPV6 && x->props.family == AF_INET6)) |
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 32cae39cdff6..8108e97d4285 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig | |||
@@ -304,7 +304,7 @@ config NET_IPVTI | |||
304 | tristate "Virtual (secure) IP: tunneling" | 304 | tristate "Virtual (secure) IP: tunneling" |
305 | select INET_TUNNEL | 305 | select INET_TUNNEL |
306 | select NET_IP_TUNNEL | 306 | select NET_IP_TUNNEL |
307 | depends on INET_XFRM_MODE_TUNNEL | 307 | select XFRM |
308 | ---help--- | 308 | ---help--- |
309 | Tunneling means encapsulating data of one protocol type within | 309 | Tunneling means encapsulating data of one protocol type within |
310 | another protocol and sending it over a channel that understands the | 310 | another protocol and sending it over a channel that understands the |
@@ -396,33 +396,6 @@ config INET_TUNNEL | |||
396 | tristate | 396 | tristate |
397 | default n | 397 | default n |
398 | 398 | ||
399 | config INET_XFRM_MODE_TRANSPORT | ||
400 | tristate "IP: IPsec transport mode" | ||
401 | default y | ||
402 | select XFRM | ||
403 | ---help--- | ||
404 | Support for IPsec transport mode. | ||
405 | |||
406 | If unsure, say Y. | ||
407 | |||
408 | config INET_XFRM_MODE_TUNNEL | ||
409 | tristate "IP: IPsec tunnel mode" | ||
410 | default y | ||
411 | select XFRM | ||
412 | ---help--- | ||
413 | Support for IPsec tunnel mode. | ||
414 | |||
415 | If unsure, say Y. | ||
416 | |||
417 | config INET_XFRM_MODE_BEET | ||
418 | tristate "IP: IPsec BEET mode" | ||
419 | default y | ||
420 | select XFRM | ||
421 | ---help--- | ||
422 | Support for IPsec BEET mode. | ||
423 | |||
424 | If unsure, say Y. | ||
425 | |||
426 | config INET_DIAG | 399 | config INET_DIAG |
427 | tristate "INET: socket monitoring interface" | 400 | tristate "INET: socket monitoring interface" |
428 | default y | 401 | default y |
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile index 58629314eae9..000a61994c8f 100644 --- a/net/ipv4/Makefile +++ b/net/ipv4/Makefile | |||
@@ -37,10 +37,7 @@ obj-$(CONFIG_INET_ESP) += esp4.o | |||
37 | obj-$(CONFIG_INET_ESP_OFFLOAD) += esp4_offload.o | 37 | obj-$(CONFIG_INET_ESP_OFFLOAD) += esp4_offload.o |
38 | obj-$(CONFIG_INET_IPCOMP) += ipcomp.o | 38 | obj-$(CONFIG_INET_IPCOMP) += ipcomp.o |
39 | obj-$(CONFIG_INET_XFRM_TUNNEL) += xfrm4_tunnel.o | 39 | obj-$(CONFIG_INET_XFRM_TUNNEL) += xfrm4_tunnel.o |
40 | obj-$(CONFIG_INET_XFRM_MODE_BEET) += xfrm4_mode_beet.o | ||
41 | obj-$(CONFIG_INET_TUNNEL) += tunnel4.o | 40 | obj-$(CONFIG_INET_TUNNEL) += tunnel4.o |
42 | obj-$(CONFIG_INET_XFRM_MODE_TRANSPORT) += xfrm4_mode_transport.o | ||
43 | obj-$(CONFIG_INET_XFRM_MODE_TUNNEL) += xfrm4_mode_tunnel.o | ||
44 | obj-$(CONFIG_IP_PNP) += ipconfig.o | 41 | obj-$(CONFIG_IP_PNP) += ipconfig.o |
45 | obj-$(CONFIG_NETFILTER) += netfilter.o netfilter/ | 42 | obj-$(CONFIG_NETFILTER) += netfilter.o netfilter/ |
46 | obj-$(CONFIG_INET_DIAG) += inet_diag.o | 43 | obj-$(CONFIG_INET_DIAG) += inet_diag.o |
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 3f3f6d6be318..91926c9a3bc9 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c | |||
@@ -107,7 +107,7 @@ static int vti_rcv_cb(struct sk_buff *skb, int err) | |||
107 | struct net_device *dev; | 107 | struct net_device *dev; |
108 | struct pcpu_sw_netstats *tstats; | 108 | struct pcpu_sw_netstats *tstats; |
109 | struct xfrm_state *x; | 109 | struct xfrm_state *x; |
110 | struct xfrm_mode *inner_mode; | 110 | const struct xfrm_mode *inner_mode; |
111 | struct ip_tunnel *tunnel = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4; | 111 | struct ip_tunnel *tunnel = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4; |
112 | u32 orig_mark = skb->mark; | 112 | u32 orig_mark = skb->mark; |
113 | int ret; | 113 | int ret; |
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c deleted file mode 100644 index ba84b278e627..000000000000 --- a/net/ipv4/xfrm4_mode_beet.c +++ /dev/null | |||
@@ -1,41 +0,0 @@ | |||
1 | /* | ||
2 | * xfrm4_mode_beet.c - BEET mode encapsulation for IPv4. | ||
3 | * | ||
4 | * Copyright (c) 2006 Diego Beltrami <diego.beltrami@gmail.com> | ||
5 | * Miika Komu <miika@iki.fi> | ||
6 | * Herbert Xu <herbert@gondor.apana.org.au> | ||
7 | * Abhinav Pathak <abhinav.pathak@hiit.fi> | ||
8 | * Jeff Ahrenholz <ahrenholz@gmail.com> | ||
9 | */ | ||
10 | |||
11 | #include <linux/init.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/skbuff.h> | ||
15 | #include <linux/stringify.h> | ||
16 | #include <net/dst.h> | ||
17 | #include <net/ip.h> | ||
18 | #include <net/xfrm.h> | ||
19 | |||
20 | |||
21 | static struct xfrm_mode xfrm4_beet_mode = { | ||
22 | .owner = THIS_MODULE, | ||
23 | .encap = XFRM_MODE_BEET, | ||
24 | .flags = XFRM_MODE_FLAG_TUNNEL, | ||
25 | .family = AF_INET, | ||
26 | }; | ||
27 | |||
28 | static int __init xfrm4_beet_init(void) | ||
29 | { | ||
30 | return xfrm_register_mode(&xfrm4_beet_mode); | ||
31 | } | ||
32 | |||
33 | static void __exit xfrm4_beet_exit(void) | ||
34 | { | ||
35 | xfrm_unregister_mode(&xfrm4_beet_mode); | ||
36 | } | ||
37 | |||
38 | module_init(xfrm4_beet_init); | ||
39 | module_exit(xfrm4_beet_exit); | ||
40 | MODULE_LICENSE("GPL"); | ||
41 | MODULE_ALIAS_XFRM_MODE(AF_INET, XFRM_MODE_BEET); | ||
diff --git a/net/ipv4/xfrm4_mode_transport.c b/net/ipv4/xfrm4_mode_transport.c deleted file mode 100644 index 397863ea762b..000000000000 --- a/net/ipv4/xfrm4_mode_transport.c +++ /dev/null | |||
@@ -1,36 +0,0 @@ | |||
1 | /* | ||
2 | * xfrm4_mode_transport.c - Transport mode encapsulation for IPv4. | ||
3 | * | ||
4 | * Copyright (c) 2004-2006 Herbert Xu <herbert@gondor.apana.org.au> | ||
5 | */ | ||
6 | |||
7 | #include <linux/init.h> | ||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/module.h> | ||
10 | #include <linux/skbuff.h> | ||
11 | #include <linux/stringify.h> | ||
12 | #include <net/dst.h> | ||
13 | #include <net/ip.h> | ||
14 | #include <net/xfrm.h> | ||
15 | #include <net/protocol.h> | ||
16 | |||
17 | static struct xfrm_mode xfrm4_transport_mode = { | ||
18 | .owner = THIS_MODULE, | ||
19 | .encap = XFRM_MODE_TRANSPORT, | ||
20 | .family = AF_INET, | ||
21 | }; | ||
22 | |||
23 | static int __init xfrm4_transport_init(void) | ||
24 | { | ||
25 | return xfrm_register_mode(&xfrm4_transport_mode); | ||
26 | } | ||
27 | |||
28 | static void __exit xfrm4_transport_exit(void) | ||
29 | { | ||
30 | xfrm_unregister_mode(&xfrm4_transport_mode); | ||
31 | } | ||
32 | |||
33 | module_init(xfrm4_transport_init); | ||
34 | module_exit(xfrm4_transport_exit); | ||
35 | MODULE_LICENSE("GPL"); | ||
36 | MODULE_ALIAS_XFRM_MODE(AF_INET, XFRM_MODE_TRANSPORT); | ||
diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c deleted file mode 100644 index b2b132c800fc..000000000000 --- a/net/ipv4/xfrm4_mode_tunnel.c +++ /dev/null | |||
@@ -1,38 +0,0 @@ | |||
1 | /* | ||
2 | * xfrm4_mode_tunnel.c - Tunnel mode encapsulation for IPv4. | ||
3 | * | ||
4 | * Copyright (c) 2004-2006 Herbert Xu <herbert@gondor.apana.org.au> | ||
5 | */ | ||
6 | |||
7 | #include <linux/gfp.h> | ||
8 | #include <linux/init.h> | ||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/skbuff.h> | ||
12 | #include <linux/stringify.h> | ||
13 | #include <net/dst.h> | ||
14 | #include <net/inet_ecn.h> | ||
15 | #include <net/ip.h> | ||
16 | #include <net/xfrm.h> | ||
17 | |||
18 | static struct xfrm_mode xfrm4_tunnel_mode = { | ||
19 | .owner = THIS_MODULE, | ||
20 | .encap = XFRM_MODE_TUNNEL, | ||
21 | .flags = XFRM_MODE_FLAG_TUNNEL, | ||
22 | .family = AF_INET, | ||
23 | }; | ||
24 | |||
25 | static int __init xfrm4_mode_tunnel_init(void) | ||
26 | { | ||
27 | return xfrm_register_mode(&xfrm4_tunnel_mode); | ||
28 | } | ||
29 | |||
30 | static void __exit xfrm4_mode_tunnel_exit(void) | ||
31 | { | ||
32 | xfrm_unregister_mode(&xfrm4_tunnel_mode); | ||
33 | } | ||
34 | |||
35 | module_init(xfrm4_mode_tunnel_init); | ||
36 | module_exit(xfrm4_mode_tunnel_exit); | ||
37 | MODULE_LICENSE("GPL"); | ||
38 | MODULE_ALIAS_XFRM_MODE(AF_INET, XFRM_MODE_TUNNEL); | ||
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig index 613282c65a10..cd915e332c98 100644 --- a/net/ipv6/Kconfig +++ b/net/ipv6/Kconfig | |||
@@ -135,44 +135,11 @@ config INET6_TUNNEL | |||
135 | tristate | 135 | tristate |
136 | default n | 136 | default n |
137 | 137 | ||
138 | config INET6_XFRM_MODE_TRANSPORT | ||
139 | tristate "IPv6: IPsec transport mode" | ||
140 | default IPV6 | ||
141 | select XFRM | ||
142 | ---help--- | ||
143 | Support for IPsec transport mode. | ||
144 | |||
145 | If unsure, say Y. | ||
146 | |||
147 | config INET6_XFRM_MODE_TUNNEL | ||
148 | tristate "IPv6: IPsec tunnel mode" | ||
149 | default IPV6 | ||
150 | select XFRM | ||
151 | ---help--- | ||
152 | Support for IPsec tunnel mode. | ||
153 | |||
154 | If unsure, say Y. | ||
155 | |||
156 | config INET6_XFRM_MODE_BEET | ||
157 | tristate "IPv6: IPsec BEET mode" | ||
158 | default IPV6 | ||
159 | select XFRM | ||
160 | ---help--- | ||
161 | Support for IPsec BEET mode. | ||
162 | |||
163 | If unsure, say Y. | ||
164 | |||
165 | config INET6_XFRM_MODE_ROUTEOPTIMIZATION | ||
166 | tristate "IPv6: MIPv6 route optimization mode" | ||
167 | select XFRM | ||
168 | ---help--- | ||
169 | Support for MIPv6 route optimization mode. | ||
170 | |||
171 | config IPV6_VTI | 138 | config IPV6_VTI |
172 | tristate "Virtual (secure) IPv6: tunneling" | 139 | tristate "Virtual (secure) IPv6: tunneling" |
173 | select IPV6_TUNNEL | 140 | select IPV6_TUNNEL |
174 | select NET_IP_TUNNEL | 141 | select NET_IP_TUNNEL |
175 | depends on INET6_XFRM_MODE_TUNNEL | 142 | select XFRM |
176 | ---help--- | 143 | ---help--- |
177 | Tunneling means encapsulating data of one protocol type within | 144 | Tunneling means encapsulating data of one protocol type within |
178 | another protocol and sending it over a channel that understands the | 145 | another protocol and sending it over a channel that understands the |
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile index e0026fa1261b..8ccf35514015 100644 --- a/net/ipv6/Makefile +++ b/net/ipv6/Makefile | |||
@@ -35,10 +35,6 @@ obj-$(CONFIG_INET6_ESP_OFFLOAD) += esp6_offload.o | |||
35 | obj-$(CONFIG_INET6_IPCOMP) += ipcomp6.o | 35 | obj-$(CONFIG_INET6_IPCOMP) += ipcomp6.o |
36 | obj-$(CONFIG_INET6_XFRM_TUNNEL) += xfrm6_tunnel.o | 36 | obj-$(CONFIG_INET6_XFRM_TUNNEL) += xfrm6_tunnel.o |
37 | obj-$(CONFIG_INET6_TUNNEL) += tunnel6.o | 37 | obj-$(CONFIG_INET6_TUNNEL) += tunnel6.o |
38 | obj-$(CONFIG_INET6_XFRM_MODE_TRANSPORT) += xfrm6_mode_transport.o | ||
39 | obj-$(CONFIG_INET6_XFRM_MODE_TUNNEL) += xfrm6_mode_tunnel.o | ||
40 | obj-$(CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION) += xfrm6_mode_ro.o | ||
41 | obj-$(CONFIG_INET6_XFRM_MODE_BEET) += xfrm6_mode_beet.o | ||
42 | obj-$(CONFIG_IPV6_MIP6) += mip6.o | 38 | obj-$(CONFIG_IPV6_MIP6) += mip6.o |
43 | obj-$(CONFIG_IPV6_ILA) += ila/ | 39 | obj-$(CONFIG_IPV6_ILA) += ila/ |
44 | obj-$(CONFIG_NETFILTER) += netfilter/ | 40 | obj-$(CONFIG_NETFILTER) += netfilter/ |
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index 369803c581b7..71ec5e60cf8f 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c | |||
@@ -342,7 +342,7 @@ static int vti6_rcv_cb(struct sk_buff *skb, int err) | |||
342 | struct net_device *dev; | 342 | struct net_device *dev; |
343 | struct pcpu_sw_netstats *tstats; | 343 | struct pcpu_sw_netstats *tstats; |
344 | struct xfrm_state *x; | 344 | struct xfrm_state *x; |
345 | struct xfrm_mode *inner_mode; | 345 | const struct xfrm_mode *inner_mode; |
346 | struct ip6_tnl *t = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6; | 346 | struct ip6_tnl *t = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6; |
347 | u32 orig_mark = skb->mark; | 347 | u32 orig_mark = skb->mark; |
348 | int ret; | 348 | int ret; |
diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c deleted file mode 100644 index 1c4a76bdd889..000000000000 --- a/net/ipv6/xfrm6_mode_beet.c +++ /dev/null | |||
@@ -1,42 +0,0 @@ | |||
1 | /* | ||
2 | * xfrm6_mode_beet.c - BEET mode encapsulation for IPv6. | ||
3 | * | ||
4 | * Copyright (c) 2006 Diego Beltrami <diego.beltrami@gmail.com> | ||
5 | * Miika Komu <miika@iki.fi> | ||
6 | * Herbert Xu <herbert@gondor.apana.org.au> | ||
7 | * Abhinav Pathak <abhinav.pathak@hiit.fi> | ||
8 | * Jeff Ahrenholz <ahrenholz@gmail.com> | ||
9 | */ | ||
10 | |||
11 | #include <linux/init.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/skbuff.h> | ||
15 | #include <linux/stringify.h> | ||
16 | #include <net/dsfield.h> | ||
17 | #include <net/dst.h> | ||
18 | #include <net/inet_ecn.h> | ||
19 | #include <net/ipv6.h> | ||
20 | #include <net/xfrm.h> | ||
21 | |||
22 | static struct xfrm_mode xfrm6_beet_mode = { | ||
23 | .owner = THIS_MODULE, | ||
24 | .encap = XFRM_MODE_BEET, | ||
25 | .flags = XFRM_MODE_FLAG_TUNNEL, | ||
26 | .family = AF_INET6, | ||
27 | }; | ||
28 | |||
29 | static int __init xfrm6_beet_init(void) | ||
30 | { | ||
31 | return xfrm_register_mode(&xfrm6_beet_mode); | ||
32 | } | ||
33 | |||
34 | static void __exit xfrm6_beet_exit(void) | ||
35 | { | ||
36 | xfrm_unregister_mode(&xfrm6_beet_mode); | ||
37 | } | ||
38 | |||
39 | module_init(xfrm6_beet_init); | ||
40 | module_exit(xfrm6_beet_exit); | ||
41 | MODULE_LICENSE("GPL"); | ||
42 | MODULE_ALIAS_XFRM_MODE(AF_INET6, XFRM_MODE_BEET); | ||
diff --git a/net/ipv6/xfrm6_mode_ro.c b/net/ipv6/xfrm6_mode_ro.c deleted file mode 100644 index d0a6a4dbd689..000000000000 --- a/net/ipv6/xfrm6_mode_ro.c +++ /dev/null | |||
@@ -1,55 +0,0 @@ | |||
1 | /* | ||
2 | * xfrm6_mode_ro.c - Route optimization mode for IPv6. | ||
3 | * | ||
4 | * Copyright (C)2003-2006 Helsinki University of Technology | ||
5 | * Copyright (C)2003-2006 USAGI/WIDE Project | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||
19 | */ | ||
20 | /* | ||
21 | * Authors: | ||
22 | * Noriaki TAKAMIYA @USAGI | ||
23 | * Masahide NAKAMURA @USAGI | ||
24 | */ | ||
25 | |||
26 | #include <linux/init.h> | ||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/skbuff.h> | ||
30 | #include <linux/spinlock.h> | ||
31 | #include <linux/stringify.h> | ||
32 | #include <linux/time.h> | ||
33 | #include <net/ipv6.h> | ||
34 | #include <net/xfrm.h> | ||
35 | |||
36 | static struct xfrm_mode xfrm6_ro_mode = { | ||
37 | .owner = THIS_MODULE, | ||
38 | .encap = XFRM_MODE_ROUTEOPTIMIZATION, | ||
39 | .family = AF_INET6, | ||
40 | }; | ||
41 | |||
42 | static int __init xfrm6_ro_init(void) | ||
43 | { | ||
44 | return xfrm_register_mode(&xfrm6_ro_mode); | ||
45 | } | ||
46 | |||
47 | static void __exit xfrm6_ro_exit(void) | ||
48 | { | ||
49 | xfrm_unregister_mode(&xfrm6_ro_mode); | ||
50 | } | ||
51 | |||
52 | module_init(xfrm6_ro_init); | ||
53 | module_exit(xfrm6_ro_exit); | ||
54 | MODULE_LICENSE("GPL"); | ||
55 | MODULE_ALIAS_XFRM_MODE(AF_INET6, XFRM_MODE_ROUTEOPTIMIZATION); | ||
diff --git a/net/ipv6/xfrm6_mode_transport.c b/net/ipv6/xfrm6_mode_transport.c deleted file mode 100644 index d90c934c2f1a..000000000000 --- a/net/ipv6/xfrm6_mode_transport.c +++ /dev/null | |||
@@ -1,37 +0,0 @@ | |||
1 | /* | ||
2 | * xfrm6_mode_transport.c - Transport mode encapsulation for IPv6. | ||
3 | * | ||
4 | * Copyright (C) 2002 USAGI/WIDE Project | ||
5 | * Copyright (c) 2004-2006 Herbert Xu <herbert@gondor.apana.org.au> | ||
6 | */ | ||
7 | |||
8 | #include <linux/init.h> | ||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/skbuff.h> | ||
12 | #include <linux/stringify.h> | ||
13 | #include <net/dst.h> | ||
14 | #include <net/ipv6.h> | ||
15 | #include <net/xfrm.h> | ||
16 | #include <net/protocol.h> | ||
17 | |||
18 | static struct xfrm_mode xfrm6_transport_mode = { | ||
19 | .owner = THIS_MODULE, | ||
20 | .encap = XFRM_MODE_TRANSPORT, | ||
21 | .family = AF_INET6, | ||
22 | }; | ||
23 | |||
24 | static int __init xfrm6_transport_init(void) | ||
25 | { | ||
26 | return xfrm_register_mode(&xfrm6_transport_mode); | ||
27 | } | ||
28 | |||
29 | static void __exit xfrm6_transport_exit(void) | ||
30 | { | ||
31 | xfrm_unregister_mode(&xfrm6_transport_mode); | ||
32 | } | ||
33 | |||
34 | module_init(xfrm6_transport_init); | ||
35 | module_exit(xfrm6_transport_exit); | ||
36 | MODULE_LICENSE("GPL"); | ||
37 | MODULE_ALIAS_XFRM_MODE(AF_INET6, XFRM_MODE_TRANSPORT); | ||
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c deleted file mode 100644 index e5c928dd70e3..000000000000 --- a/net/ipv6/xfrm6_mode_tunnel.c +++ /dev/null | |||
@@ -1,45 +0,0 @@ | |||
1 | /* | ||
2 | * xfrm6_mode_tunnel.c - Tunnel mode encapsulation for IPv6. | ||
3 | * | ||
4 | * Copyright (C) 2002 USAGI/WIDE Project | ||
5 | * Copyright (c) 2004-2006 Herbert Xu <herbert@gondor.apana.org.au> | ||
6 | */ | ||
7 | |||
8 | #include <linux/gfp.h> | ||
9 | #include <linux/init.h> | ||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/skbuff.h> | ||
13 | #include <linux/stringify.h> | ||
14 | #include <net/dsfield.h> | ||
15 | #include <net/dst.h> | ||
16 | #include <net/inet_ecn.h> | ||
17 | #include <net/ip6_route.h> | ||
18 | #include <net/ipv6.h> | ||
19 | #include <net/xfrm.h> | ||
20 | |||
21 | /* Add encapsulation header. | ||
22 | * | ||
23 | * The top IP header will be constructed per RFC 2401. | ||
24 | */ | ||
25 | static struct xfrm_mode xfrm6_tunnel_mode = { | ||
26 | .owner = THIS_MODULE, | ||
27 | .encap = XFRM_MODE_TUNNEL, | ||
28 | .flags = XFRM_MODE_FLAG_TUNNEL, | ||
29 | .family = AF_INET6, | ||
30 | }; | ||
31 | |||
32 | static int __init xfrm6_mode_tunnel_init(void) | ||
33 | { | ||
34 | return xfrm_register_mode(&xfrm6_tunnel_mode); | ||
35 | } | ||
36 | |||
37 | static void __exit xfrm6_mode_tunnel_exit(void) | ||
38 | { | ||
39 | xfrm_unregister_mode(&xfrm6_tunnel_mode); | ||
40 | } | ||
41 | |||
42 | module_init(xfrm6_mode_tunnel_init); | ||
43 | module_exit(xfrm6_mode_tunnel_exit); | ||
44 | MODULE_LICENSE("GPL"); | ||
45 | MODULE_ALIAS_XFRM_MODE(AF_INET6, XFRM_MODE_TUNNEL); | ||
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index 74b53c13279b..b5a31c8e2088 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c | |||
@@ -351,7 +351,7 @@ 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 | 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 | ||
@@ -394,7 +394,6 @@ static int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb) | |||
394 | */ | 394 | */ |
395 | static int xfrm4_transport_input(struct xfrm_state *x, struct sk_buff *skb) | 395 | static int xfrm4_transport_input(struct xfrm_state *x, struct sk_buff *skb) |
396 | { | 396 | { |
397 | #if IS_ENABLED(CONFIG_INET_XFRM_MODE_TRANSPORT) | ||
398 | int ihl = skb->data - skb_transport_header(skb); | 397 | int ihl = skb->data - skb_transport_header(skb); |
399 | 398 | ||
400 | if (skb->transport_header != skb->network_header) { | 399 | if (skb->transport_header != skb->network_header) { |
@@ -405,14 +404,11 @@ static int xfrm4_transport_input(struct xfrm_state *x, struct sk_buff *skb) | |||
405 | ip_hdr(skb)->tot_len = htons(skb->len + ihl); | 404 | ip_hdr(skb)->tot_len = htons(skb->len + ihl); |
406 | skb_reset_transport_header(skb); | 405 | skb_reset_transport_header(skb); |
407 | return 0; | 406 | return 0; |
408 | #else | ||
409 | return -EOPNOTSUPP; | ||
410 | #endif | ||
411 | } | 407 | } |
412 | 408 | ||
413 | static int xfrm6_transport_input(struct xfrm_state *x, struct sk_buff *skb) | 409 | static int xfrm6_transport_input(struct xfrm_state *x, struct sk_buff *skb) |
414 | { | 410 | { |
415 | #if IS_ENABLED(CONFIG_INET6_XFRM_MODE_TRANSPORT) | 411 | #if IS_ENABLED(CONFIG_IPV6) |
416 | int ihl = skb->data - skb_transport_header(skb); | 412 | int ihl = skb->data - skb_transport_header(skb); |
417 | 413 | ||
418 | if (skb->transport_header != skb->network_header) { | 414 | if (skb->transport_header != skb->network_header) { |
@@ -425,7 +421,8 @@ static int xfrm6_transport_input(struct xfrm_state *x, struct sk_buff *skb) | |||
425 | skb_reset_transport_header(skb); | 421 | skb_reset_transport_header(skb); |
426 | return 0; | 422 | return 0; |
427 | #else | 423 | #else |
428 | return -EOPNOTSUPP; | 424 | WARN_ON_ONCE(1); |
425 | return -EAFNOSUPPORT; | ||
429 | #endif | 426 | #endif |
430 | } | 427 | } |
431 | 428 | ||
@@ -458,12 +455,12 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) | |||
458 | { | 455 | { |
459 | const struct xfrm_state_afinfo *afinfo; | 456 | const struct xfrm_state_afinfo *afinfo; |
460 | struct net *net = dev_net(skb->dev); | 457 | struct net *net = dev_net(skb->dev); |
458 | const struct xfrm_mode *inner_mode; | ||
461 | int err; | 459 | int err; |
462 | __be32 seq; | 460 | __be32 seq; |
463 | __be32 seq_hi; | 461 | __be32 seq_hi; |
464 | struct xfrm_state *x = NULL; | 462 | struct xfrm_state *x = NULL; |
465 | xfrm_address_t *daddr; | 463 | xfrm_address_t *daddr; |
466 | struct xfrm_mode *inner_mode; | ||
467 | u32 mark = skb->mark; | 464 | u32 mark = skb->mark; |
468 | unsigned int family = AF_UNSPEC; | 465 | unsigned int family = AF_UNSPEC; |
469 | int decaps = 0; | 466 | int decaps = 0; |
diff --git a/net/xfrm/xfrm_interface.c b/net/xfrm/xfrm_interface.c index 93efb0965e7d..4fc49dbf3edf 100644 --- a/net/xfrm/xfrm_interface.c +++ b/net/xfrm/xfrm_interface.c | |||
@@ -244,8 +244,8 @@ static void xfrmi_scrub_packet(struct sk_buff *skb, bool xnet) | |||
244 | 244 | ||
245 | static int xfrmi_rcv_cb(struct sk_buff *skb, int err) | 245 | static int xfrmi_rcv_cb(struct sk_buff *skb, int err) |
246 | { | 246 | { |
247 | const struct xfrm_mode *inner_mode; | ||
247 | struct pcpu_sw_netstats *tstats; | 248 | struct pcpu_sw_netstats *tstats; |
248 | struct xfrm_mode *inner_mode; | ||
249 | struct net_device *dev; | 249 | struct net_device *dev; |
250 | struct xfrm_state *x; | 250 | struct xfrm_state *x; |
251 | struct xfrm_if *xi; | 251 | struct xfrm_if *xi; |
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c index 17c4f58d28ea..3cb2a328a8ab 100644 --- a/net/xfrm/xfrm_output.c +++ b/net/xfrm/xfrm_output.c | |||
@@ -61,7 +61,6 @@ static struct dst_entry *skb_dst_pop(struct sk_buff *skb) | |||
61 | */ | 61 | */ |
62 | static int xfrm4_transport_output(struct xfrm_state *x, struct sk_buff *skb) | 62 | static int xfrm4_transport_output(struct xfrm_state *x, struct sk_buff *skb) |
63 | { | 63 | { |
64 | #if IS_ENABLED(CONFIG_INET_XFRM_MODE_TRANSPORT) | ||
65 | struct iphdr *iph = ip_hdr(skb); | 64 | struct iphdr *iph = ip_hdr(skb); |
66 | int ihl = iph->ihl * 4; | 65 | int ihl = iph->ihl * 4; |
67 | 66 | ||
@@ -74,10 +73,6 @@ static int xfrm4_transport_output(struct xfrm_state *x, struct sk_buff *skb) | |||
74 | __skb_pull(skb, ihl); | 73 | __skb_pull(skb, ihl); |
75 | memmove(skb_network_header(skb), iph, ihl); | 74 | memmove(skb_network_header(skb), iph, ihl); |
76 | return 0; | 75 | return 0; |
77 | #else | ||
78 | WARN_ON_ONCE(1); | ||
79 | return -EOPNOTSUPP; | ||
80 | #endif | ||
81 | } | 76 | } |
82 | 77 | ||
83 | /* Add encapsulation header. | 78 | /* Add encapsulation header. |
@@ -87,7 +82,7 @@ static int xfrm4_transport_output(struct xfrm_state *x, struct sk_buff *skb) | |||
87 | */ | 82 | */ |
88 | static int xfrm6_transport_output(struct xfrm_state *x, struct sk_buff *skb) | 83 | static int xfrm6_transport_output(struct xfrm_state *x, struct sk_buff *skb) |
89 | { | 84 | { |
90 | #if IS_ENABLED(CONFIG_INET6_XFRM_MODE_TRANSPORT) | 85 | #if IS_ENABLED(CONFIG_IPV6) |
91 | struct ipv6hdr *iph; | 86 | struct ipv6hdr *iph; |
92 | u8 *prevhdr; | 87 | u8 *prevhdr; |
93 | int hdr_len; | 88 | int hdr_len; |
@@ -107,7 +102,7 @@ static int xfrm6_transport_output(struct xfrm_state *x, struct sk_buff *skb) | |||
107 | return 0; | 102 | return 0; |
108 | #else | 103 | #else |
109 | WARN_ON_ONCE(1); | 104 | WARN_ON_ONCE(1); |
110 | return -EOPNOTSUPP; | 105 | return -EAFNOSUPPORT; |
111 | #endif | 106 | #endif |
112 | } | 107 | } |
113 | 108 | ||
@@ -118,7 +113,7 @@ static int xfrm6_transport_output(struct xfrm_state *x, struct sk_buff *skb) | |||
118 | */ | 113 | */ |
119 | static int xfrm6_ro_output(struct xfrm_state *x, struct sk_buff *skb) | 114 | static int xfrm6_ro_output(struct xfrm_state *x, struct sk_buff *skb) |
120 | { | 115 | { |
121 | #if IS_ENABLED(CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION) | 116 | #if IS_ENABLED(CONFIG_IPV6) |
122 | struct ipv6hdr *iph; | 117 | struct ipv6hdr *iph; |
123 | u8 *prevhdr; | 118 | u8 *prevhdr; |
124 | int hdr_len; | 119 | int hdr_len; |
@@ -140,7 +135,7 @@ static int xfrm6_ro_output(struct xfrm_state *x, struct sk_buff *skb) | |||
140 | return 0; | 135 | return 0; |
141 | #else | 136 | #else |
142 | WARN_ON_ONCE(1); | 137 | WARN_ON_ONCE(1); |
143 | return -EOPNOTSUPP; | 138 | return -EAFNOSUPPORT; |
144 | #endif | 139 | #endif |
145 | } | 140 | } |
146 | 141 | ||
@@ -624,7 +619,7 @@ EXPORT_SYMBOL_GPL(xfrm_output); | |||
624 | static int xfrm_inner_extract_output(struct xfrm_state *x, struct sk_buff *skb) | 619 | static int xfrm_inner_extract_output(struct xfrm_state *x, struct sk_buff *skb) |
625 | { | 620 | { |
626 | const struct xfrm_state_afinfo *afinfo; | 621 | const struct xfrm_state_afinfo *afinfo; |
627 | struct xfrm_mode *inner_mode; | 622 | const struct xfrm_mode *inner_mode; |
628 | int err = -EAFNOSUPPORT; | 623 | int err = -EAFNOSUPPORT; |
629 | 624 | ||
630 | if (x->sel.family == AF_UNSPEC) | 625 | if (x->sel.family == AF_UNSPEC) |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 67122beb116c..1a5fd2296556 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -2546,10 +2546,10 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy, | |||
2546 | struct dst_entry *dst) | 2546 | struct dst_entry *dst) |
2547 | { | 2547 | { |
2548 | const struct xfrm_state_afinfo *afinfo; | 2548 | const struct xfrm_state_afinfo *afinfo; |
2549 | const struct xfrm_mode *inner_mode; | ||
2549 | struct net *net = xp_net(policy); | 2550 | struct net *net = xp_net(policy); |
2550 | unsigned long now = jiffies; | 2551 | unsigned long now = jiffies; |
2551 | struct net_device *dev; | 2552 | struct net_device *dev; |
2552 | struct xfrm_mode *inner_mode; | ||
2553 | struct xfrm_dst *xdst_prev = NULL; | 2553 | struct xfrm_dst *xdst_prev = NULL; |
2554 | struct xfrm_dst *xdst0 = NULL; | 2554 | struct xfrm_dst *xdst0 = NULL; |
2555 | int i = 0; | 2555 | int i = 0; |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 358b09f0d018..ace26f6dc790 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -330,92 +330,67 @@ static void xfrm_put_type_offload(const struct xfrm_type_offload *type) | |||
330 | module_put(type->owner); | 330 | module_put(type->owner); |
331 | } | 331 | } |
332 | 332 | ||
333 | static DEFINE_SPINLOCK(xfrm_mode_lock); | 333 | static const struct xfrm_mode xfrm4_mode_map[XFRM_MODE_MAX] = { |
334 | int xfrm_register_mode(struct xfrm_mode *mode) | 334 | [XFRM_MODE_BEET] = { |
335 | { | 335 | .encap = XFRM_MODE_BEET, |
336 | struct xfrm_state_afinfo *afinfo; | 336 | .flags = XFRM_MODE_FLAG_TUNNEL, |
337 | struct xfrm_mode **modemap; | 337 | .family = AF_INET, |
338 | int err; | 338 | }, |
339 | 339 | [XFRM_MODE_TRANSPORT] = { | |
340 | if (unlikely(mode->encap >= XFRM_MODE_MAX)) | 340 | .encap = XFRM_MODE_TRANSPORT, |
341 | return -EINVAL; | 341 | .family = AF_INET, |
342 | 342 | }, | |
343 | afinfo = xfrm_state_get_afinfo(mode->family); | 343 | [XFRM_MODE_TUNNEL] = { |
344 | if (unlikely(afinfo == NULL)) | 344 | .encap = XFRM_MODE_TUNNEL, |
345 | return -EAFNOSUPPORT; | 345 | .flags = XFRM_MODE_FLAG_TUNNEL, |
346 | 346 | .family = AF_INET, | |
347 | err = -EEXIST; | 347 | }, |
348 | modemap = afinfo->mode_map; | 348 | }; |
349 | spin_lock_bh(&xfrm_mode_lock); | 349 | |
350 | if (modemap[mode->encap]) | 350 | static const struct xfrm_mode xfrm6_mode_map[XFRM_MODE_MAX] = { |
351 | goto out; | 351 | [XFRM_MODE_BEET] = { |
352 | 352 | .encap = XFRM_MODE_BEET, | |
353 | err = -ENOENT; | 353 | .flags = XFRM_MODE_FLAG_TUNNEL, |
354 | if (!try_module_get(afinfo->owner)) | 354 | .family = AF_INET6, |
355 | goto out; | 355 | }, |
356 | 356 | [XFRM_MODE_ROUTEOPTIMIZATION] = { | |
357 | modemap[mode->encap] = mode; | 357 | .encap = XFRM_MODE_ROUTEOPTIMIZATION, |
358 | err = 0; | 358 | .family = AF_INET6, |
359 | 359 | }, | |
360 | out: | 360 | [XFRM_MODE_TRANSPORT] = { |
361 | spin_unlock_bh(&xfrm_mode_lock); | 361 | .encap = XFRM_MODE_TRANSPORT, |
362 | rcu_read_unlock(); | 362 | .family = AF_INET6, |
363 | return err; | 363 | }, |
364 | } | 364 | [XFRM_MODE_TUNNEL] = { |
365 | EXPORT_SYMBOL(xfrm_register_mode); | 365 | .encap = XFRM_MODE_TUNNEL, |
366 | 366 | .flags = XFRM_MODE_FLAG_TUNNEL, | |
367 | void xfrm_unregister_mode(struct xfrm_mode *mode) | 367 | .family = AF_INET6, |
368 | { | 368 | }, |
369 | struct xfrm_state_afinfo *afinfo; | 369 | }; |
370 | struct xfrm_mode **modemap; | 370 | |
371 | 371 | static const struct xfrm_mode *xfrm_get_mode(unsigned int encap, int family) | |
372 | afinfo = xfrm_state_get_afinfo(mode->family); | 372 | { |
373 | if (WARN_ON_ONCE(!afinfo)) | 373 | const struct xfrm_mode *mode; |
374 | return; | ||
375 | |||
376 | modemap = afinfo->mode_map; | ||
377 | spin_lock_bh(&xfrm_mode_lock); | ||
378 | if (likely(modemap[mode->encap] == mode)) { | ||
379 | modemap[mode->encap] = NULL; | ||
380 | module_put(afinfo->owner); | ||
381 | } | ||
382 | |||
383 | spin_unlock_bh(&xfrm_mode_lock); | ||
384 | rcu_read_unlock(); | ||
385 | } | ||
386 | EXPORT_SYMBOL(xfrm_unregister_mode); | ||
387 | |||
388 | static struct xfrm_mode *xfrm_get_mode(unsigned int encap, int family) | ||
389 | { | ||
390 | struct xfrm_state_afinfo *afinfo; | ||
391 | struct xfrm_mode *mode; | ||
392 | int modload_attempted = 0; | ||
393 | 374 | ||
394 | if (unlikely(encap >= XFRM_MODE_MAX)) | 375 | if (unlikely(encap >= XFRM_MODE_MAX)) |
395 | return NULL; | 376 | return NULL; |
396 | 377 | ||
397 | retry: | 378 | switch (family) { |
398 | afinfo = xfrm_state_get_afinfo(family); | 379 | case AF_INET: |
399 | if (unlikely(afinfo == NULL)) | 380 | mode = &xfrm4_mode_map[encap]; |
400 | return NULL; | 381 | if (mode->family == family) |
401 | 382 | return mode; | |
402 | mode = READ_ONCE(afinfo->mode_map[encap]); | 383 | break; |
403 | if (unlikely(mode && !try_module_get(mode->owner))) | 384 | case AF_INET6: |
404 | mode = NULL; | 385 | mode = &xfrm6_mode_map[encap]; |
405 | 386 | if (mode->family == family) | |
406 | rcu_read_unlock(); | 387 | return mode; |
407 | if (!mode && !modload_attempted) { | 388 | break; |
408 | request_module("xfrm-mode-%d-%d", family, encap); | 389 | default: |
409 | modload_attempted = 1; | 390 | break; |
410 | goto retry; | ||
411 | } | 391 | } |
412 | 392 | ||
413 | return mode; | 393 | return NULL; |
414 | } | ||
415 | |||
416 | static void xfrm_put_mode(struct xfrm_mode *mode) | ||
417 | { | ||
418 | module_put(mode->owner); | ||
419 | } | 394 | } |
420 | 395 | ||
421 | void xfrm_state_free(struct xfrm_state *x) | 396 | void xfrm_state_free(struct xfrm_state *x) |
@@ -436,12 +411,6 @@ static void ___xfrm_state_destroy(struct xfrm_state *x) | |||
436 | kfree(x->coaddr); | 411 | kfree(x->coaddr); |
437 | kfree(x->replay_esn); | 412 | kfree(x->replay_esn); |
438 | kfree(x->preplay_esn); | 413 | kfree(x->preplay_esn); |
439 | if (x->inner_mode) | ||
440 | xfrm_put_mode(x->inner_mode); | ||
441 | if (x->inner_mode_iaf) | ||
442 | xfrm_put_mode(x->inner_mode_iaf); | ||
443 | if (x->outer_mode) | ||
444 | xfrm_put_mode(x->outer_mode); | ||
445 | if (x->type_offload) | 414 | if (x->type_offload) |
446 | xfrm_put_type_offload(x->type_offload); | 415 | xfrm_put_type_offload(x->type_offload); |
447 | if (x->type) { | 416 | if (x->type) { |
@@ -2235,8 +2204,8 @@ int xfrm_state_mtu(struct xfrm_state *x, int mtu) | |||
2235 | 2204 | ||
2236 | int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload) | 2205 | int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload) |
2237 | { | 2206 | { |
2238 | struct xfrm_state_afinfo *afinfo; | 2207 | const struct xfrm_mode *inner_mode; |
2239 | struct xfrm_mode *inner_mode; | 2208 | const struct xfrm_state_afinfo *afinfo; |
2240 | int family = x->props.family; | 2209 | int family = x->props.family; |
2241 | int err; | 2210 | int err; |
2242 | 2211 | ||
@@ -2262,24 +2231,21 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload) | |||
2262 | goto error; | 2231 | goto error; |
2263 | 2232 | ||
2264 | if (!(inner_mode->flags & XFRM_MODE_FLAG_TUNNEL) && | 2233 | if (!(inner_mode->flags & XFRM_MODE_FLAG_TUNNEL) && |
2265 | family != x->sel.family) { | 2234 | family != x->sel.family) |
2266 | xfrm_put_mode(inner_mode); | ||
2267 | goto error; | 2235 | goto error; |
2268 | } | ||
2269 | 2236 | ||
2270 | x->inner_mode = inner_mode; | 2237 | x->inner_mode = inner_mode; |
2271 | } else { | 2238 | } else { |
2272 | struct xfrm_mode *inner_mode_iaf; | 2239 | const struct xfrm_mode *inner_mode_iaf; |
2273 | int iafamily = AF_INET; | 2240 | int iafamily = AF_INET; |
2274 | 2241 | ||
2275 | inner_mode = xfrm_get_mode(x->props.mode, x->props.family); | 2242 | inner_mode = xfrm_get_mode(x->props.mode, x->props.family); |
2276 | if (inner_mode == NULL) | 2243 | if (inner_mode == NULL) |
2277 | goto error; | 2244 | goto error; |
2278 | 2245 | ||
2279 | if (!(inner_mode->flags & XFRM_MODE_FLAG_TUNNEL)) { | 2246 | if (!(inner_mode->flags & XFRM_MODE_FLAG_TUNNEL)) |
2280 | xfrm_put_mode(inner_mode); | ||
2281 | goto error; | 2247 | goto error; |
2282 | } | 2248 | |
2283 | x->inner_mode = inner_mode; | 2249 | x->inner_mode = inner_mode; |
2284 | 2250 | ||
2285 | if (x->props.family == AF_INET) | 2251 | if (x->props.family == AF_INET) |
@@ -2289,8 +2255,6 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload) | |||
2289 | if (inner_mode_iaf) { | 2255 | if (inner_mode_iaf) { |
2290 | if (inner_mode_iaf->flags & XFRM_MODE_FLAG_TUNNEL) | 2256 | if (inner_mode_iaf->flags & XFRM_MODE_FLAG_TUNNEL) |
2291 | x->inner_mode_iaf = inner_mode_iaf; | 2257 | x->inner_mode_iaf = inner_mode_iaf; |
2292 | else | ||
2293 | xfrm_put_mode(inner_mode_iaf); | ||
2294 | } | 2258 | } |
2295 | } | 2259 | } |
2296 | 2260 | ||
diff --git a/tools/testing/selftests/net/config b/tools/testing/selftests/net/config index e9c860d00416..474040448601 100644 --- a/tools/testing/selftests/net/config +++ b/tools/testing/selftests/net/config | |||
@@ -7,9 +7,7 @@ CONFIG_NET_L3_MASTER_DEV=y | |||
7 | CONFIG_IPV6=y | 7 | CONFIG_IPV6=y |
8 | CONFIG_IPV6_MULTIPLE_TABLES=y | 8 | CONFIG_IPV6_MULTIPLE_TABLES=y |
9 | CONFIG_VETH=y | 9 | CONFIG_VETH=y |
10 | CONFIG_INET_XFRM_MODE_TUNNEL=y | ||
11 | CONFIG_NET_IPVTI=y | 10 | CONFIG_NET_IPVTI=y |
12 | CONFIG_INET6_XFRM_MODE_TUNNEL=y | ||
13 | CONFIG_IPV6_VTI=y | 11 | CONFIG_IPV6_VTI=y |
14 | CONFIG_DUMMY=y | 12 | CONFIG_DUMMY=y |
15 | CONFIG_BRIDGE=y | 13 | CONFIG_BRIDGE=y |