183c9e13aSJakub Kicinski /* 283c9e13aSJakub Kicinski * Copyright (C) 2017 Netronome Systems, Inc. 383c9e13aSJakub Kicinski * 483c9e13aSJakub Kicinski * This software is licensed under the GNU General License Version 2, 583c9e13aSJakub Kicinski * June 1991 as shown in the file COPYING in the top-level directory of this 683c9e13aSJakub Kicinski * source tree. 783c9e13aSJakub Kicinski * 883c9e13aSJakub Kicinski * THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" 983c9e13aSJakub Kicinski * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, 1083c9e13aSJakub Kicinski * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 1183c9e13aSJakub Kicinski * FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE 1283c9e13aSJakub Kicinski * OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME 1383c9e13aSJakub Kicinski * THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 1483c9e13aSJakub Kicinski */ 1583c9e13aSJakub Kicinski 1679579220SJakub Kicinski #include <linux/device.h> 1783c9e13aSJakub Kicinski #include <linux/kernel.h> 1831d3ad83SJakub Kicinski #include <linux/list.h> 1983c9e13aSJakub Kicinski #include <linux/netdevice.h> 2083c9e13aSJakub Kicinski #include <linux/u64_stats_sync.h> 2183c9e13aSJakub Kicinski 2283c9e13aSJakub Kicinski #define DRV_NAME "netdevsim" 2383c9e13aSJakub Kicinski 2431d3ad83SJakub Kicinski #define NSIM_XDP_MAX_MTU 4000 2531d3ad83SJakub Kicinski 2631d3ad83SJakub Kicinski #define NSIM_EA(extack, msg) NL_SET_ERR_MSG_MOD((extack), msg) 2731d3ad83SJakub Kicinski 2831d3ad83SJakub Kicinski struct bpf_prog; 2931d3ad83SJakub Kicinski struct dentry; 3079579220SJakub Kicinski struct nsim_vf_config; 3131d3ad83SJakub Kicinski 3283c9e13aSJakub Kicinski struct netdevsim { 3331d3ad83SJakub Kicinski struct net_device *netdev; 3431d3ad83SJakub Kicinski 3583c9e13aSJakub Kicinski u64 tx_packets; 3683c9e13aSJakub Kicinski u64 tx_bytes; 3783c9e13aSJakub Kicinski struct u64_stats_sync syncp; 3831d3ad83SJakub Kicinski 3979579220SJakub Kicinski struct device dev; 4079579220SJakub Kicinski 4131d3ad83SJakub Kicinski struct dentry *ddir; 4231d3ad83SJakub Kicinski 4379579220SJakub Kicinski unsigned int num_vfs; 4479579220SJakub Kicinski struct nsim_vf_config *vfconfigs; 4579579220SJakub Kicinski 4631d3ad83SJakub Kicinski struct bpf_prog *bpf_offloaded; 4731d3ad83SJakub Kicinski u32 bpf_offloaded_id; 4831d3ad83SJakub Kicinski 4931d3ad83SJakub Kicinski u32 xdp_flags; 5031d3ad83SJakub Kicinski int xdp_prog_mode; 5131d3ad83SJakub Kicinski struct bpf_prog *xdp_prog; 5231d3ad83SJakub Kicinski 5331d3ad83SJakub Kicinski u32 prog_id_gen; 5431d3ad83SJakub Kicinski 5531d3ad83SJakub Kicinski bool bpf_bind_accept; 5631d3ad83SJakub Kicinski u32 bpf_bind_verifier_delay; 5731d3ad83SJakub Kicinski struct dentry *ddir_bpf_bound_progs; 5831d3ad83SJakub Kicinski struct list_head bpf_bound_progs; 5931d3ad83SJakub Kicinski 6031d3ad83SJakub Kicinski bool bpf_tc_accept; 6131d3ad83SJakub Kicinski bool bpf_tc_non_bound_accept; 6231d3ad83SJakub Kicinski bool bpf_xdpdrv_accept; 6331d3ad83SJakub Kicinski bool bpf_xdpoffload_accept; 64395cacb5SJakub Kicinski 65395cacb5SJakub Kicinski bool bpf_map_accept; 66395cacb5SJakub Kicinski struct list_head bpf_bound_maps; 6737923ed6SDavid Ahern #if IS_ENABLED(CONFIG_NET_DEVLINK) 6837923ed6SDavid Ahern struct devlink *devlink; 6937923ed6SDavid Ahern #endif 7083c9e13aSJakub Kicinski }; 7131d3ad83SJakub Kicinski 7231d3ad83SJakub Kicinski extern struct dentry *nsim_ddir; 7331d3ad83SJakub Kicinski 747c5db7e7SJakub Kicinski #ifdef CONFIG_BPF_SYSCALL 7531d3ad83SJakub Kicinski int nsim_bpf_init(struct netdevsim *ns); 7631d3ad83SJakub Kicinski void nsim_bpf_uninit(struct netdevsim *ns); 7731d3ad83SJakub Kicinski int nsim_bpf(struct net_device *dev, struct netdev_bpf *bpf); 7831d3ad83SJakub Kicinski int nsim_bpf_disable_tc(struct netdevsim *ns); 7931d3ad83SJakub Kicinski int nsim_bpf_setup_tc_block_cb(enum tc_setup_type type, 8031d3ad83SJakub Kicinski void *type_data, void *cb_priv); 817c5db7e7SJakub Kicinski #else 827c5db7e7SJakub Kicinski static inline int nsim_bpf_init(struct netdevsim *ns) 837c5db7e7SJakub Kicinski { 847c5db7e7SJakub Kicinski return 0; 857c5db7e7SJakub Kicinski } 867c5db7e7SJakub Kicinski 877c5db7e7SJakub Kicinski static inline void nsim_bpf_uninit(struct netdevsim *ns) 887c5db7e7SJakub Kicinski { 897c5db7e7SJakub Kicinski } 907c5db7e7SJakub Kicinski 917c5db7e7SJakub Kicinski static inline int nsim_bpf(struct net_device *dev, struct netdev_bpf *bpf) 927c5db7e7SJakub Kicinski { 937c5db7e7SJakub Kicinski return bpf->command == XDP_QUERY_PROG ? 0 : -EOPNOTSUPP; 947c5db7e7SJakub Kicinski } 957c5db7e7SJakub Kicinski 967c5db7e7SJakub Kicinski static inline int nsim_bpf_disable_tc(struct netdevsim *ns) 977c5db7e7SJakub Kicinski { 987c5db7e7SJakub Kicinski return 0; 997c5db7e7SJakub Kicinski } 1007c5db7e7SJakub Kicinski 1017c5db7e7SJakub Kicinski static inline int 1027c5db7e7SJakub Kicinski nsim_bpf_setup_tc_block_cb(enum tc_setup_type type, void *type_data, 1037c5db7e7SJakub Kicinski void *cb_priv) 1047c5db7e7SJakub Kicinski { 1057c5db7e7SJakub Kicinski return -EOPNOTSUPP; 1067c5db7e7SJakub Kicinski } 1077c5db7e7SJakub Kicinski #endif 10879579220SJakub Kicinski 10937923ed6SDavid Ahern #if IS_ENABLED(CONFIG_NET_DEVLINK) 11037923ed6SDavid Ahern enum nsim_resource_id { 11137923ed6SDavid Ahern NSIM_RESOURCE_NONE, /* DEVLINK_RESOURCE_ID_PARENT_TOP */ 11237923ed6SDavid Ahern NSIM_RESOURCE_IPV4, 11337923ed6SDavid Ahern NSIM_RESOURCE_IPV4_FIB, 11437923ed6SDavid Ahern NSIM_RESOURCE_IPV4_FIB_RULES, 11537923ed6SDavid Ahern NSIM_RESOURCE_IPV6, 11637923ed6SDavid Ahern NSIM_RESOURCE_IPV6_FIB, 11737923ed6SDavid Ahern NSIM_RESOURCE_IPV6_FIB_RULES, 11837923ed6SDavid Ahern }; 11937923ed6SDavid Ahern 120ef817102SDavid Ahern int nsim_devlink_setup(struct netdevsim *ns); 12137923ed6SDavid Ahern void nsim_devlink_teardown(struct netdevsim *ns); 12237923ed6SDavid Ahern 12337923ed6SDavid Ahern int nsim_devlink_init(void); 12437923ed6SDavid Ahern void nsim_devlink_exit(void); 12537923ed6SDavid Ahern 12637923ed6SDavid Ahern int nsim_fib_init(void); 12737923ed6SDavid Ahern void nsim_fib_exit(void); 12837923ed6SDavid Ahern u64 nsim_fib_get_val(struct net *net, enum nsim_resource_id res_id, bool max); 129*7fa76d77SDavid Ahern int nsim_fib_set_max(struct net *net, enum nsim_resource_id res_id, u64 val, 130*7fa76d77SDavid Ahern struct netlink_ext_ack *extack); 13137923ed6SDavid Ahern #else 132ef817102SDavid Ahern static inline int nsim_devlink_setup(struct netdevsim *ns) 13337923ed6SDavid Ahern { 134ef817102SDavid Ahern return 0; 13537923ed6SDavid Ahern } 13637923ed6SDavid Ahern 13737923ed6SDavid Ahern static inline void nsim_devlink_teardown(struct netdevsim *ns) 13837923ed6SDavid Ahern { 13937923ed6SDavid Ahern } 14037923ed6SDavid Ahern 14137923ed6SDavid Ahern static inline int nsim_devlink_init(void) 14237923ed6SDavid Ahern { 14337923ed6SDavid Ahern return 0; 14437923ed6SDavid Ahern } 14537923ed6SDavid Ahern 14637923ed6SDavid Ahern static inline void nsim_devlink_exit(void) 14737923ed6SDavid Ahern { 14837923ed6SDavid Ahern } 14937923ed6SDavid Ahern #endif 15037923ed6SDavid Ahern 15179579220SJakub Kicinski static inline struct netdevsim *to_nsim(struct device *ptr) 15279579220SJakub Kicinski { 15379579220SJakub Kicinski return container_of(ptr, struct netdevsim, dev); 15479579220SJakub Kicinski } 155