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 13 static 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 23 static int ipip_xfrm_rcv(struct xfrm_state *x, struct sk_buff *skb) 24 { 25 return 0; 26 } 27 28 static 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 41 static void ipip_destroy(struct xfrm_state *x) 42 { 43 } 44 45 static 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 55 static int xfrm_tunnel_err(struct sk_buff *skb, u32 info) 56 { 57 return -ENOENT; 58 } 59 60 static 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) 67 static struct xfrm_tunnel xfrm64_tunnel_handler = { 68 .handler = xfrm4_rcv, 69 .err_handler = xfrm_tunnel_err, 70 .priority = 2, 71 }; 72 #endif 73 74 static 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 97 static 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 109 module_init(ipip_init); 110 module_exit(ipip_fini); 111 MODULE_LICENSE("GPL"); 112