2005-04-16 15:20:36 -07:00
/* xfrm4_tunnel.c: Generic IP tunnel transformer.
*
* Copyright ( C ) 2003 David S . Miller ( davem @ redhat . com )
*/
2012-03-12 07:03:32 +00:00
# define pr_fmt(fmt) "IPsec: " fmt
2005-04-16 15:20:36 -07:00
# include <linux/skbuff.h>
# include <linux/module.h>
2006-03-20 22:33:17 -08:00
# include <linux/mutex.h>
2005-04-16 15:20:36 -07: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-10-10 15:44:06 -07:00
skb_push ( skb , - skb_network_offset ( skb ) ) ;
2005-04-16 15:20:36 -07:00
return 0 ;
}
2006-04-01 00:52:46 -08:00
static int ipip_xfrm_rcv ( struct xfrm_state * x , struct sk_buff * skb )
2005-04-16 15:20:36 -07:00
{
2007-10-17 21:28:06 -07:00
return ip_hdr ( skb ) - > protocol ;
2005-04-16 15:20:36 -07:00
}
2005-06-20 13:18:08 -07:00
static int ipip_init_state ( struct xfrm_state * x )
2005-04-16 15:20:36 -07:00
{
2006-09-22 15:05:15 -07:00
if ( x - > props . mode ! = XFRM_MODE_TUNNEL )
2005-04-16 15:20:36 -07: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 )
{
}
2008-01-30 19:11:50 -08:00
static const struct xfrm_type ipip_type = {
2005-04-16 15:20:36 -07:00
. description = " IPIP " ,
. owner = THIS_MODULE ,
. proto = IPPROTO_IPIP ,
. init_state = ipip_init_state ,
. destructor = ipip_destroy ,
. input = ipip_xfrm_rcv ,
. output = ipip_output
} ;
2007-10-17 21:28:53 -07:00
static int xfrm_tunnel_rcv ( struct sk_buff * skb )
{
2008-01-30 21:48:24 -08:00
return xfrm4_rcv_spi ( skb , IPPROTO_IPIP , ip_hdr ( skb ) - > saddr ) ;
2007-10-17 21:28:53 -07:00
}
2006-03-28 01:12:13 -08:00
static int xfrm_tunnel_err ( struct sk_buff * skb , u32 info )
{
return - ENOENT ;
}
2010-08-30 07:04:14 +00:00
static struct xfrm_tunnel xfrm_tunnel_handler __read_mostly = {
2007-10-17 21:28:53 -07:00
. handler = xfrm_tunnel_rcv ,
2006-03-28 01:12:13 -08:00
. err_handler = xfrm_tunnel_err ,
2013-05-27 23:48:16 +00:00
. priority = 3 ,
2005-04-16 15:20:36 -07:00
} ;
2011-12-10 09:48:31 +00:00
# if IS_ENABLED(CONFIG_IPV6)
2010-08-30 07:04:14 +00:00
static struct xfrm_tunnel xfrm64_tunnel_handler __read_mostly = {
2007-10-17 21:28:53 -07:00
. handler = xfrm_tunnel_rcv ,
2007-02-13 12:54:47 -08:00
. err_handler = xfrm_tunnel_err ,
. priority = 2 ,
} ;
# endif
2005-04-16 15:20:36 -07:00
static int __init ipip_init ( void )
{
if ( xfrm_register_type ( & ipip_type , AF_INET ) < 0 ) {
2012-03-11 18:36:11 +00:00
pr_info ( " %s: can't add xfrm type \n " , __func__ ) ;
2005-04-16 15:20:36 -07:00
return - EAGAIN ;
}
2007-02-13 12:54:47 -08:00
if ( xfrm4_tunnel_register ( & xfrm_tunnel_handler , AF_INET ) ) {
2012-03-11 18:36:11 +00:00
pr_info ( " %s: can't add xfrm handler for AF_INET \n " , __func__ ) ;
2007-02-13 12:54:47 -08:00
xfrm_unregister_type ( & ipip_type , AF_INET ) ;
return - EAGAIN ;
}
2011-12-10 09:48:31 +00:00
# if IS_ENABLED(CONFIG_IPV6)
2007-02-13 12:54:47 -08:00
if ( xfrm4_tunnel_register ( & xfrm64_tunnel_handler , AF_INET6 ) ) {
2012-03-11 18:36:11 +00:00
pr_info ( " %s: can't add xfrm handler for AF_INET6 \n " , __func__ ) ;
2007-02-13 12:54:47 -08:00
xfrm4_tunnel_deregister ( & xfrm_tunnel_handler , AF_INET ) ;
2005-04-16 15:20:36 -07:00
xfrm_unregister_type ( & ipip_type , AF_INET ) ;
return - EAGAIN ;
}
2007-02-13 12:54:47 -08:00
# endif
2005-04-16 15:20:36 -07:00
return 0 ;
}
static void __exit ipip_fini ( void )
{
2011-12-10 09:48:31 +00:00
# if IS_ENABLED(CONFIG_IPV6)
2007-02-13 12:54:47 -08:00
if ( xfrm4_tunnel_deregister ( & xfrm64_tunnel_handler , AF_INET6 ) )
2012-03-11 18:36:11 +00:00
pr_info ( " %s: can't remove xfrm handler for AF_INET6 \n " ,
__func__ ) ;
2007-02-13 12:54:47 -08:00
# endif
if ( xfrm4_tunnel_deregister ( & xfrm_tunnel_handler , AF_INET ) )
2012-03-11 18:36:11 +00:00
pr_info ( " %s: can't remove xfrm handler for AF_INET \n " ,
__func__ ) ;
2005-04-16 15:20:36 -07:00
if ( xfrm_unregister_type ( & ipip_type , AF_INET ) < 0 )
2012-03-11 18:36:11 +00:00
pr_info ( " %s: can't remove xfrm type \n " , __func__ ) ;
2005-04-16 15:20:36 -07:00
}
module_init ( ipip_init ) ;
module_exit ( ipip_fini ) ;
MODULE_LICENSE ( " GPL " ) ;
2007-06-26 23:57:49 -07:00
MODULE_ALIAS_XFRM_TYPE ( AF_INET , XFRM_PROTO_IPIP ) ;