0001
0002
0003
0004
0005
0006
0007 #define pr_fmt(fmt) "IPsec: " fmt
0008
0009 #include <linux/skbuff.h>
0010 #include <linux/module.h>
0011 #include <net/xfrm.h>
0012 #include <net/protocol.h>
0013
0014 static int ipip_output(struct xfrm_state *x, struct sk_buff *skb)
0015 {
0016 skb_push(skb, -skb_network_offset(skb));
0017 return 0;
0018 }
0019
0020 static int ipip_xfrm_rcv(struct xfrm_state *x, struct sk_buff *skb)
0021 {
0022 return ip_hdr(skb)->protocol;
0023 }
0024
0025 static int ipip_init_state(struct xfrm_state *x)
0026 {
0027 if (x->props.mode != XFRM_MODE_TUNNEL)
0028 return -EINVAL;
0029
0030 if (x->encap)
0031 return -EINVAL;
0032
0033 x->props.header_len = sizeof(struct iphdr);
0034
0035 return 0;
0036 }
0037
0038 static void ipip_destroy(struct xfrm_state *x)
0039 {
0040 }
0041
0042 static const struct xfrm_type ipip_type = {
0043 .owner = THIS_MODULE,
0044 .proto = IPPROTO_IPIP,
0045 .init_state = ipip_init_state,
0046 .destructor = ipip_destroy,
0047 .input = ipip_xfrm_rcv,
0048 .output = ipip_output
0049 };
0050
0051 static int xfrm_tunnel_rcv(struct sk_buff *skb)
0052 {
0053 return xfrm4_rcv_spi(skb, IPPROTO_IPIP, ip_hdr(skb)->saddr);
0054 }
0055
0056 static int xfrm_tunnel_err(struct sk_buff *skb, u32 info)
0057 {
0058 return -ENOENT;
0059 }
0060
0061 static struct xfrm_tunnel xfrm_tunnel_handler __read_mostly = {
0062 .handler = xfrm_tunnel_rcv,
0063 .err_handler = xfrm_tunnel_err,
0064 .priority = 4,
0065 };
0066
0067 #if IS_ENABLED(CONFIG_IPV6)
0068 static struct xfrm_tunnel xfrm64_tunnel_handler __read_mostly = {
0069 .handler = xfrm_tunnel_rcv,
0070 .err_handler = xfrm_tunnel_err,
0071 .priority = 3,
0072 };
0073 #endif
0074
0075 static int __init ipip_init(void)
0076 {
0077 if (xfrm_register_type(&ipip_type, AF_INET) < 0) {
0078 pr_info("%s: can't add xfrm type\n", __func__);
0079 return -EAGAIN;
0080 }
0081
0082 if (xfrm4_tunnel_register(&xfrm_tunnel_handler, AF_INET)) {
0083 pr_info("%s: can't add xfrm handler for AF_INET\n", __func__);
0084 xfrm_unregister_type(&ipip_type, AF_INET);
0085 return -EAGAIN;
0086 }
0087 #if IS_ENABLED(CONFIG_IPV6)
0088 if (xfrm4_tunnel_register(&xfrm64_tunnel_handler, AF_INET6)) {
0089 pr_info("%s: can't add xfrm handler for AF_INET6\n", __func__);
0090 xfrm4_tunnel_deregister(&xfrm_tunnel_handler, AF_INET);
0091 xfrm_unregister_type(&ipip_type, AF_INET);
0092 return -EAGAIN;
0093 }
0094 #endif
0095 return 0;
0096 }
0097
0098 static void __exit ipip_fini(void)
0099 {
0100 #if IS_ENABLED(CONFIG_IPV6)
0101 if (xfrm4_tunnel_deregister(&xfrm64_tunnel_handler, AF_INET6))
0102 pr_info("%s: can't remove xfrm handler for AF_INET6\n",
0103 __func__);
0104 #endif
0105 if (xfrm4_tunnel_deregister(&xfrm_tunnel_handler, AF_INET))
0106 pr_info("%s: can't remove xfrm handler for AF_INET\n",
0107 __func__);
0108 xfrm_unregister_type(&ipip_type, AF_INET);
0109 }
0110
0111 module_init(ipip_init);
0112 module_exit(ipip_fini);
0113 MODULE_LICENSE("GPL");
0114 MODULE_ALIAS_XFRM_TYPE(AF_INET, XFRM_PROTO_IPIP);