forked from mirrors/linux
		
	netdevsim: add software driver for testing offloads
To be able to run selftests without any hardware required we need a software model. The model can also serve as an example implementation for those implementing actual HW offloads. The dummy driver have previously been extended to test SR-IOV, but the general consensus seems to be against adding further features to it. Add a new driver for purposes of software modelling only. eBPF and SR-IOV will be added here shortly, others are invited to further extend the driver with their offload models. Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> Reviewed-by: Simon Horman <simon.horman@netronome.com> Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
This commit is contained in:
		
							parent
							
								
									bd0b2e7fe6
								
							
						
					
					
						commit
						83c9e13aa3
					
				
					 6 changed files with 167 additions and 0 deletions
				
			
		| 
						 | 
					@ -9599,6 +9599,11 @@ NETWORKING [WIRELESS]
 | 
				
			||||||
L:	linux-wireless@vger.kernel.org
 | 
					L:	linux-wireless@vger.kernel.org
 | 
				
			||||||
Q:	http://patchwork.kernel.org/project/linux-wireless/list/
 | 
					Q:	http://patchwork.kernel.org/project/linux-wireless/list/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NETDEVSIM
 | 
				
			||||||
 | 
					M:	Jakub Kicinski <jakub.kicinski@netronome.com>
 | 
				
			||||||
 | 
					S:	Maintained
 | 
				
			||||||
 | 
					F:	drivers/net/netdevsim/*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NETXEN (1/10) GbE SUPPORT
 | 
					NETXEN (1/10) GbE SUPPORT
 | 
				
			||||||
M:	Manish Chopra <manish.chopra@cavium.com>
 | 
					M:	Manish Chopra <manish.chopra@cavium.com>
 | 
				
			||||||
M:	Rahul Verma <rahul.verma@cavium.com>
 | 
					M:	Rahul Verma <rahul.verma@cavium.com>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -497,4 +497,15 @@ config THUNDERBOLT_NET
 | 
				
			||||||
 | 
					
 | 
				
			||||||
source "drivers/net/hyperv/Kconfig"
 | 
					source "drivers/net/hyperv/Kconfig"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config NETDEVSIM
 | 
				
			||||||
 | 
						tristate "Simulated networking device"
 | 
				
			||||||
 | 
						depends on DEBUG_FS
 | 
				
			||||||
 | 
						help
 | 
				
			||||||
 | 
						  This driver is a developer testing tool and software model that can
 | 
				
			||||||
 | 
						  be used to test various control path networking APIs, especially
 | 
				
			||||||
 | 
						  HW-offload related.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  To compile this driver as a module, choose M here: the module
 | 
				
			||||||
 | 
						  will be called netdevsim.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
endif # NETDEVICES
 | 
					endif # NETDEVICES
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -78,3 +78,4 @@ obj-$(CONFIG_FUJITSU_ES) += fjes/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
thunderbolt-net-y += thunderbolt.o
 | 
					thunderbolt-net-y += thunderbolt.o
 | 
				
			||||||
obj-$(CONFIG_THUNDERBOLT_NET) += thunderbolt-net.o
 | 
					obj-$(CONFIG_THUNDERBOLT_NET) += thunderbolt-net.o
 | 
				
			||||||
 | 
					obj-$(CONFIG_NETDEVSIM) += netdevsim/
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										6
									
								
								drivers/net/netdevsim/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								drivers/net/netdevsim/Makefile
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,6 @@
 | 
				
			||||||
 | 
					# SPDX-License-Identifier: GPL-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					obj-$(CONFIG_NETDEVSIM) += netdevsim.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					netdevsim-objs := \
 | 
				
			||||||
 | 
						netdev.o \
 | 
				
			||||||
							
								
								
									
										118
									
								
								drivers/net/netdevsim/netdev.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								drivers/net/netdevsim/netdev.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,118 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <linux/etherdevice.h>
 | 
				
			||||||
 | 
					#include <linux/kernel.h>
 | 
				
			||||||
 | 
					#include <linux/module.h>
 | 
				
			||||||
 | 
					#include <linux/netdevice.h>
 | 
				
			||||||
 | 
					#include <linux/slab.h>
 | 
				
			||||||
 | 
					#include <net/netlink.h>
 | 
				
			||||||
 | 
					#include <net/rtnetlink.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "netdevsim.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static netdev_tx_t nsim_start_xmit(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct netdevsim *ns = netdev_priv(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u64_stats_update_begin(&ns->syncp);
 | 
				
			||||||
 | 
						ns->tx_packets++;
 | 
				
			||||||
 | 
						ns->tx_bytes += skb->len;
 | 
				
			||||||
 | 
						u64_stats_update_end(&ns->syncp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dev_kfree_skb(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return NETDEV_TX_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void nsim_set_rx_mode(struct net_device *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					nsim_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct netdevsim *ns = netdev_priv(dev);
 | 
				
			||||||
 | 
						unsigned int start;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						do {
 | 
				
			||||||
 | 
							start = u64_stats_fetch_begin(&ns->syncp);
 | 
				
			||||||
 | 
							stats->tx_bytes = ns->tx_bytes;
 | 
				
			||||||
 | 
							stats->tx_packets = ns->tx_packets;
 | 
				
			||||||
 | 
						} while (u64_stats_fetch_retry(&ns->syncp, start));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct net_device_ops nsim_netdev_ops = {
 | 
				
			||||||
 | 
						.ndo_start_xmit		= nsim_start_xmit,
 | 
				
			||||||
 | 
						.ndo_set_rx_mode	= nsim_set_rx_mode,
 | 
				
			||||||
 | 
						.ndo_set_mac_address	= eth_mac_addr,
 | 
				
			||||||
 | 
						.ndo_validate_addr	= eth_validate_addr,
 | 
				
			||||||
 | 
						.ndo_get_stats64	= nsim_get_stats64,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void nsim_setup(struct net_device *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						ether_setup(dev);
 | 
				
			||||||
 | 
						eth_hw_addr_random(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dev->netdev_ops = &nsim_netdev_ops;
 | 
				
			||||||
 | 
						dev->needs_free_netdev = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dev->tx_queue_len = 0;
 | 
				
			||||||
 | 
						dev->flags |= IFF_NOARP;
 | 
				
			||||||
 | 
						dev->flags &= ~IFF_MULTICAST;
 | 
				
			||||||
 | 
						dev->priv_flags |= IFF_LIVE_ADDR_CHANGE |
 | 
				
			||||||
 | 
								   IFF_NO_QUEUE;
 | 
				
			||||||
 | 
						dev->features |= NETIF_F_HIGHDMA |
 | 
				
			||||||
 | 
								 NETIF_F_SG |
 | 
				
			||||||
 | 
								 NETIF_F_FRAGLIST |
 | 
				
			||||||
 | 
								 NETIF_F_HW_CSUM |
 | 
				
			||||||
 | 
								 NETIF_F_TSO;
 | 
				
			||||||
 | 
						dev->max_mtu = ETH_MAX_MTU;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int nsim_validate(struct nlattr *tb[], struct nlattr *data[],
 | 
				
			||||||
 | 
								 struct netlink_ext_ack *extack)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (tb[IFLA_ADDRESS]) {
 | 
				
			||||||
 | 
							if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
 | 
				
			||||||
 | 
								return -EINVAL;
 | 
				
			||||||
 | 
							if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
 | 
				
			||||||
 | 
								return -EADDRNOTAVAIL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct rtnl_link_ops nsim_link_ops __read_mostly = {
 | 
				
			||||||
 | 
						.kind		= DRV_NAME,
 | 
				
			||||||
 | 
						.priv_size	= sizeof(struct netdevsim),
 | 
				
			||||||
 | 
						.setup		= nsim_setup,
 | 
				
			||||||
 | 
						.validate	= nsim_validate,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int __init nsim_module_init(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return rtnl_link_register(&nsim_link_ops);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void __exit nsim_module_exit(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						rtnl_link_unregister(&nsim_link_ops);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module_init(nsim_module_init);
 | 
				
			||||||
 | 
					module_exit(nsim_module_exit);
 | 
				
			||||||
 | 
					MODULE_LICENSE("GPL");
 | 
				
			||||||
 | 
					MODULE_ALIAS_RTNL_LINK(DRV_NAME);
 | 
				
			||||||
							
								
								
									
										26
									
								
								drivers/net/netdevsim/netdevsim.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								drivers/net/netdevsim/netdevsim.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,26 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <linux/kernel.h>
 | 
				
			||||||
 | 
					#include <linux/netdevice.h>
 | 
				
			||||||
 | 
					#include <linux/u64_stats_sync.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DRV_NAME	"netdevsim"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct netdevsim {
 | 
				
			||||||
 | 
						u64 tx_packets;
 | 
				
			||||||
 | 
						u64 tx_bytes;
 | 
				
			||||||
 | 
						struct u64_stats_sync syncp;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
		Loading…
	
		Reference in a new issue