2005-04-16 15:20:36 -07:00
/*
* xfrm_input . c
*
* Changes :
* YOSHIFUJI Hideaki @ USAGI
* Split up af - specific portion
*
*/
# include <linux/slab.h>
# include <linux/module.h>
# include <net/ip.h>
# include <net/xfrm.h>
2006-12-06 20:33:20 -08:00
static struct kmem_cache * secpath_cachep __read_mostly ;
2005-04-16 15:20:36 -07:00
void __secpath_destroy ( struct sec_path * sp )
{
int i ;
for ( i = 0 ; i < sp - > len ; i + + )
2006-04-01 00:54:16 -08:00
xfrm_state_put ( sp - > xvec [ i ] ) ;
2005-04-16 15:20:36 -07:00
kmem_cache_free ( secpath_cachep , sp ) ;
}
EXPORT_SYMBOL ( __secpath_destroy ) ;
struct sec_path * secpath_dup ( struct sec_path * src )
{
struct sec_path * sp ;
2006-12-06 20:33:16 -08:00
sp = kmem_cache_alloc ( secpath_cachep , GFP_ATOMIC ) ;
2005-04-16 15:20:36 -07:00
if ( ! sp )
return NULL ;
sp - > len = 0 ;
if ( src ) {
int i ;
memcpy ( sp , src , sizeof ( * sp ) ) ;
for ( i = 0 ; i < sp - > len ; i + + )
2006-04-01 00:54:16 -08:00
xfrm_state_hold ( sp - > xvec [ i ] ) ;
2005-04-16 15:20:36 -07:00
}
atomic_set ( & sp - > refcnt , 1 ) ;
return sp ;
}
EXPORT_SYMBOL ( secpath_dup ) ;
/* Fetch spi and seq from ipsec header */
2006-09-27 18:47:59 -07:00
int xfrm_parse_spi ( struct sk_buff * skb , u8 nexthdr , __be32 * spi , __be32 * seq )
2005-04-16 15:20:36 -07:00
{
int offset , offset_seq ;
switch ( nexthdr ) {
case IPPROTO_AH :
offset = offsetof ( struct ip_auth_hdr , spi ) ;
offset_seq = offsetof ( struct ip_auth_hdr , seq_no ) ;
break ;
case IPPROTO_ESP :
offset = offsetof ( struct ip_esp_hdr , spi ) ;
offset_seq = offsetof ( struct ip_esp_hdr , seq_no ) ;
break ;
case IPPROTO_COMP :
if ( ! pskb_may_pull ( skb , sizeof ( struct ip_comp_hdr ) ) )
return - EINVAL ;
2006-09-27 18:47:59 -07:00
* spi = htonl ( ntohs ( * ( __be16 * ) ( skb - > h . raw + 2 ) ) ) ;
2005-04-16 15:20:36 -07:00
* seq = 0 ;
return 0 ;
default :
return 1 ;
}
if ( ! pskb_may_pull ( skb , 16 ) )
return - EINVAL ;
2006-09-27 18:47:59 -07:00
* spi = * ( __be32 * ) ( skb - > h . raw + offset ) ;
* seq = * ( __be32 * ) ( skb - > h . raw + offset_seq ) ;
2005-04-16 15:20:36 -07:00
return 0 ;
}
EXPORT_SYMBOL ( xfrm_parse_spi ) ;
void __init xfrm_input_init ( void )
{
secpath_cachep = kmem_cache_create ( " secpath_cache " ,
sizeof ( struct sec_path ) ,
2006-08-26 19:25:52 -07:00
0 , SLAB_HWCACHE_ALIGN | SLAB_PANIC ,
2005-04-16 15:20:36 -07:00
NULL , NULL ) ;
}