2015-05-12 15:56:07 +03:00
# ifndef _NET_FLOW_DISSECTOR_H
# define _NET_FLOW_DISSECTOR_H
2011-11-28 09:22:18 +04:00
2015-05-12 15:56:17 +03:00
# include <linux/types.h>
# include <linux/skbuff.h>
2015-05-12 15:56:18 +03:00
# include <linux/in6.h>
2015-05-12 15:56:19 +03:00
# include <uapi/linux/if_ether.h>
2015-05-12 15:56:17 +03:00
2015-06-04 19:16:39 +03:00
/**
* struct flow_dissector_key_control :
* @ thoff : Transport header offset
*/
struct flow_dissector_key_control {
u16 thoff ;
2015-06-04 19:16:40 +03:00
u16 addr_type ;
2015-06-04 19:16:39 +03:00
} ;
2015-05-12 15:56:15 +03:00
/**
* struct flow_dissector_key_basic :
* @ thoff : Transport header offset
* @ n_proto : Network header protocol ( eg . IPv4 / IPv6 )
* @ ip_proto : Transport header protocol ( eg . TCP / UDP )
*/
struct flow_dissector_key_basic {
__be16 n_proto ;
u8 ip_proto ;
2015-06-04 19:16:39 +03:00
u8 padding ;
2015-05-12 15:56:15 +03:00
} ;
2015-06-04 19:16:43 +03:00
struct flow_dissector_key_tags {
2015-06-04 19:16:44 +03:00
u32 vlan_id : 12 ,
flow_label : 20 ;
2015-06-04 19:16:43 +03:00
} ;
2015-06-04 19:16:45 +03:00
struct flow_dissector_key_keyid {
__be32 keyid ;
} ;
2015-05-12 15:56:15 +03:00
/**
2015-06-04 19:16:40 +03:00
* struct flow_dissector_key_ipv4_addrs :
* @ src : source ip address
* @ dst : destination ip address
2015-05-12 15:56:15 +03:00
*/
2015-06-04 19:16:40 +03:00
struct flow_dissector_key_ipv4_addrs {
2015-05-12 15:56:15 +03:00
/* (src,dst) must be grouped, in the same way than in IP header */
__be32 src ;
__be32 dst ;
} ;
2015-06-04 19:16:40 +03:00
/**
* struct flow_dissector_key_ipv6_addrs :
* @ src : source ip address
* @ dst : destination ip address
*/
struct flow_dissector_key_ipv6_addrs {
/* (src,dst) must be grouped, in the same way than in IP header */
struct in6_addr src ;
struct in6_addr dst ;
} ;
2015-06-04 19:16:41 +03:00
/**
* struct flow_dissector_key_tipc_addrs :
* @ srcnode : source node address
*/
struct flow_dissector_key_tipc_addrs {
__be32 srcnode ;
} ;
2015-06-04 19:16:40 +03:00
/**
* struct flow_dissector_key_addrs :
* @ v4addrs : IPv4 addresses
* @ v6addrs : IPv6 addresses
*/
struct flow_dissector_key_addrs {
union {
struct flow_dissector_key_ipv4_addrs v4addrs ;
struct flow_dissector_key_ipv6_addrs v6addrs ;
2015-06-04 19:16:41 +03:00
struct flow_dissector_key_tipc_addrs tipcaddrs ;
2015-06-04 19:16:40 +03:00
} ;
} ;
2015-05-12 15:56:15 +03:00
/**
* flow_dissector_key_tp_ports :
* @ ports : port numbers of Transport header
2015-05-12 15:56:20 +03:00
* src : source port number
* dst : destination port number
2015-05-12 15:56:15 +03:00
*/
struct flow_dissector_key_ports {
union {
__be32 ports ;
2015-05-12 15:56:20 +03:00
struct {
__be16 src ;
__be16 dst ;
} ;
2015-05-12 15:56:15 +03:00
} ;
} ;
2015-05-12 15:56:18 +03:00
2015-05-12 15:56:19 +03:00
/**
* struct flow_dissector_key_eth_addrs :
* @ src : source Ethernet address
* @ dst : destination Ethernet address
*/
struct flow_dissector_key_eth_addrs {
/* (dst,src) must be grouped, in the same way than in ETH header */
unsigned char dst [ ETH_ALEN ] ;
unsigned char src [ ETH_ALEN ] ;
} ;
2015-05-12 15:56:15 +03:00
enum flow_dissector_key_id {
2015-06-04 19:16:39 +03:00
FLOW_DISSECTOR_KEY_CONTROL , /* struct flow_dissector_key_control */
2015-05-12 15:56:15 +03:00
FLOW_DISSECTOR_KEY_BASIC , /* struct flow_dissector_key_basic */
2015-06-04 19:16:40 +03:00
FLOW_DISSECTOR_KEY_IPV4_ADDRS , /* struct flow_dissector_key_ipv4_addrs */
FLOW_DISSECTOR_KEY_IPV6_ADDRS , /* struct flow_dissector_key_ipv6_addrs */
2015-05-12 15:56:15 +03:00
FLOW_DISSECTOR_KEY_PORTS , /* struct flow_dissector_key_ports */
2015-05-12 15:56:19 +03:00
FLOW_DISSECTOR_KEY_ETH_ADDRS , /* struct flow_dissector_key_eth_addrs */
2015-06-04 19:16:41 +03:00
FLOW_DISSECTOR_KEY_TIPC_ADDRS , /* struct flow_dissector_key_tipc_addrs */
2015-06-04 19:16:43 +03:00
FLOW_DISSECTOR_KEY_VLANID , /* struct flow_dissector_key_flow_tags */
2015-06-04 19:16:44 +03:00
FLOW_DISSECTOR_KEY_FLOW_LABEL , /* struct flow_dissector_key_flow_tags */
2015-06-04 19:16:45 +03:00
FLOW_DISSECTOR_KEY_GRE_KEYID , /* struct flow_dissector_key_keyid */
2015-06-04 19:16:46 +03:00
FLOW_DISSECTOR_KEY_MPLS_ENTROPY , /* struct flow_dissector_key_keyid */
2015-05-12 15:56:15 +03:00
FLOW_DISSECTOR_KEY_MAX ,
} ;
struct flow_dissector_key {
enum flow_dissector_key_id key_id ;
size_t offset ; /* offset of struct flow_dissector_key_*
in target the struct */
} ;
struct flow_dissector {
unsigned int used_keys ; /* each bit repesents presence of one key id */
unsigned short int offset [ FLOW_DISSECTOR_KEY_MAX ] ;
} ;
void skb_flow_dissector_init ( struct flow_dissector * flow_dissector ,
const struct flow_dissector_key * key ,
unsigned int key_count ) ;
2015-05-12 15:56:16 +03:00
bool __skb_flow_dissect ( const struct sk_buff * skb ,
struct flow_dissector * flow_dissector ,
void * target_container ,
2014-08-26 04:03:47 +04:00
void * data , __be16 proto , int nhoff , int hlen ) ;
2015-05-12 15:56:07 +03:00
static inline bool skb_flow_dissect ( const struct sk_buff * skb ,
2015-05-12 15:56:16 +03:00
struct flow_dissector * flow_dissector ,
void * target_container )
{
return __skb_flow_dissect ( skb , flow_dissector , target_container ,
NULL , 0 , 0 , 0 ) ;
}
struct flow_keys {
2015-06-04 19:16:39 +03:00
struct flow_dissector_key_control control ;
# define FLOW_KEYS_HASH_START_FIELD basic
2015-05-12 15:56:16 +03:00
struct flow_dissector_key_basic basic ;
2015-06-04 19:16:43 +03:00
struct flow_dissector_key_tags tags ;
2015-06-04 19:16:45 +03:00
struct flow_dissector_key_keyid keyid ;
2015-06-04 19:16:39 +03:00
struct flow_dissector_key_ports ports ;
struct flow_dissector_key_addrs addrs ;
2015-05-12 15:56:16 +03:00
} ;
2015-06-04 19:16:39 +03:00
# define FLOW_KEYS_HASH_OFFSET \
offsetof ( struct flow_keys , FLOW_KEYS_HASH_START_FIELD )
2015-06-04 19:16:40 +03:00
__be32 flow_get_u32_src ( const struct flow_keys * flow ) ;
__be32 flow_get_u32_dst ( const struct flow_keys * flow ) ;
2015-05-12 15:56:16 +03:00
extern struct flow_dissector flow_keys_dissector ;
extern struct flow_dissector flow_keys_buf_dissector ;
static inline bool skb_flow_dissect_flow_keys ( const struct sk_buff * skb ,
struct flow_keys * flow )
{
memset ( flow , 0 , sizeof ( * flow ) ) ;
return __skb_flow_dissect ( skb , & flow_keys_dissector , flow ,
NULL , 0 , 0 , 0 ) ;
}
static inline bool skb_flow_dissect_flow_keys_buf ( struct flow_keys * flow ,
void * data , __be16 proto ,
int nhoff , int hlen )
2014-08-23 23:13:41 +04:00
{
2015-05-12 15:56:16 +03:00
memset ( flow , 0 , sizeof ( * flow ) ) ;
return __skb_flow_dissect ( NULL , & flow_keys_buf_dissector , flow ,
data , proto , nhoff , hlen ) ;
2014-08-23 23:13:41 +04:00
}
2015-05-12 15:56:07 +03:00
2014-08-23 23:13:41 +04:00
__be32 __skb_flow_get_ports ( const struct sk_buff * skb , int thoff , u8 ip_proto ,
void * data , int hlen_proto ) ;
2015-05-12 15:56:07 +03:00
static inline __be32 skb_flow_get_ports ( const struct sk_buff * skb ,
int thoff , u8 ip_proto )
2014-08-23 23:13:41 +04:00
{
return __skb_flow_get_ports ( skb , thoff , ip_proto , NULL , 0 ) ;
}
2015-05-12 15:56:07 +03:00
2014-07-02 08:32:05 +04:00
u32 flow_hash_from_keys ( struct flow_keys * keys ) ;
2015-05-12 15:56:11 +03:00
void __skb_get_hash ( struct sk_buff * skb ) ;
2015-05-12 15:56:09 +03:00
u32 skb_get_poff ( const struct sk_buff * skb ) ;
u32 __skb_get_poff ( const struct sk_buff * skb , void * data ,
const struct flow_keys * keys , int hlen ) ;
2015-05-12 15:56:07 +03:00
2015-05-01 21:30:17 +03:00
/* struct flow_keys_digest:
*
* This structure is used to hold a digest of the full flow keys . This is a
* larger " hash " of a flow to allow definitively matching specific flows where
* the 32 bit skb - > hash is not large enough . The size is limited to 16 bytes so
* that it can by used in CB of skb ( see sch_choke for an example ) .
*/
# define FLOW_KEYS_DIGEST_LEN 16
struct flow_keys_digest {
u8 data [ FLOW_KEYS_DIGEST_LEN ] ;
} ;
void make_flow_keys_digest ( struct flow_keys_digest * digest ,
const struct flow_keys * flow ) ;
2011-11-28 09:22:18 +04:00
# endif