2017-12-02 02:08:58 +03: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-02 02:09:01 +03:00
# include <linux/device.h>
2017-12-02 02:08:58 +03:00
# include <linux/kernel.h>
2017-12-02 02:08:59 +03:00
# include <linux/list.h>
2017-12-02 02:08:58 +03:00
# include <linux/netdevice.h>
# include <linux/u64_stats_sync.h>
2019-04-25 16:59:53 +03:00
# include <net/devlink.h>
2018-07-12 06:36:40 +03:00
# include <net/xdp.h>
2017-12-02 02:08:58 +03:00
# define DRV_NAME "netdevsim"
2017-12-02 02:08:59 +03:00
# define NSIM_XDP_MAX_MTU 4000
# define NSIM_EA(extack, msg) NL_SET_ERR_MSG_MOD((extack), msg)
2018-06-26 20:07:54 +03: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-02 02:08:58 +03:00
struct netdevsim {
2017-12-02 02:08:59 +03:00
struct net_device * netdev ;
2019-04-25 16:59:49 +03:00
struct nsim_dev * nsim_dev ;
2019-04-25 16:59:55 +03:00
struct nsim_dev_port * nsim_dev_port ;
2017-12-02 02:08:59 +03:00
2017-12-02 02:08:58 +03:00
u64 tx_packets ;
u64 tx_bytes ;
struct u64_stats_sync syncp ;
2017-12-02 02:08:59 +03:00
2019-04-25 16:59:45 +03:00
struct nsim_bus_dev * nsim_bus_dev ;
2017-12-02 02:09:01 +03:00
2017-12-02 02:08:59 +03:00
struct bpf_prog * bpf_offloaded ;
u32 bpf_offloaded_id ;
2018-07-12 06:36:40 +03:00
struct xdp_attachment_info xdp ;
2018-07-12 06:36:42 +03:00
struct xdp_attachment_info xdp_hw ;
2017-12-02 02:08:59 +03:00
bool bpf_tc_accept ;
bool bpf_tc_non_bound_accept ;
bool bpf_xdpdrv_accept ;
bool bpf_xdpoffload_accept ;
2018-01-18 06:13:30 +03:00
bool bpf_map_accept ;
2018-06-26 20:07:54 +03:00
struct nsim_ipsec ipsec ;
2017-12-02 02:08:58 +03:00
} ;
2017-12-02 02:08:59 +03:00
2019-04-25 16:59:55 +03: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 22:22:54 +03:00
# ifdef CONFIG_BPF_SYSCALL
2019-04-25 16:59:50 +03:00
int nsim_bpf_dev_init ( struct nsim_dev * nsim_dev ) ;
void nsim_bpf_dev_exit ( struct nsim_dev * nsim_dev ) ;
2017-12-02 02:08:59 +03: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 22:22:54 +03:00
# else
2019-04-25 16:59:50 +03: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 22:22:54 +03: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-02 02:09:01 +03:00
2018-03-28 04:22:00 +03: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 16:59:53 +03:00
struct nsim_dev_port {
struct list_head list ;
struct devlink_port devlink_port ;
unsigned int port_index ;
struct dentry * ddir ;
2019-04-25 16:59:55 +03:00
struct netdevsim * ns ;
2019-04-25 16:59:53 +03:00
} ;
2019-04-25 16:59:49 +03:00
struct nsim_dev {
2019-04-25 16:59:50 +03:00
struct nsim_bus_dev * nsim_bus_dev ;
2019-04-25 16:59:49 +03:00
struct nsim_fib_data * fib_data ;
2019-08-17 16:28:20 +03:00
struct nsim_trap_data * trap_data ;
2019-04-25 16:59:50 +03:00
struct dentry * ddir ;
2019-04-25 16:59:52 +03:00
struct dentry * ports_ddir ;
2019-04-25 16:59:50 +03: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 16:59:51 +03:00
struct netdev_phys_item_id switch_id ;
2019-04-25 16:59:53 +03:00
struct list_head port_list ;
2019-04-25 16:59:54 +03:00
struct mutex port_list_lock ; /* protects port list */
2019-06-04 16:40:43 +03:00
bool fw_update_status ;
2019-08-09 14:05:12 +03:00
u32 max_macs ;
bool test1 ;
2019-10-06 09:30:01 +03:00
bool dont_allow_reload ;
bool fail_reload ;
2019-08-15 16:46:33 +03:00
struct devlink_region * dummy_region ;
2019-04-25 16:59:49 +03:00
} ;
2019-10-03 12:49:37 +03:00
static inline struct net * nsim_dev_net ( struct nsim_dev * nsim_dev )
{
return devlink_net ( priv_to_devlink ( nsim_dev ) ) ;
}
2019-04-25 16:59:50 +03:00
int nsim_dev_init ( void ) ;
void nsim_dev_exit ( void ) ;
2019-04-25 16:59:53 +03: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 16:59:54 +03: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-28 04:22:00 +03:00
2019-10-03 12:49:36 +03:00
struct nsim_fib_data * nsim_fib_create ( struct devlink * devlink ,
struct netlink_ext_ack * extack ) ;
void nsim_fib_destroy ( struct devlink * devlink , struct nsim_fib_data * fib_data ) ;
2019-10-03 12:49:26 +03:00
u64 nsim_fib_get_val ( struct nsim_fib_data * fib_data ,
enum nsim_resource_id res_id , bool max ) ;
2018-03-28 04:22:00 +03:00
2018-06-26 20:07:54 +03: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 16:59:45 +03: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 16:59:44 +03:00
2019-04-25 16:59:45 +03:00
struct nsim_bus_dev {
struct device dev ;
2019-04-25 16:59:48 +03:00
struct list_head list ;
unsigned int port_count ;
2019-10-05 09:10:32 +03:00
struct net * initial_net ; /* Purpose of this is to carry net pointer
* during the probe time only .
*/
2019-04-25 16:59:45 +03:00
unsigned int num_vfs ;
struct nsim_vf_config * vfconfigs ;
} ;
2019-04-25 16:59:44 +03:00
int nsim_bus_init ( void ) ;
void nsim_bus_exit ( void ) ;