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