2017-12-01 15:08:58 -08:00
/*
* Copyright ( C ) 2017 Netronome Systems , Inc .
*
* This software is licensed under the GNU General License Version 2 ,
* June 1991 as shown in the file COPYING in the top - level directory of this
* source tree .
*
* THE COPYRIGHT HOLDERS AND / OR OTHER PARTIES PROVIDE THE PROGRAM " AS IS "
* WITHOUT WARRANTY OF ANY KIND , EITHER EXPRESSED OR IMPLIED , INCLUDING ,
* BUT NOT LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE . THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
* OF THE PROGRAM IS WITH YOU . SHOULD THE PROGRAM PROVE DEFECTIVE , YOU ASSUME
* THE COST OF ALL NECESSARY SERVICING , REPAIR OR CORRECTION .
*/
2017-12-01 15:09:01 -08:00
# include <linux/device.h>
2017-12-01 15:08:58 -08:00
# include <linux/kernel.h>
2017-12-01 15:08:59 -08:00
# include <linux/list.h>
2017-12-01 15:08:58 -08:00
# include <linux/netdevice.h>
# include <linux/u64_stats_sync.h>
2019-04-25 15:59:53 +02:00
# include <net/devlink.h>
2018-07-11 20:36:40 -07:00
# include <net/xdp.h>
2017-12-01 15:08:58 -08:00
# define DRV_NAME "netdevsim"
2017-12-01 15:08:59 -08:00
# define NSIM_XDP_MAX_MTU 4000
# define NSIM_EA(extack, msg) NL_SET_ERR_MSG_MOD((extack), msg)
2018-06-26 10:07:54 -07:00
# define NSIM_IPSEC_MAX_SA_COUNT 33
# define NSIM_IPSEC_VALID BIT(31)
struct nsim_sa {
struct xfrm_state * xs ;
__be32 ipaddr [ 4 ] ;
u32 key [ 4 ] ;
u32 salt ;
bool used ;
bool crypt ;
bool rx ;
} ;
struct nsim_ipsec {
struct nsim_sa sa [ NSIM_IPSEC_MAX_SA_COUNT ] ;
struct dentry * pfile ;
u32 count ;
u32 tx ;
u32 ok ;
} ;
2017-12-01 15:08:58 -08:00
struct netdevsim {
2017-12-01 15:08:59 -08:00
struct net_device * netdev ;
2019-04-25 15:59:49 +02:00
struct nsim_dev * nsim_dev ;
2019-04-25 15:59:55 +02:00
struct nsim_dev_port * nsim_dev_port ;
2017-12-01 15:08:59 -08:00
2017-12-01 15:08:58 -08:00
u64 tx_packets ;
u64 tx_bytes ;
struct u64_stats_sync syncp ;
2017-12-01 15:08:59 -08:00
2019-04-25 15:59:45 +02:00
struct nsim_bus_dev * nsim_bus_dev ;
2017-12-01 15:09:01 -08:00
2017-12-01 15:08:59 -08:00
struct bpf_prog * bpf_offloaded ;
u32 bpf_offloaded_id ;
2018-07-11 20:36:40 -07:00
struct xdp_attachment_info xdp ;
2018-07-11 20:36:42 -07:00
struct xdp_attachment_info xdp_hw ;
2017-12-01 15:08:59 -08:00
bool bpf_tc_accept ;
bool bpf_tc_non_bound_accept ;
bool bpf_xdpdrv_accept ;
bool bpf_xdpoffload_accept ;
2018-01-17 19:13:30 -08:00
bool bpf_map_accept ;
2018-06-26 10:07:54 -07:00
struct nsim_ipsec ipsec ;
2017-12-01 15:08:58 -08:00
} ;
2017-12-01 15:08:59 -08:00
2019-04-25 15:59:55 +02:00
struct netdevsim *
nsim_create ( struct nsim_dev * nsim_dev , struct nsim_dev_port * nsim_dev_port ) ;
void nsim_destroy ( struct netdevsim * ns ) ;
2018-01-23 11:22:54 -08:00
# ifdef CONFIG_BPF_SYSCALL
2019-04-25 15:59:50 +02:00
int nsim_bpf_dev_init ( struct nsim_dev * nsim_dev ) ;
void nsim_bpf_dev_exit ( struct nsim_dev * nsim_dev ) ;
2017-12-01 15:08:59 -08:00
int nsim_bpf_init ( struct netdevsim * ns ) ;
void nsim_bpf_uninit ( struct netdevsim * ns ) ;
int nsim_bpf ( struct net_device * dev , struct netdev_bpf * bpf ) ;
int nsim_bpf_disable_tc ( struct netdevsim * ns ) ;
int nsim_bpf_setup_tc_block_cb ( enum tc_setup_type type ,
void * type_data , void * cb_priv ) ;
2018-01-23 11:22:54 -08:00
# else
2019-04-25 15:59:50 +02:00
static inline int nsim_bpf_dev_init ( struct nsim_dev * nsim_dev )
{
return 0 ;
}
static inline void nsim_bpf_dev_exit ( struct nsim_dev * nsim_dev )
{
}
2018-01-23 11:22:54 -08:00
static inline int nsim_bpf_init ( struct netdevsim * ns )
{
return 0 ;
}
static inline void nsim_bpf_uninit ( struct netdevsim * ns )
{
}
static inline int nsim_bpf ( struct net_device * dev , struct netdev_bpf * bpf )
{
return bpf - > command = = XDP_QUERY_PROG ? 0 : - EOPNOTSUPP ;
}
static inline int nsim_bpf_disable_tc ( struct netdevsim * ns )
{
return 0 ;
}
static inline int
nsim_bpf_setup_tc_block_cb ( enum tc_setup_type type , void * type_data ,
void * cb_priv )
{
return - EOPNOTSUPP ;
}
# endif
2017-12-01 15:09:01 -08:00
2018-03-27 18:22:00 -07:00
enum nsim_resource_id {
NSIM_RESOURCE_NONE , /* DEVLINK_RESOURCE_ID_PARENT_TOP */
NSIM_RESOURCE_IPV4 ,
NSIM_RESOURCE_IPV4_FIB ,
NSIM_RESOURCE_IPV4_FIB_RULES ,
NSIM_RESOURCE_IPV6 ,
NSIM_RESOURCE_IPV6_FIB ,
NSIM_RESOURCE_IPV6_FIB_RULES ,
} ;
2019-04-25 15:59:53 +02:00
struct nsim_dev_port {
struct list_head list ;
struct devlink_port devlink_port ;
unsigned int port_index ;
struct dentry * ddir ;
2019-04-25 15:59:55 +02:00
struct netdevsim * ns ;
2019-04-25 15:59:53 +02:00
} ;
2019-04-25 15:59:49 +02:00
struct nsim_dev {
2019-04-25 15:59:50 +02:00
struct nsim_bus_dev * nsim_bus_dev ;
2019-04-25 15:59:49 +02:00
struct nsim_fib_data * fib_data ;
2019-04-25 15:59:50 +02:00
struct dentry * ddir ;
2019-04-25 15:59:52 +02:00
struct dentry * ports_ddir ;
2019-04-25 15:59:50 +02:00
struct bpf_offload_dev * bpf_dev ;
bool bpf_bind_accept ;
u32 bpf_bind_verifier_delay ;
struct dentry * ddir_bpf_bound_progs ;
u32 prog_id_gen ;
struct list_head bpf_bound_progs ;
struct list_head bpf_bound_maps ;
2019-04-25 15:59:51 +02:00
struct netdev_phys_item_id switch_id ;
2019-04-25 15:59:53 +02:00
struct list_head port_list ;
2019-04-25 15:59:54 +02:00
struct mutex port_list_lock ; /* protects port list */
2019-06-04 15:40:43 +02:00
bool fw_update_status ;
2019-04-25 15:59:49 +02:00
} ;
2019-04-25 15:59:50 +02:00
int nsim_dev_init ( void ) ;
void nsim_dev_exit ( void ) ;
2019-04-25 15:59:53 +02:00
int nsim_dev_probe ( struct nsim_bus_dev * nsim_bus_dev ) ;
void nsim_dev_remove ( struct nsim_bus_dev * nsim_bus_dev ) ;
2019-04-25 15:59:54 +02:00
int nsim_dev_port_add ( struct nsim_bus_dev * nsim_bus_dev ,
unsigned int port_index ) ;
int nsim_dev_port_del ( struct nsim_bus_dev * nsim_bus_dev ,
unsigned int port_index ) ;
2018-03-27 18:22:00 -07:00
2019-04-25 15:59:42 +02:00
struct nsim_fib_data * nsim_fib_create ( void ) ;
void nsim_fib_destroy ( struct nsim_fib_data * fib_data ) ;
u64 nsim_fib_get_val ( struct nsim_fib_data * fib_data ,
enum nsim_resource_id res_id , bool max ) ;
int nsim_fib_set_max ( struct nsim_fib_data * fib_data ,
enum nsim_resource_id res_id , u64 val ,
2018-06-05 08:14:10 -07:00
struct netlink_ext_ack * extack ) ;
2018-03-27 18:22:00 -07:00
2018-06-26 10:07:54 -07:00
# if IS_ENABLED(CONFIG_XFRM_OFFLOAD)
void nsim_ipsec_init ( struct netdevsim * ns ) ;
void nsim_ipsec_teardown ( struct netdevsim * ns ) ;
bool nsim_ipsec_tx ( struct netdevsim * ns , struct sk_buff * skb ) ;
# else
static inline void nsim_ipsec_init ( struct netdevsim * ns )
{
}
static inline void nsim_ipsec_teardown ( struct netdevsim * ns )
{
}
static inline bool nsim_ipsec_tx ( struct netdevsim * ns , struct sk_buff * skb )
{
return true ;
}
# endif
2019-04-25 15:59:45 +02:00
struct nsim_vf_config {
int link_state ;
u16 min_tx_rate ;
u16 max_tx_rate ;
u16 vlan ;
__be16 vlan_proto ;
u16 qos ;
u8 vf_mac [ ETH_ALEN ] ;
bool spoofchk_enabled ;
bool trusted ;
bool rss_query_enabled ;
} ;
2019-04-25 15:59:44 +02:00
2019-04-25 15:59:45 +02:00
struct nsim_bus_dev {
struct device dev ;
2019-04-25 15:59:48 +02:00
struct list_head list ;
unsigned int port_count ;
2019-04-25 15:59:45 +02:00
unsigned int num_vfs ;
struct nsim_vf_config * vfconfigs ;
} ;
2019-04-25 15:59:44 +02:00
int nsim_bus_init ( void ) ;
void nsim_bus_exit ( void ) ;