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