xref: /OK3568_Linux_fs/kernel/net/ipv4/xfrm4_tunnel.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /* xfrm4_tunnel.c: Generic IP tunnel transformer.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Copyright (C) 2003 David S. Miller (davem@redhat.com)
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #define pr_fmt(fmt) "IPsec: " fmt
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include <linux/skbuff.h>
10*4882a593Smuzhiyun #include <linux/module.h>
11*4882a593Smuzhiyun #include <linux/mutex.h>
12*4882a593Smuzhiyun #include <net/xfrm.h>
13*4882a593Smuzhiyun #include <net/ip.h>
14*4882a593Smuzhiyun #include <net/protocol.h>
15*4882a593Smuzhiyun 
ipip_output(struct xfrm_state * x,struct sk_buff * skb)16*4882a593Smuzhiyun static int ipip_output(struct xfrm_state *x, struct sk_buff *skb)
17*4882a593Smuzhiyun {
18*4882a593Smuzhiyun 	skb_push(skb, -skb_network_offset(skb));
19*4882a593Smuzhiyun 	return 0;
20*4882a593Smuzhiyun }
21*4882a593Smuzhiyun 
ipip_xfrm_rcv(struct xfrm_state * x,struct sk_buff * skb)22*4882a593Smuzhiyun static int ipip_xfrm_rcv(struct xfrm_state *x, struct sk_buff *skb)
23*4882a593Smuzhiyun {
24*4882a593Smuzhiyun 	return ip_hdr(skb)->protocol;
25*4882a593Smuzhiyun }
26*4882a593Smuzhiyun 
ipip_init_state(struct xfrm_state * x)27*4882a593Smuzhiyun static int ipip_init_state(struct xfrm_state *x)
28*4882a593Smuzhiyun {
29*4882a593Smuzhiyun 	if (x->props.mode != XFRM_MODE_TUNNEL)
30*4882a593Smuzhiyun 		return -EINVAL;
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun 	if (x->encap)
33*4882a593Smuzhiyun 		return -EINVAL;
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun 	x->props.header_len = sizeof(struct iphdr);
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun 	return 0;
38*4882a593Smuzhiyun }
39*4882a593Smuzhiyun 
ipip_destroy(struct xfrm_state * x)40*4882a593Smuzhiyun static void ipip_destroy(struct xfrm_state *x)
41*4882a593Smuzhiyun {
42*4882a593Smuzhiyun }
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun static const struct xfrm_type ipip_type = {
45*4882a593Smuzhiyun 	.description	= "IPIP",
46*4882a593Smuzhiyun 	.owner		= THIS_MODULE,
47*4882a593Smuzhiyun 	.proto	     	= IPPROTO_IPIP,
48*4882a593Smuzhiyun 	.init_state	= ipip_init_state,
49*4882a593Smuzhiyun 	.destructor	= ipip_destroy,
50*4882a593Smuzhiyun 	.input		= ipip_xfrm_rcv,
51*4882a593Smuzhiyun 	.output		= ipip_output
52*4882a593Smuzhiyun };
53*4882a593Smuzhiyun 
xfrm_tunnel_rcv(struct sk_buff * skb)54*4882a593Smuzhiyun static int xfrm_tunnel_rcv(struct sk_buff *skb)
55*4882a593Smuzhiyun {
56*4882a593Smuzhiyun 	return xfrm4_rcv_spi(skb, IPPROTO_IPIP, ip_hdr(skb)->saddr);
57*4882a593Smuzhiyun }
58*4882a593Smuzhiyun 
xfrm_tunnel_err(struct sk_buff * skb,u32 info)59*4882a593Smuzhiyun static int xfrm_tunnel_err(struct sk_buff *skb, u32 info)
60*4882a593Smuzhiyun {
61*4882a593Smuzhiyun 	return -ENOENT;
62*4882a593Smuzhiyun }
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun static struct xfrm_tunnel xfrm_tunnel_handler __read_mostly = {
65*4882a593Smuzhiyun 	.handler	=	xfrm_tunnel_rcv,
66*4882a593Smuzhiyun 	.err_handler	=	xfrm_tunnel_err,
67*4882a593Smuzhiyun 	.priority	=	4,
68*4882a593Smuzhiyun };
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_IPV6)
71*4882a593Smuzhiyun static struct xfrm_tunnel xfrm64_tunnel_handler __read_mostly = {
72*4882a593Smuzhiyun 	.handler	=	xfrm_tunnel_rcv,
73*4882a593Smuzhiyun 	.err_handler	=	xfrm_tunnel_err,
74*4882a593Smuzhiyun 	.priority	=	3,
75*4882a593Smuzhiyun };
76*4882a593Smuzhiyun #endif
77*4882a593Smuzhiyun 
ipip_init(void)78*4882a593Smuzhiyun static int __init ipip_init(void)
79*4882a593Smuzhiyun {
80*4882a593Smuzhiyun 	if (xfrm_register_type(&ipip_type, AF_INET) < 0) {
81*4882a593Smuzhiyun 		pr_info("%s: can't add xfrm type\n", __func__);
82*4882a593Smuzhiyun 		return -EAGAIN;
83*4882a593Smuzhiyun 	}
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun 	if (xfrm4_tunnel_register(&xfrm_tunnel_handler, AF_INET)) {
86*4882a593Smuzhiyun 		pr_info("%s: can't add xfrm handler for AF_INET\n", __func__);
87*4882a593Smuzhiyun 		xfrm_unregister_type(&ipip_type, AF_INET);
88*4882a593Smuzhiyun 		return -EAGAIN;
89*4882a593Smuzhiyun 	}
90*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_IPV6)
91*4882a593Smuzhiyun 	if (xfrm4_tunnel_register(&xfrm64_tunnel_handler, AF_INET6)) {
92*4882a593Smuzhiyun 		pr_info("%s: can't add xfrm handler for AF_INET6\n", __func__);
93*4882a593Smuzhiyun 		xfrm4_tunnel_deregister(&xfrm_tunnel_handler, AF_INET);
94*4882a593Smuzhiyun 		xfrm_unregister_type(&ipip_type, AF_INET);
95*4882a593Smuzhiyun 		return -EAGAIN;
96*4882a593Smuzhiyun 	}
97*4882a593Smuzhiyun #endif
98*4882a593Smuzhiyun 	return 0;
99*4882a593Smuzhiyun }
100*4882a593Smuzhiyun 
ipip_fini(void)101*4882a593Smuzhiyun static void __exit ipip_fini(void)
102*4882a593Smuzhiyun {
103*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_IPV6)
104*4882a593Smuzhiyun 	if (xfrm4_tunnel_deregister(&xfrm64_tunnel_handler, AF_INET6))
105*4882a593Smuzhiyun 		pr_info("%s: can't remove xfrm handler for AF_INET6\n",
106*4882a593Smuzhiyun 			__func__);
107*4882a593Smuzhiyun #endif
108*4882a593Smuzhiyun 	if (xfrm4_tunnel_deregister(&xfrm_tunnel_handler, AF_INET))
109*4882a593Smuzhiyun 		pr_info("%s: can't remove xfrm handler for AF_INET\n",
110*4882a593Smuzhiyun 			__func__);
111*4882a593Smuzhiyun 	xfrm_unregister_type(&ipip_type, AF_INET);
112*4882a593Smuzhiyun }
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun module_init(ipip_init);
115*4882a593Smuzhiyun module_exit(ipip_fini);
116*4882a593Smuzhiyun MODULE_LICENSE("GPL");
117*4882a593Smuzhiyun MODULE_ALIAS_XFRM_TYPE(AF_INET, XFRM_PROTO_IPIP);
118