diff options
Diffstat (limited to 'drivers/net/netdevsim')
| -rw-r--r-- | drivers/net/netdevsim/bpf.c | 11 | ||||
| -rw-r--r-- | drivers/net/netdevsim/bus.c | 7 | ||||
| -rw-r--r-- | drivers/net/netdevsim/ethtool.c | 53 | ||||
| -rw-r--r-- | drivers/net/netdevsim/ipsec.c | 10 | ||||
| -rw-r--r-- | drivers/net/netdevsim/netdev.c | 10 | ||||
| -rw-r--r-- | drivers/net/netdevsim/netdevsim.h | 8 | ||||
| -rw-r--r-- | drivers/net/netdevsim/psp.c | 33 |
7 files changed, 87 insertions, 45 deletions
diff --git a/drivers/net/netdevsim/bpf.c b/drivers/net/netdevsim/bpf.c index 16aa88278398..f45c1c8f0584 100644 --- a/drivers/net/netdevsim/bpf.c +++ b/drivers/net/netdevsim/bpf.c @@ -144,6 +144,17 @@ int nsim_bpf_setup_tc_block_cb(enum tc_setup_type type, return -EOPNOTSUPP; } + /* A dev-bound program can be replayed here when a netdev joins + * a shared block, after the core attach-time check has run; + * enforce the device match as nfp does. + */ + if (prog && bpf_prog_is_dev_bound(prog->aux) && + !bpf_offload_dev_match(prog, ns->netdev)) { + NSIM_EA(cls_bpf->common.extack, + "program bound to a different device"); + return -EINVAL; + } + if (cls_bpf->command != TC_CLSBPF_OFFLOAD) return -EOPNOTSUPP; diff --git a/drivers/net/netdevsim/bus.c b/drivers/net/netdevsim/bus.c index 5c55c308487b..b792ee10b1c1 100644 --- a/drivers/net/netdevsim/bus.c +++ b/drivers/net/netdevsim/bus.c @@ -194,7 +194,6 @@ new_device_store(const struct bus_type *bus, const char *buf, size_t count) goto err; } - refcount_inc(&nsim_bus_devs); /* Allow using nsim_bus_dev */ smp_store_release(&nsim_bus_dev->init, true); @@ -465,6 +464,7 @@ nsim_bus_dev_new(unsigned int id, unsigned int port_count, unsigned int num_queu /* Disallow using nsim_bus_dev */ smp_store_release(&nsim_bus_dev->init, false); + refcount_inc(&nsim_bus_devs); err = device_register(&nsim_bus_dev->dev); if (err) goto err_nsim_bus_dev_id_free; @@ -520,8 +520,6 @@ void nsim_bus_exit(void) /* Disallow using resources */ smp_store_release(&nsim_bus_enable, false); - if (refcount_dec_and_test(&nsim_bus_devs)) - complete(&nsim_bus_devs_released); mutex_lock(&nsim_bus_dev_list_lock); list_for_each_entry_safe(nsim_bus_dev, tmp, &nsim_bus_dev_list, list) { @@ -530,6 +528,9 @@ void nsim_bus_exit(void) } mutex_unlock(&nsim_bus_dev_list_lock); + if (refcount_dec_and_test(&nsim_bus_devs)) + complete(&nsim_bus_devs_released); + wait_for_completion(&nsim_bus_devs_released); driver_unregister(&nsim_driver); diff --git a/drivers/net/netdevsim/ethtool.c b/drivers/net/netdevsim/ethtool.c index 025ea79879f3..c3d2bc783d55 100644 --- a/drivers/net/netdevsim/ethtool.c +++ b/drivers/net/netdevsim/ethtool.c @@ -205,7 +205,59 @@ static int nsim_get_ts_info(struct net_device *dev, return 0; } +static u32 nsim_get_rxfh_key_size(struct net_device *dev) +{ + return NETDEV_RSS_KEY_LEN; +} + +static u32 nsim_get_rxfh_indir_size(struct net_device *dev) +{ + return NSIM_RSS_INDIR_SIZE; +} + +static int nsim_get_rxfh(struct net_device *dev, + struct ethtool_rxfh_param *rxfh) +{ + struct netdevsim *ns = netdev_priv(dev); + u32 i; + + rxfh->hfunc = ETH_RSS_HASH_TOP; + if (rxfh->indir) { + for (i = 0; i < NSIM_RSS_INDIR_SIZE; i++) + rxfh->indir[i] = ethtool_rxfh_indir_default(i, ns->ethtool.channels); + } + if (rxfh->key) + memcpy(rxfh->key, ns->ethtool.rss_key, + sizeof(ns->ethtool.rss_key)); + + return 0; +} + +static int nsim_get_rxfh_fields(struct net_device *dev, + struct ethtool_rxfh_fields *info) +{ + switch (info->flow_type) { + case TCP_V4_FLOW: + case UDP_V4_FLOW: + case TCP_V6_FLOW: + case UDP_V6_FLOW: + info->data = RXH_IP_SRC | RXH_IP_DST | + RXH_L4_B_0_1 | RXH_L4_B_2_3; + return 0; + case IPV4_FLOW: + case IPV6_FLOW: + info->data = RXH_IP_SRC | RXH_IP_DST; + return 0; + default: + return -EOPNOTSUPP; + } +} + static const struct ethtool_ops nsim_ethtool_ops = { + .get_rxfh_key_size = nsim_get_rxfh_key_size, + .get_rxfh_indir_size = nsim_get_rxfh_indir_size, + .get_rxfh = nsim_get_rxfh, + .get_rxfh_fields = nsim_get_rxfh_fields, .supported_coalesce_params = ETHTOOL_COALESCE_ALL_PARAMS, .supported_ring_params = ETHTOOL_RING_USE_TCP_DATA_SPLIT | ETHTOOL_RING_USE_HDS_THRS, @@ -250,6 +302,7 @@ void nsim_ethtool_init(struct netdevsim *ns) ns->ethtool.fec.active_fec = ETHTOOL_FEC_NONE; ns->ethtool.channels = ns->nsim_bus_dev->num_queues; + netdev_rss_key_fill(ns->ethtool.rss_key, sizeof(ns->ethtool.rss_key)); ethtool = debugfs_create_dir("ethtool", ns->nsim_dev_port->ddir); ns->ethtool_ddir = ethtool; diff --git a/drivers/net/netdevsim/ipsec.c b/drivers/net/netdevsim/ipsec.c index 36a1be4923d6..5722837bcda3 100644 --- a/drivers/net/netdevsim/ipsec.c +++ b/drivers/net/netdevsim/ipsec.c @@ -50,11 +50,11 @@ static ssize_t nsim_dbg_netdev_ops_read(struct file *filp, p += scnprintf(p, bufsize - (p - buf), "sa[%i] spi=0x%08x proto=0x%x salt=0x%08x crypt=%d\n", i, be32_to_cpu(sap->xs->id.spi), - sap->xs->id.proto, sap->salt, sap->crypt); + sap->xs->id.proto, be32_to_cpu(sap->salt), sap->crypt); p += scnprintf(p, bufsize - (p - buf), "sa[%i] key=0x%08x %08x %08x %08x\n", - i, sap->key[0], sap->key[1], - sap->key[2], sap->key[3]); + i, be32_to_cpu(sap->key[0]), be32_to_cpu(sap->key[1]), + be32_to_cpu(sap->key[2]), be32_to_cpu(sap->key[3])); } len = simple_read_from_buffer(buffer, count, ppos, buf, p - buf); @@ -87,7 +87,7 @@ static int nsim_ipsec_find_empty_idx(struct nsim_ipsec *ipsec) static int nsim_ipsec_parse_proto_keys(struct net_device *dev, struct xfrm_state *xs, - u32 *mykey, u32 *mysalt) + __be32 *mykey, __be32 *mysalt) { const char aes_gcm_name[] = "rfc4106(gcm(aes))"; unsigned char *key_data; @@ -117,7 +117,7 @@ static int nsim_ipsec_parse_proto_keys(struct net_device *dev, /* 160 accounts for 16 byte key and 4 byte salt */ if (key_len > NSIM_IPSEC_AUTH_BITS) { - *mysalt = ((u32 *)key_data)[4]; + *mysalt = ((__be32 *)key_data)[4]; } else if (key_len == NSIM_IPSEC_AUTH_BITS) { *mysalt = 0; } else { diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c index b4a99f3ceac6..eebc02ccc4a9 100644 --- a/drivers/net/netdevsim/netdev.c +++ b/drivers/net/netdevsim/netdev.c @@ -185,6 +185,14 @@ out_drop_cnt: return NETDEV_TX_OK; } +static netdev_tx_t nsim_start_xmit_vf(struct sk_buff *skb, + struct net_device *dev) +{ + dev_dstats_tx_dropped(dev); + kfree_skb(skb); + return NETDEV_TX_OK; +} + static int nsim_set_rx_mode(struct net_device *dev, struct netdev_hw_addr_list *uc, struct netdev_hw_addr_list *mc) @@ -651,7 +659,7 @@ static const struct net_device_ops nsim_netdev_ops = { }; static const struct net_device_ops nsim_vf_netdev_ops = { - .ndo_start_xmit = nsim_start_xmit, + .ndo_start_xmit = nsim_start_xmit_vf, .ndo_set_rx_mode_async = nsim_set_rx_mode, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h index 55aec41237b9..fd5599cd3bb9 100644 --- a/drivers/net/netdevsim/netdevsim.h +++ b/drivers/net/netdevsim/netdevsim.h @@ -42,8 +42,8 @@ struct nsim_sa { struct xfrm_state *xs; __be32 ipaddr[4]; - u32 key[4]; - u32 salt; + __be32 key[4]; + __be32 salt; bool used; bool crypt; bool rx; @@ -87,10 +87,13 @@ struct nsim_ethtool_pauseparam { bool report_stats_tx; }; +#define NSIM_RSS_INDIR_SIZE 128 + struct nsim_ethtool { u32 get_err; u32 set_err; u32 channels; + u8 rss_key[NETDEV_RSS_KEY_LEN]; struct nsim_ethtool_pauseparam pauseparam; struct ethtool_coalesce coalesce; struct ethtool_ringparam ring; @@ -122,7 +125,6 @@ struct netdevsim { struct dentry *rereg; struct mutex rereg_lock; u32 spi; - u32 assoc_cnt; } psp; struct nsim_bus_dev *nsim_bus_dev; diff --git a/drivers/net/netdevsim/psp.c b/drivers/net/netdevsim/psp.c index 6b3532b5e360..b7452c49b581 100644 --- a/drivers/net/netdevsim/psp.c +++ b/drivers/net/netdevsim/psp.c @@ -23,7 +23,6 @@ nsim_do_psp(struct sk_buff *skb, struct netdevsim *ns, struct psp_assoc *pas; struct net *net; int psp_len; - void **ptr; rcu_read_lock(); pas = psp_skb_get_assoc_rcu(skb); @@ -37,12 +36,6 @@ nsim_do_psp(struct sk_buff *skb, struct netdevsim *ns, goto out_unlock; } - ptr = psp_assoc_drv_data(pas); - if (*ptr != ns) { - rc = SKB_DROP_REASON_PSP_OUTPUT; - goto out_unlock; - } - net = sock_net(skb->sk); if (!psp_dev_encapsulate(net, skb, pas->tx.spi, pas->version, 0)) { rc = SKB_DROP_REASON_PSP_OUTPUT; @@ -149,19 +142,6 @@ nsim_rx_spi_alloc(struct psp_dev *psd, u32 version, return 0; } -static int nsim_assoc_add(struct psp_dev *psd, struct psp_assoc *pas, - struct netlink_ext_ack *extack) -{ - struct netdevsim *ns = psd->drv_priv; - void **ptr = psp_assoc_drv_data(pas); - - /* Copy drv_priv from psd to assoc */ - *ptr = psd->drv_priv; - ns->psp.assoc_cnt++; - - return 0; -} - static int nsim_key_rotate(struct psp_dev *psd, struct netlink_ext_ack *extack) { struct netdevsim *ns = psd->drv_priv; @@ -177,15 +157,6 @@ static int nsim_key_rotate(struct psp_dev *psd, struct netlink_ext_ack *extack) return 0; } -static void nsim_assoc_del(struct psp_dev *psd, struct psp_assoc *pas) -{ - struct netdevsim *ns = psd->drv_priv; - void **ptr = psp_assoc_drv_data(pas); - - *ptr = NULL; - ns->psp.assoc_cnt--; -} - static void nsim_get_stats(struct psp_dev *psd, struct psp_dev_stats *stats) { struct netdevsim *ns = psd->drv_priv; @@ -204,8 +175,6 @@ static void nsim_get_stats(struct psp_dev *psd, struct psp_dev_stats *stats) static struct psp_dev_ops nsim_psp_ops = { .set_config = nsim_psp_set_config, .rx_spi_alloc = nsim_rx_spi_alloc, - .tx_key_add = nsim_assoc_add, - .tx_key_del = nsim_assoc_del, .key_rotate = nsim_key_rotate, .get_stats = nsim_get_stats, }; @@ -215,7 +184,6 @@ static struct psp_dev_caps nsim_psp_caps = { 1 << PSP_VERSION_HDR0_AES_GMAC_128 | 1 << PSP_VERSION_HDR0_AES_GCM_256 | 1 << PSP_VERSION_HDR0_AES_GMAC_256, - .assoc_drv_spc = sizeof(void *), }; static void __nsim_psp_uninit(struct netdevsim *ns, bool teardown) @@ -230,7 +198,6 @@ static void __nsim_psp_uninit(struct netdevsim *ns, bool teardown) synchronize_rcu(); psp_dev_unregister(psd); } - WARN_ON(ns->psp.assoc_cnt); } void nsim_psp_uninit(struct netdevsim *ns) |
