2005-04-17 02:20:36 +04:00
/* xfrm4_tunnel.c: Generic IP tunnel transformer.
*
* Copyright ( C ) 2003 David S . Miller ( davem @ redhat . com )
*/
# include <linux/skbuff.h>
# include <linux/module.h>
2006-03-21 09:33:17 +03:00
# include <linux/mutex.h>
2005-04-17 02:20:36 +04:00
# include <net/xfrm.h>
# include <net/ip.h>
# include <net/protocol.h>
static int ipip_output ( struct xfrm_state * x , struct sk_buff * skb )
{
2007-04-21 09:47:35 +04:00
struct iphdr * iph = ip_hdr ( skb ) ;
2007-02-09 17:24:47 +03:00
2005-04-17 02:20:36 +04:00
iph - > tot_len = htons ( skb - > len ) ;
ip_send_check ( iph ) ;
return 0 ;
}
2006-04-01 12:52:46 +04:00
static int ipip_xfrm_rcv ( struct xfrm_state * x , struct sk_buff * skb )
2005-04-17 02:20:36 +04:00
{
return 0 ;
}
2005-06-21 00:18:08 +04:00
static int ipip_init_state ( struct xfrm_state * x )
2005-04-17 02:20:36 +04:00
{
2006-09-23 02:05:15 +04:00
if ( x - > props . mode ! = XFRM_MODE_TUNNEL )
2005-04-17 02:20:36 +04:00
return - EINVAL ;
if ( x - > encap )
return - EINVAL ;
x - > props . header_len = sizeof ( struct iphdr ) ;
return 0 ;
}
static void ipip_destroy ( struct xfrm_state * x )
{
}
static struct xfrm_type ipip_type = {
. description = " IPIP " ,
. owner = THIS_MODULE ,
. proto = IPPROTO_IPIP ,
. init_state = ipip_init_state ,
. destructor = ipip_destroy ,
. input = ipip_xfrm_rcv ,
. output = ipip_output
} ;
2006-03-28 13:12:13 +04:00
static int xfrm_tunnel_err ( struct sk_buff * skb , u32 info )
{
return - ENOENT ;
}
static struct xfrm_tunnel xfrm_tunnel_handler = {
. handler = xfrm4_rcv ,
. err_handler = xfrm_tunnel_err ,
. priority = 2 ,
2005-04-17 02:20:36 +04:00
} ;
2007-02-13 23:54:47 +03:00
# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
static struct xfrm_tunnel xfrm64_tunnel_handler = {
. handler = xfrm4_rcv ,
. err_handler = xfrm_tunnel_err ,
. priority = 2 ,
} ;
# endif
2005-04-17 02:20:36 +04:00
static int __init ipip_init ( void )
{
if ( xfrm_register_type ( & ipip_type , AF_INET ) < 0 ) {
printk ( KERN_INFO " ipip init: can't add xfrm type \n " ) ;
return - EAGAIN ;
}
2007-02-13 23:54:47 +03:00
if ( xfrm4_tunnel_register ( & xfrm_tunnel_handler , AF_INET ) ) {
printk ( KERN_INFO " ipip init: can't add xfrm handler for AF_INET \n " ) ;
xfrm_unregister_type ( & ipip_type , AF_INET ) ;
return - EAGAIN ;
}
# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
if ( xfrm4_tunnel_register ( & xfrm64_tunnel_handler , AF_INET6 ) ) {
printk ( KERN_INFO " ipip init: can't add xfrm handler for AF_INET6 \n " ) ;
xfrm4_tunnel_deregister ( & xfrm_tunnel_handler , AF_INET ) ;
2005-04-17 02:20:36 +04:00
xfrm_unregister_type ( & ipip_type , AF_INET ) ;
return - EAGAIN ;
}
2007-02-13 23:54:47 +03:00
# endif
2005-04-17 02:20:36 +04:00
return 0 ;
}
static void __exit ipip_fini ( void )
{
2007-02-13 23:54:47 +03:00
# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
if ( xfrm4_tunnel_deregister ( & xfrm64_tunnel_handler , AF_INET6 ) )
printk ( KERN_INFO " ipip close: can't remove xfrm handler for AF_INET6 \n " ) ;
# endif
if ( xfrm4_tunnel_deregister ( & xfrm_tunnel_handler , AF_INET ) )
printk ( KERN_INFO " ipip close: can't remove xfrm handler for AF_INET \n " ) ;
2005-04-17 02:20:36 +04:00
if ( xfrm_unregister_type ( & ipip_type , AF_INET ) < 0 )
printk ( KERN_INFO " ipip close: can't remove xfrm type \n " ) ;
}
module_init ( ipip_init ) ;
module_exit ( ipip_fini ) ;
MODULE_LICENSE ( " GPL " ) ;