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 16424be63aSJakub Kicinski #include <linux/debugfs.h> 1779579220SJakub Kicinski #include <linux/device.h> 1883c9e13aSJakub Kicinski #include <linux/kernel.h> 1931d3ad83SJakub Kicinski #include <linux/list.h> 2083c9e13aSJakub Kicinski #include <linux/netdevice.h> 2183c9e13aSJakub Kicinski #include <linux/u64_stats_sync.h> 228320d145SJiri Pirko #include <net/devlink.h> 23dc9c0753SJakub Kicinski #include <net/udp_tunnel.h> 2405296620SJakub Kicinski #include <net/xdp.h> 2583c9e13aSJakub Kicinski 2683c9e13aSJakub Kicinski #define DRV_NAME "netdevsim" 2783c9e13aSJakub Kicinski 2831d3ad83SJakub Kicinski #define NSIM_XDP_MAX_MTU 4000 2931d3ad83SJakub Kicinski 3031d3ad83SJakub Kicinski #define NSIM_EA(extack, msg) NL_SET_ERR_MSG_MOD((extack), msg) 3131d3ad83SJakub Kicinski 327699353dSShannon Nelson #define NSIM_IPSEC_MAX_SA_COUNT 33 337699353dSShannon Nelson #define NSIM_IPSEC_VALID BIT(31) 34424be63aSJakub Kicinski #define NSIM_UDP_TUNNEL_N_PORTS 4 357699353dSShannon Nelson 367699353dSShannon Nelson struct nsim_sa { 377699353dSShannon Nelson struct xfrm_state *xs; 387699353dSShannon Nelson __be32 ipaddr[4]; 397699353dSShannon Nelson u32 key[4]; 407699353dSShannon Nelson u32 salt; 417699353dSShannon Nelson bool used; 427699353dSShannon Nelson bool crypt; 437699353dSShannon Nelson bool rx; 447699353dSShannon Nelson }; 457699353dSShannon Nelson 467699353dSShannon Nelson struct nsim_ipsec { 477699353dSShannon Nelson struct nsim_sa sa[NSIM_IPSEC_MAX_SA_COUNT]; 487699353dSShannon Nelson struct dentry *pfile; 497699353dSShannon Nelson u32 count; 507699353dSShannon Nelson u32 tx; 517699353dSShannon Nelson u32 ok; 527699353dSShannon Nelson }; 537699353dSShannon Nelson 54ff1f7c17SJakub Kicinski struct nsim_ethtool { 55ff1f7c17SJakub Kicinski bool rx; 56ff1f7c17SJakub Kicinski bool tx; 57ff1f7c17SJakub Kicinski bool report_stats_rx; 58ff1f7c17SJakub Kicinski bool report_stats_tx; 59ff1f7c17SJakub Kicinski }; 60ff1f7c17SJakub Kicinski 6183c9e13aSJakub Kicinski struct netdevsim { 6231d3ad83SJakub Kicinski struct net_device *netdev; 63a60f9e48SJiri Pirko struct nsim_dev *nsim_dev; 64e05b2d14SJiri Pirko struct nsim_dev_port *nsim_dev_port; 6531d3ad83SJakub Kicinski 6683c9e13aSJakub Kicinski u64 tx_packets; 6783c9e13aSJakub Kicinski u64 tx_bytes; 6883c9e13aSJakub Kicinski struct u64_stats_sync syncp; 6931d3ad83SJakub Kicinski 7040e4fe4cSJiri Pirko struct nsim_bus_dev *nsim_bus_dev; 7179579220SJakub Kicinski 7231d3ad83SJakub Kicinski struct bpf_prog *bpf_offloaded; 7331d3ad83SJakub Kicinski u32 bpf_offloaded_id; 7431d3ad83SJakub Kicinski 7505296620SJakub Kicinski struct xdp_attachment_info xdp; 76799e173dSJakub Kicinski struct xdp_attachment_info xdp_hw; 7731d3ad83SJakub Kicinski 7831d3ad83SJakub Kicinski bool bpf_tc_accept; 7931d3ad83SJakub Kicinski bool bpf_tc_non_bound_accept; 8031d3ad83SJakub Kicinski bool bpf_xdpdrv_accept; 8131d3ad83SJakub Kicinski bool bpf_xdpoffload_accept; 82395cacb5SJakub Kicinski 83395cacb5SJakub Kicinski bool bpf_map_accept; 847699353dSShannon Nelson struct nsim_ipsec ipsec; 85424be63aSJakub Kicinski struct { 86424be63aSJakub Kicinski u32 inject_error; 87424be63aSJakub Kicinski u32 sleep; 88dc9c0753SJakub Kicinski u32 __ports[2][NSIM_UDP_TUNNEL_N_PORTS]; 89dc9c0753SJakub Kicinski u32 (*ports)[NSIM_UDP_TUNNEL_N_PORTS]; 90424be63aSJakub Kicinski struct debugfs_u32_array dfs_ports[2]; 91424be63aSJakub Kicinski } udp_ports; 92ff1f7c17SJakub Kicinski 93ff1f7c17SJakub Kicinski struct nsim_ethtool ethtool; 9483c9e13aSJakub Kicinski }; 9531d3ad83SJakub Kicinski 96e05b2d14SJiri Pirko struct netdevsim * 97e05b2d14SJiri Pirko nsim_create(struct nsim_dev *nsim_dev, struct nsim_dev_port *nsim_dev_port); 98e05b2d14SJiri Pirko void nsim_destroy(struct netdevsim *ns); 99e05b2d14SJiri Pirko 100ff1f7c17SJakub Kicinski void nsim_ethtool_init(struct netdevsim *ns); 101ff1f7c17SJakub Kicinski 102424be63aSJakub Kicinski void nsim_udp_tunnels_debugfs_create(struct nsim_dev *nsim_dev); 103424be63aSJakub Kicinski int nsim_udp_tunnels_info_create(struct nsim_dev *nsim_dev, 104424be63aSJakub Kicinski struct net_device *dev); 105424be63aSJakub Kicinski void nsim_udp_tunnels_info_destroy(struct net_device *dev); 106424be63aSJakub Kicinski 1077c5db7e7SJakub Kicinski #ifdef CONFIG_BPF_SYSCALL 108d514f41eSJiri Pirko int nsim_bpf_dev_init(struct nsim_dev *nsim_dev); 109d514f41eSJiri Pirko void nsim_bpf_dev_exit(struct nsim_dev *nsim_dev); 11031d3ad83SJakub Kicinski int nsim_bpf_init(struct netdevsim *ns); 11131d3ad83SJakub Kicinski void nsim_bpf_uninit(struct netdevsim *ns); 11231d3ad83SJakub Kicinski int nsim_bpf(struct net_device *dev, struct netdev_bpf *bpf); 11331d3ad83SJakub Kicinski int nsim_bpf_disable_tc(struct netdevsim *ns); 11431d3ad83SJakub Kicinski int nsim_bpf_setup_tc_block_cb(enum tc_setup_type type, 11531d3ad83SJakub Kicinski void *type_data, void *cb_priv); 1167c5db7e7SJakub Kicinski #else 117d514f41eSJiri Pirko 118d514f41eSJiri Pirko static inline int nsim_bpf_dev_init(struct nsim_dev *nsim_dev) 119d514f41eSJiri Pirko { 120d514f41eSJiri Pirko return 0; 121d514f41eSJiri Pirko } 122d514f41eSJiri Pirko 123d514f41eSJiri Pirko static inline void nsim_bpf_dev_exit(struct nsim_dev *nsim_dev) 124d514f41eSJiri Pirko { 125d514f41eSJiri Pirko } 1267c5db7e7SJakub Kicinski static inline int nsim_bpf_init(struct netdevsim *ns) 1277c5db7e7SJakub Kicinski { 1287c5db7e7SJakub Kicinski return 0; 1297c5db7e7SJakub Kicinski } 1307c5db7e7SJakub Kicinski 1317c5db7e7SJakub Kicinski static inline void nsim_bpf_uninit(struct netdevsim *ns) 1327c5db7e7SJakub Kicinski { 1337c5db7e7SJakub Kicinski } 1347c5db7e7SJakub Kicinski 1357c5db7e7SJakub Kicinski static inline int nsim_bpf(struct net_device *dev, struct netdev_bpf *bpf) 1367c5db7e7SJakub Kicinski { 137e8407fdeSAndrii Nakryiko return -EOPNOTSUPP; 1387c5db7e7SJakub Kicinski } 1397c5db7e7SJakub Kicinski 1407c5db7e7SJakub Kicinski static inline int nsim_bpf_disable_tc(struct netdevsim *ns) 1417c5db7e7SJakub Kicinski { 1427c5db7e7SJakub Kicinski return 0; 1437c5db7e7SJakub Kicinski } 1447c5db7e7SJakub Kicinski 1457c5db7e7SJakub Kicinski static inline int 1467c5db7e7SJakub Kicinski nsim_bpf_setup_tc_block_cb(enum tc_setup_type type, void *type_data, 1477c5db7e7SJakub Kicinski void *cb_priv) 1487c5db7e7SJakub Kicinski { 1497c5db7e7SJakub Kicinski return -EOPNOTSUPP; 1507c5db7e7SJakub Kicinski } 1517c5db7e7SJakub Kicinski #endif 15279579220SJakub Kicinski 15337923ed6SDavid Ahern enum nsim_resource_id { 15437923ed6SDavid Ahern NSIM_RESOURCE_NONE, /* DEVLINK_RESOURCE_ID_PARENT_TOP */ 15537923ed6SDavid Ahern NSIM_RESOURCE_IPV4, 15637923ed6SDavid Ahern NSIM_RESOURCE_IPV4_FIB, 15737923ed6SDavid Ahern NSIM_RESOURCE_IPV4_FIB_RULES, 15837923ed6SDavid Ahern NSIM_RESOURCE_IPV6, 15937923ed6SDavid Ahern NSIM_RESOURCE_IPV6_FIB, 16037923ed6SDavid Ahern NSIM_RESOURCE_IPV6_FIB_RULES, 16137923ed6SDavid Ahern }; 16237923ed6SDavid Ahern 16382c93a87SJiri Pirko struct nsim_dev_health { 16482c93a87SJiri Pirko struct devlink_health_reporter *empty_reporter; 16582c93a87SJiri Pirko struct devlink_health_reporter *dummy_reporter; 16682c93a87SJiri Pirko struct dentry *ddir; 16782c93a87SJiri Pirko char *recovered_break_msg; 16882c93a87SJiri Pirko u32 binary_len; 16982c93a87SJiri Pirko bool fail_recover; 17082c93a87SJiri Pirko }; 17182c93a87SJiri Pirko 17282c93a87SJiri Pirko int nsim_dev_health_init(struct nsim_dev *nsim_dev, struct devlink *devlink); 17382c93a87SJiri Pirko void nsim_dev_health_exit(struct nsim_dev *nsim_dev); 17482c93a87SJiri Pirko 1758320d145SJiri Pirko struct nsim_dev_port { 1768320d145SJiri Pirko struct list_head list; 1778320d145SJiri Pirko struct devlink_port devlink_port; 1788320d145SJiri Pirko unsigned int port_index; 1798320d145SJiri Pirko struct dentry *ddir; 180e05b2d14SJiri Pirko struct netdevsim *ns; 1818320d145SJiri Pirko }; 1828320d145SJiri Pirko 183a60f9e48SJiri Pirko struct nsim_dev { 184d514f41eSJiri Pirko struct nsim_bus_dev *nsim_bus_dev; 185a60f9e48SJiri Pirko struct nsim_fib_data *fib_data; 186da58f90fSIdo Schimmel struct nsim_trap_data *trap_data; 187d514f41eSJiri Pirko struct dentry *ddir; 188ab1d0cc0SJiri Pirko struct dentry *ports_ddir; 1898526ad96STaehee Yoo struct dentry *take_snapshot; 190d514f41eSJiri Pirko struct bpf_offload_dev *bpf_dev; 191d514f41eSJiri Pirko bool bpf_bind_accept; 192*e4ff5aa4SToke Høiland-Jørgensen bool bpf_bind_verifier_accept; 193d514f41eSJiri Pirko u32 bpf_bind_verifier_delay; 194d514f41eSJiri Pirko struct dentry *ddir_bpf_bound_progs; 195d514f41eSJiri Pirko u32 prog_id_gen; 196d514f41eSJiri Pirko struct list_head bpf_bound_progs; 197d514f41eSJiri Pirko struct list_head bpf_bound_maps; 198514cf64cSJiri Pirko struct netdev_phys_item_id switch_id; 1998320d145SJiri Pirko struct list_head port_list; 200794b2c05SJiri Pirko struct mutex port_list_lock; /* protects port list */ 201fa4dfc4aSJiri Pirko bool fw_update_status; 202cbb58368SJacob Keller u32 fw_update_overwrite_mask; 203150e8f8aSJiri Pirko u32 max_macs; 204150e8f8aSJiri Pirko bool test1; 205155ddfc5SJiri Pirko bool dont_allow_reload; 206155ddfc5SJiri Pirko bool fail_reload; 2074418f862SJiri Pirko struct devlink_region *dummy_region; 20882c93a87SJiri Pirko struct nsim_dev_health health; 209d3cbb907SJiri Pirko struct flow_action_cookie *fa_cookie; 210d3cbb907SJiri Pirko spinlock_t fa_cookie_lock; /* protects fa_cookie */ 2110dc8249aSIdo Schimmel bool fail_trap_group_set; 212ad188458SIdo Schimmel bool fail_trap_policer_set; 213ad188458SIdo Schimmel bool fail_trap_policer_counter_get; 214424be63aSJakub Kicinski struct { 215dc9c0753SJakub Kicinski struct udp_tunnel_nic_shared utn_shared; 216dc9c0753SJakub Kicinski u32 __ports[2][NSIM_UDP_TUNNEL_N_PORTS]; 217424be63aSJakub Kicinski bool sync_all; 218424be63aSJakub Kicinski bool open_only; 219424be63aSJakub Kicinski bool ipv4_only; 220dc9c0753SJakub Kicinski bool shared; 221dda75173SJakub Kicinski bool static_iana_vxlan; 222424be63aSJakub Kicinski u32 sleep; 223424be63aSJakub Kicinski } udp_ports; 224a60f9e48SJiri Pirko }; 225a60f9e48SJiri Pirko 22690d29913SJiri Pirko static inline struct net *nsim_dev_net(struct nsim_dev *nsim_dev) 22790d29913SJiri Pirko { 22890d29913SJiri Pirko return devlink_net(priv_to_devlink(nsim_dev)); 22990d29913SJiri Pirko } 23090d29913SJiri Pirko 231d514f41eSJiri Pirko int nsim_dev_init(void); 232d514f41eSJiri Pirko void nsim_dev_exit(void); 2338320d145SJiri Pirko int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev); 2348320d145SJiri Pirko void nsim_dev_remove(struct nsim_bus_dev *nsim_bus_dev); 235794b2c05SJiri Pirko int nsim_dev_port_add(struct nsim_bus_dev *nsim_bus_dev, 236794b2c05SJiri Pirko unsigned int port_index); 237794b2c05SJiri Pirko int nsim_dev_port_del(struct nsim_bus_dev *nsim_bus_dev, 238794b2c05SJiri Pirko unsigned int port_index); 23937923ed6SDavid Ahern 24075ba029fSJiri Pirko struct nsim_fib_data *nsim_fib_create(struct devlink *devlink, 24175ba029fSJiri Pirko struct netlink_ext_ack *extack); 24275ba029fSJiri Pirko void nsim_fib_destroy(struct devlink *devlink, struct nsim_fib_data *fib_data); 243a5facc4cSJiri Pirko u64 nsim_fib_get_val(struct nsim_fib_data *fib_data, 244a5facc4cSJiri Pirko enum nsim_resource_id res_id, bool max); 24537923ed6SDavid Ahern 2467699353dSShannon Nelson #if IS_ENABLED(CONFIG_XFRM_OFFLOAD) 2477699353dSShannon Nelson void nsim_ipsec_init(struct netdevsim *ns); 2487699353dSShannon Nelson void nsim_ipsec_teardown(struct netdevsim *ns); 2497699353dSShannon Nelson bool nsim_ipsec_tx(struct netdevsim *ns, struct sk_buff *skb); 2507699353dSShannon Nelson #else 2517699353dSShannon Nelson static inline void nsim_ipsec_init(struct netdevsim *ns) 2527699353dSShannon Nelson { 2537699353dSShannon Nelson } 2547699353dSShannon Nelson 2557699353dSShannon Nelson static inline void nsim_ipsec_teardown(struct netdevsim *ns) 2567699353dSShannon Nelson { 2577699353dSShannon Nelson } 2587699353dSShannon Nelson 2597699353dSShannon Nelson static inline bool nsim_ipsec_tx(struct netdevsim *ns, struct sk_buff *skb) 2607699353dSShannon Nelson { 2617699353dSShannon Nelson return true; 2627699353dSShannon Nelson } 2637699353dSShannon Nelson #endif 2647699353dSShannon Nelson 26540e4fe4cSJiri Pirko struct nsim_vf_config { 26640e4fe4cSJiri Pirko int link_state; 26740e4fe4cSJiri Pirko u16 min_tx_rate; 26840e4fe4cSJiri Pirko u16 max_tx_rate; 26940e4fe4cSJiri Pirko u16 vlan; 27040e4fe4cSJiri Pirko __be16 vlan_proto; 27140e4fe4cSJiri Pirko u16 qos; 27240e4fe4cSJiri Pirko u8 vf_mac[ETH_ALEN]; 27340e4fe4cSJiri Pirko bool spoofchk_enabled; 27440e4fe4cSJiri Pirko bool trusted; 27540e4fe4cSJiri Pirko bool rss_query_enabled; 27640e4fe4cSJiri Pirko }; 277925f5afeSJiri Pirko 27840e4fe4cSJiri Pirko struct nsim_bus_dev { 27940e4fe4cSJiri Pirko struct device dev; 280f9d9db47SJiri Pirko struct list_head list; 281f9d9db47SJiri Pirko unsigned int port_count; 2827b60027bSJiri Pirko struct net *initial_net; /* Purpose of this is to carry net pointer 2837b60027bSJiri Pirko * during the probe time only. 2847b60027bSJiri Pirko */ 28540e4fe4cSJiri Pirko unsigned int num_vfs; 28640e4fe4cSJiri Pirko struct nsim_vf_config *vfconfigs; 2876ab63366STaehee Yoo /* Lock for devlink->reload_enabled in netdevsim module */ 2886ab63366STaehee Yoo struct mutex nsim_bus_reload_lock; 289f5cd2160STaehee Yoo bool init; 29040e4fe4cSJiri Pirko }; 291925f5afeSJiri Pirko 292925f5afeSJiri Pirko int nsim_bus_init(void); 293925f5afeSJiri Pirko void nsim_bus_exit(void); 294