2005-04-17 02:20:36 +04:00
# ifndef __BEN_VLAN_802_1Q_INC__
# define __BEN_VLAN_802_1Q_INC__
# include <linux/if_vlan.h>
2010-06-24 04:55:06 +04:00
# include <linux/u64_stats_sync.h>
2011-12-08 08:11:18 +04:00
# include <linux/list.h>
2005-04-17 02:20:36 +04:00
2008-07-08 14:23:57 +04:00
/**
* struct vlan_priority_tci_mapping - vlan egress priority mappings
* @ priority : skb priority
* @ vlan_qos : vlan priority : ( skb - > priority < < 13 ) & 0xE000
* @ next : pointer to next struct
*/
struct vlan_priority_tci_mapping {
u32 priority ;
2008-07-08 14:24:44 +04:00
u16 vlan_qos ;
2008-07-08 14:23:57 +04:00
struct vlan_priority_tci_mapping * next ;
} ;
2009-11-17 07:53:09 +03:00
/**
2010-11-11 02:42:00 +03:00
* struct vlan_pcpu_stats - VLAN percpu rx / tx stats
2009-11-17 07:53:09 +03:00
* @ rx_packets : number of received packets
* @ rx_bytes : number of received bytes
2010-06-24 04:55:06 +04:00
* @ rx_multicast : number of received multicast packets
2010-11-11 02:42:00 +03:00
* @ tx_packets : number of transmitted packets
* @ tx_bytes : number of transmitted bytes
2010-06-24 04:55:06 +04:00
* @ syncp : synchronization point for 64 bit counters
2010-11-11 02:42:00 +03:00
* @ rx_errors : number of rx errors
* @ tx_dropped : number of tx drops
2009-11-17 07:53:09 +03:00
*/
2010-11-11 02:42:00 +03:00
struct vlan_pcpu_stats {
2010-06-24 04:55:06 +04:00
u64 rx_packets ;
u64 rx_bytes ;
u64 rx_multicast ;
2010-11-11 02:42:00 +03:00
u64 tx_packets ;
u64 tx_bytes ;
2010-06-24 04:55:06 +04:00
struct u64_stats_sync syncp ;
2010-11-11 02:42:00 +03:00
u32 rx_errors ;
u32 tx_dropped ;
2009-11-17 07:53:09 +03:00
} ;
2011-12-08 10:20:49 +04:00
struct netpoll ;
2008-07-08 14:23:57 +04:00
/**
2011-12-08 08:11:15 +04:00
* struct vlan_dev_priv - VLAN private device data
2008-07-08 14:23:57 +04:00
* @ nr_ingress_mappings : number of ingress priority mappings
* @ ingress_priority_map : ingress priority mappings
* @ nr_egress_mappings : number of egress priority mappings
* @ egress_priority_map : hash of egress priority mappings
* @ vlan_id : VLAN identifier
* @ flags : device flags
* @ real_dev : underlying netdevice
* @ real_dev_addr : address of underlying netdevice
* @ dent : proc dir entry
2010-11-11 02:42:00 +03:00
* @ vlan_pcpu_stats : ptr to percpu rx stats
2008-07-08 14:23:57 +04:00
*/
2011-12-08 08:11:15 +04:00
struct vlan_dev_priv {
2008-07-08 14:23:57 +04:00
unsigned int nr_ingress_mappings ;
u32 ingress_priority_map [ 8 ] ;
unsigned int nr_egress_mappings ;
struct vlan_priority_tci_mapping * egress_priority_map [ 16 ] ;
2008-07-08 14:24:44 +04:00
u16 vlan_id ;
u16 flags ;
2008-07-08 14:23:57 +04:00
struct net_device * real_dev ;
unsigned char real_dev_addr [ ETH_ALEN ] ;
struct proc_dir_entry * dent ;
2010-11-11 02:42:00 +03:00
struct vlan_pcpu_stats __percpu * vlan_pcpu_stats ;
2011-12-08 10:20:49 +04:00
# ifdef CONFIG_NET_POLL_CONTROLLER
struct netpoll * netpoll ;
# endif
2008-07-08 14:23:57 +04:00
} ;
2011-12-08 08:11:15 +04:00
static inline struct vlan_dev_priv * vlan_dev_priv ( const struct net_device * dev )
2008-07-08 14:23:57 +04:00
{
return netdev_priv ( dev ) ;
}
2011-12-08 08:11:18 +04:00
/* if this changes, algorithm will have to be reworked because this
* depends on completely exhausting the VLAN identifier space . Thus
* it gives constant time look - up , but in many cases it wastes memory .
*/
# define VLAN_GROUP_ARRAY_SPLIT_PARTS 8
# define VLAN_GROUP_ARRAY_PART_LEN (VLAN_N_VID / VLAN_GROUP_ARRAY_SPLIT_PARTS)
struct vlan_group {
unsigned int nr_vlan_devs ;
struct hlist_node hlist ; /* linked list */
struct net_device * * vlan_devices_arrays [ VLAN_GROUP_ARRAY_SPLIT_PARTS ] ;
} ;
struct vlan_info {
struct net_device * real_dev ; /* The ethernet(like) device
* the vlan is attached to .
*/
struct vlan_group grp ;
struct list_head vid_list ;
unsigned int nr_vids ;
struct rcu_head rcu ;
} ;
2011-07-20 08:54:49 +04:00
static inline struct net_device * vlan_group_get_device ( struct vlan_group * vg ,
u16 vlan_id )
{
struct net_device * * array ;
array = vg - > vlan_devices_arrays [ vlan_id / VLAN_GROUP_ARRAY_PART_LEN ] ;
return array ? array [ vlan_id % VLAN_GROUP_ARRAY_PART_LEN ] : NULL ;
}
static inline void vlan_group_set_device ( struct vlan_group * vg ,
u16 vlan_id ,
struct net_device * dev )
{
struct net_device * * array ;
if ( ! vg )
return ;
array = vg - > vlan_devices_arrays [ vlan_id / VLAN_GROUP_ARRAY_PART_LEN ] ;
array [ vlan_id % VLAN_GROUP_ARRAY_PART_LEN ] = dev ;
}
2011-07-17 12:53:12 +04:00
/* Must be invoked with rcu_read_lock or with RTNL. */
static inline struct net_device * vlan_find_dev ( struct net_device * real_dev ,
u16 vlan_id )
{
2011-12-08 08:11:18 +04:00
struct vlan_info * vlan_info = rcu_dereference_rtnl ( real_dev - > vlan_info ) ;
2011-07-17 12:53:12 +04:00
2011-12-08 08:11:18 +04:00
if ( vlan_info )
return vlan_group_get_device ( & vlan_info - > grp , vlan_id ) ;
2011-07-17 12:53:12 +04:00
return NULL ;
}
2005-04-17 02:20:36 +04:00
/* found in vlan_dev.c */
2007-06-13 23:05:22 +04:00
void vlan_dev_set_ingress_priority ( const struct net_device * dev ,
2008-07-08 14:24:44 +04:00
u32 skb_prio , u16 vlan_prio ) ;
2007-06-13 23:05:22 +04:00
int vlan_dev_set_egress_priority ( const struct net_device * dev ,
2008-07-08 14:24:44 +04:00
u32 skb_prio , u16 vlan_prio ) ;
2008-07-06 08:26:27 +04:00
int vlan_dev_change_flags ( const struct net_device * dev , u32 flag , u32 mask ) ;
2007-06-13 23:05:22 +04:00
void vlan_dev_get_realdev_name ( const struct net_device * dev , char * result ) ;
2005-04-17 02:20:36 +04:00
2008-07-08 14:24:44 +04:00
int vlan_check_real_dev ( struct net_device * real_dev , u16 vlan_id ) ;
2007-06-13 23:07:54 +04:00
void vlan_setup ( struct net_device * dev ) ;
int register_vlan_dev ( struct net_device * dev ) ;
2009-10-27 10:06:36 +03:00
void unregister_vlan_dev ( struct net_device * dev , struct list_head * head ) ;
2007-06-13 23:07:54 +04:00
2008-07-08 14:23:36 +04:00
static inline u32 vlan_get_ingress_priority ( struct net_device * dev ,
2008-07-08 14:24:44 +04:00
u16 vlan_tci )
2008-07-08 14:23:36 +04:00
{
2011-12-08 08:11:15 +04:00
struct vlan_dev_priv * vip = vlan_dev_priv ( dev ) ;
2008-07-08 14:23:36 +04:00
2009-10-27 04:40:35 +03:00
return vip - > ingress_priority_map [ ( vlan_tci > > VLAN_PRIO_SHIFT ) & 0x7 ] ;
2008-07-08 14:23:36 +04:00
}
2008-07-06 08:26:57 +04:00
# ifdef CONFIG_VLAN_8021Q_GVRP
extern int vlan_gvrp_request_join ( const struct net_device * dev ) ;
extern void vlan_gvrp_request_leave ( const struct net_device * dev ) ;
extern int vlan_gvrp_init_applicant ( struct net_device * dev ) ;
extern void vlan_gvrp_uninit_applicant ( struct net_device * dev ) ;
extern int vlan_gvrp_init ( void ) ;
extern void vlan_gvrp_uninit ( void ) ;
# else
static inline int vlan_gvrp_request_join ( const struct net_device * dev ) { return 0 ; }
static inline void vlan_gvrp_request_leave ( const struct net_device * dev ) { }
static inline int vlan_gvrp_init_applicant ( struct net_device * dev ) { return 0 ; }
static inline void vlan_gvrp_uninit_applicant ( struct net_device * dev ) { }
static inline int vlan_gvrp_init ( void ) { return 0 ; }
static inline void vlan_gvrp_uninit ( void ) { }
# endif
2008-10-29 08:12:36 +03:00
extern const char vlan_fullname [ ] ;
extern const char vlan_version [ ] ;
extern int vlan_netlink_init ( void ) ;
extern void vlan_netlink_fini ( void ) ;
2007-06-13 23:07:54 +04:00
extern struct rtnl_link_ops vlan_link_ops ;
2008-04-16 11:49:09 +04:00
extern int vlan_net_id ;
2008-04-16 11:51:51 +04:00
struct proc_dir_entry ;
2008-04-16 11:49:09 +04:00
struct vlan_net {
2008-04-16 11:51:51 +04:00
/* /proc/net/vlan */
struct proc_dir_entry * proc_vlan_dir ;
/* /proc/net/vlan/config */
struct proc_dir_entry * proc_vlan_conf ;
2008-04-16 11:54:39 +04:00
/* Determines interface naming scheme. */
unsigned short name_type ;
2008-04-16 11:49:09 +04:00
} ;
2005-04-17 02:20:36 +04:00
# endif /* !(__BEN_VLAN_802_1Q_INC__) */