2015-07-21 11:43:46 +03:00
# ifndef __NET_LWTUNNEL_H
# define __NET_LWTUNNEL_H 1
# include <linux/lwtunnel.h>
# include <linux/netdevice.h>
# include <linux/skbuff.h>
# include <linux/types.h>
# include <net/route.h>
# define LWTUNNEL_HASH_BITS 7
# define LWTUNNEL_HASH_SIZE (1 << LWTUNNEL_HASH_BITS)
/* lw tunnel state flags */
2015-08-17 23:42:24 +03:00
# define LWTUNNEL_STATE_OUTPUT_REDIRECT BIT(0)
# define LWTUNNEL_STATE_INPUT_REDIRECT BIT(1)
2016-08-25 06:10:43 +03:00
# define LWTUNNEL_STATE_XMIT_REDIRECT BIT(2)
enum {
LWTUNNEL_XMIT_DONE ,
LWTUNNEL_XMIT_CONTINUE ,
} ;
2015-07-21 11:43:46 +03:00
struct lwtunnel_state {
__u16 type ;
__u16 flags ;
2016-10-21 17:10:22 +03:00
__u16 headroom ;
2015-07-21 11:43:46 +03:00
atomic_t refcnt ;
2015-10-08 00:48:47 +03:00
int ( * orig_output ) ( struct net * net , struct sock * sk , struct sk_buff * skb ) ;
2015-08-17 23:42:24 +03:00
int ( * orig_input ) ( struct sk_buff * ) ;
2016-10-14 21:25:36 +03:00
struct rcu_head rcu ;
2015-07-21 11:43:46 +03:00
__u8 data [ 0 ] ;
} ;
struct lwtunnel_encap_ops {
2017-01-30 23:07:37 +03:00
int ( * build_state ) ( struct nlattr * encap ,
2015-08-24 19:45:41 +03:00
unsigned int family , const void * cfg ,
2017-05-28 01:19:28 +03:00
struct lwtunnel_state * * ts ,
struct netlink_ext_ack * extack ) ;
2016-10-14 21:25:36 +03:00
void ( * destroy_state ) ( struct lwtunnel_state * lws ) ;
2015-10-08 00:48:47 +03:00
int ( * output ) ( struct net * net , struct sock * sk , struct sk_buff * skb ) ;
2015-08-17 23:42:24 +03:00
int ( * input ) ( struct sk_buff * skb ) ;
2015-07-21 11:43:46 +03:00
int ( * fill_encap ) ( struct sk_buff * skb ,
struct lwtunnel_state * lwtstate ) ;
int ( * get_encap_size ) ( struct lwtunnel_state * lwtstate ) ;
int ( * cmp_encap ) ( struct lwtunnel_state * a , struct lwtunnel_state * b ) ;
2016-08-25 06:10:43 +03:00
int ( * xmit ) ( struct sk_buff * skb ) ;
2017-01-24 19:26:47 +03:00
struct module * owner ;
2015-07-21 11:43:46 +03:00
} ;
# ifdef CONFIG_LWTUNNEL
2016-10-14 21:25:36 +03:00
void lwtstate_free ( struct lwtunnel_state * lws ) ;
2015-08-18 19:41:13 +03:00
2015-07-24 13:28:36 +03:00
static inline struct lwtunnel_state *
lwtstate_get ( struct lwtunnel_state * lws )
2015-07-21 11:43:46 +03:00
{
2015-07-24 13:28:36 +03:00
if ( lws )
atomic_inc ( & lws - > refcnt ) ;
return lws ;
2015-07-21 11:43:46 +03:00
}
2015-07-24 13:28:36 +03:00
static inline void lwtstate_put ( struct lwtunnel_state * lws )
2015-07-21 11:43:46 +03:00
{
if ( ! lws )
return ;
if ( atomic_dec_and_test ( & lws - > refcnt ) )
2015-08-18 19:41:13 +03:00
lwtstate_free ( lws ) ;
2015-07-21 11:43:46 +03:00
}
static inline bool lwtunnel_output_redirect ( struct lwtunnel_state * lwtstate )
{
if ( lwtstate & & ( lwtstate - > flags & LWTUNNEL_STATE_OUTPUT_REDIRECT ) )
return true ;
return false ;
}
2015-08-17 23:42:24 +03:00
static inline bool lwtunnel_input_redirect ( struct lwtunnel_state * lwtstate )
{
if ( lwtstate & & ( lwtstate - > flags & LWTUNNEL_STATE_INPUT_REDIRECT ) )
return true ;
return false ;
}
2016-08-25 06:10:43 +03:00
static inline bool lwtunnel_xmit_redirect ( struct lwtunnel_state * lwtstate )
{
if ( lwtstate & & ( lwtstate - > flags & LWTUNNEL_STATE_XMIT_REDIRECT ) )
return true ;
return false ;
}
static inline unsigned int lwtunnel_headroom ( struct lwtunnel_state * lwtstate ,
unsigned int mtu )
{
2016-11-16 12:05:46 +03:00
if ( ( lwtunnel_xmit_redirect ( lwtstate ) | |
lwtunnel_output_redirect ( lwtstate ) ) & & lwtstate - > headroom < mtu )
2016-08-25 06:10:43 +03:00
return lwtstate - > headroom ;
return 0 ;
}
2015-07-21 11:43:46 +03:00
int lwtunnel_encap_add_ops ( const struct lwtunnel_encap_ops * op ,
unsigned int num ) ;
int lwtunnel_encap_del_ops ( const struct lwtunnel_encap_ops * op ,
unsigned int num ) ;
2017-05-28 01:19:27 +03:00
int lwtunnel_valid_encap_type ( u16 encap_type ,
struct netlink_ext_ack * extack ) ;
int lwtunnel_valid_encap_type_attr ( struct nlattr * attr , int len ,
struct netlink_ext_ack * extack ) ;
2017-01-30 23:07:37 +03:00
int lwtunnel_build_state ( u16 encap_type ,
2015-07-21 11:43:46 +03:00
struct nlattr * encap ,
2015-08-24 19:45:41 +03:00
unsigned int family , const void * cfg ,
2017-05-28 01:19:28 +03:00
struct lwtunnel_state * * lws ,
struct netlink_ext_ack * extack ) ;
2015-07-21 11:43:46 +03:00
int lwtunnel_fill_encap ( struct sk_buff * skb ,
struct lwtunnel_state * lwtstate ) ;
int lwtunnel_get_encap_size ( struct lwtunnel_state * lwtstate ) ;
struct lwtunnel_state * lwtunnel_state_alloc ( int hdr_len ) ;
int lwtunnel_cmp_encap ( struct lwtunnel_state * a , struct lwtunnel_state * b ) ;
2015-10-08 00:48:47 +03:00
int lwtunnel_output ( struct net * net , struct sock * sk , struct sk_buff * skb ) ;
2015-08-17 23:42:24 +03:00
int lwtunnel_input ( struct sk_buff * skb ) ;
2016-08-25 06:10:43 +03:00
int lwtunnel_xmit ( struct sk_buff * skb ) ;
2015-07-21 11:43:46 +03:00
# else
2015-08-19 10:46:17 +03:00
static inline void lwtstate_free ( struct lwtunnel_state * lws )
{
}
2015-07-24 13:28:36 +03:00
static inline struct lwtunnel_state *
lwtstate_get ( struct lwtunnel_state * lws )
2015-07-21 11:43:46 +03:00
{
2015-07-24 13:28:36 +03:00
return lws ;
2015-07-21 11:43:46 +03:00
}
2015-07-24 13:28:36 +03:00
static inline void lwtstate_put ( struct lwtunnel_state * lws )
2015-07-21 11:43:46 +03:00
{
}
static inline bool lwtunnel_output_redirect ( struct lwtunnel_state * lwtstate )
{
return false ;
}
2015-08-17 23:42:24 +03:00
static inline bool lwtunnel_input_redirect ( struct lwtunnel_state * lwtstate )
{
return false ;
}
2016-08-25 06:10:43 +03:00
static inline bool lwtunnel_xmit_redirect ( struct lwtunnel_state * lwtstate )
{
return false ;
}
static inline unsigned int lwtunnel_headroom ( struct lwtunnel_state * lwtstate ,
unsigned int mtu )
{
return 0 ;
}
2015-07-21 11:43:46 +03:00
static inline int lwtunnel_encap_add_ops ( const struct lwtunnel_encap_ops * op ,
unsigned int num )
{
return - EOPNOTSUPP ;
}
static inline int lwtunnel_encap_del_ops ( const struct lwtunnel_encap_ops * op ,
unsigned int num )
{
return - EOPNOTSUPP ;
}
2017-05-28 01:19:27 +03:00
static inline int lwtunnel_valid_encap_type ( u16 encap_type ,
struct netlink_ext_ack * extack )
2017-01-18 01:57:36 +03:00
{
2017-05-28 01:19:27 +03:00
NL_SET_ERR_MSG ( extack , " CONFIG_LWTUNNEL is not enabled in this kernel " ) ;
2017-01-18 01:57:36 +03:00
return - EOPNOTSUPP ;
}
2017-05-28 01:19:27 +03:00
static inline int lwtunnel_valid_encap_type_attr ( struct nlattr * attr , int len ,
struct netlink_ext_ack * extack )
2017-01-18 01:57:36 +03:00
{
2017-02-08 20:29:00 +03:00
/* return 0 since we are not walking attr looking for
* RTA_ENCAP_TYPE attribute on nexthops .
*/
return 0 ;
2017-01-18 01:57:36 +03:00
}
2017-01-30 23:07:37 +03:00
static inline int lwtunnel_build_state ( u16 encap_type ,
2015-07-21 11:43:46 +03:00
struct nlattr * encap ,
2015-08-24 19:45:41 +03:00
unsigned int family , const void * cfg ,
2017-05-28 01:19:28 +03:00
struct lwtunnel_state * * lws ,
struct netlink_ext_ack * extack )
2015-07-21 11:43:46 +03:00
{
return - EOPNOTSUPP ;
}
static inline int lwtunnel_fill_encap ( struct sk_buff * skb ,
struct lwtunnel_state * lwtstate )
{
return 0 ;
}
static inline int lwtunnel_get_encap_size ( struct lwtunnel_state * lwtstate )
{
return 0 ;
}
static inline struct lwtunnel_state * lwtunnel_state_alloc ( int hdr_len )
{
return NULL ;
}
static inline int lwtunnel_cmp_encap ( struct lwtunnel_state * a ,
struct lwtunnel_state * b )
{
return 0 ;
}
2015-10-08 00:48:47 +03:00
static inline int lwtunnel_output ( struct net * net , struct sock * sk , struct sk_buff * skb )
2015-07-21 11:43:49 +03:00
{
return - EOPNOTSUPP ;
}
2015-08-17 23:42:24 +03:00
static inline int lwtunnel_input ( struct sk_buff * skb )
{
return - EOPNOTSUPP ;
}
2016-08-25 06:10:43 +03:00
static inline int lwtunnel_xmit ( struct sk_buff * skb )
{
return - EOPNOTSUPP ;
}
2016-02-19 12:43:16 +03:00
# endif /* CONFIG_LWTUNNEL */
# define MODULE_ALIAS_RTNL_LWT(encap_type) MODULE_ALIAS("rtnl-lwt-" __stringify(encap_type))
2015-07-21 11:43:46 +03:00
# endif /* __NET_LWTUNNEL_H */