Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /* xfrm4_tunnel.c: Generic IP tunnel transformer.
0003  *
0004  * Copyright (C) 2003 David S. Miller (davem@redhat.com)
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);