Add support for storing the list of VLANs in nsim devices, together with ops for adding/removing them and a debug file to show them. This will be used in upcoming tests. Signed-off-by: Cosmin Ratiu --- drivers/net/netdevsim/netdev.c | 59 +++++++++++++++++++++++++++++-- drivers/net/netdevsim/netdevsim.h | 8 +++++ 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c index 6285fbefe38a..7177711cf9fc 100644 --- a/drivers/net/netdevsim/netdev.c +++ b/drivers/net/netdevsim/netdev.c @@ -602,6 +602,36 @@ static int nsim_stop(struct net_device *dev) return 0; } +static int nsim_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid) +{ + struct netdevsim *ns = netdev_priv(dev); + + if (vid >= VLAN_N_VID) + return -EINVAL; + + if (proto == htons(ETH_P_8021Q)) + set_bit(vid, ns->vlan.ctag); + else if (proto == htons(ETH_P_8021AD)) + set_bit(vid, ns->vlan.stag); + + return 0; +} + +static int nsim_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid) +{ + struct netdevsim *ns = netdev_priv(dev); + + if (vid >= VLAN_N_VID) + return -EINVAL; + + if (proto == htons(ETH_P_8021Q)) + clear_bit(vid, ns->vlan.ctag); + else if (proto == htons(ETH_P_8021AD)) + clear_bit(vid, ns->vlan.stag); + + return 0; +} + static int nsim_shaper_set(struct net_shaper_binding *binding, const struct net_shaper *shaper, struct netlink_ext_ack *extack) @@ -659,6 +689,8 @@ static const struct net_device_ops nsim_netdev_ops = { .ndo_bpf = nsim_bpf, .ndo_open = nsim_open, .ndo_stop = nsim_stop, + .ndo_vlan_rx_add_vid = nsim_vlan_rx_add_vid, + .ndo_vlan_rx_kill_vid = nsim_vlan_rx_kill_vid, .net_shaper_ops = &nsim_shaper_ops, }; @@ -670,6 +702,8 @@ static const struct net_device_ops nsim_vf_netdev_ops = { .ndo_change_mtu = nsim_change_mtu, .ndo_setup_tc = nsim_setup_tc, .ndo_set_features = nsim_set_features, + .ndo_vlan_rx_add_vid = nsim_vlan_rx_add_vid, + .ndo_vlan_rx_kill_vid = nsim_vlan_rx_kill_vid, }; /* We don't have true per-queue stats, yet, so do some random fakery here. @@ -967,6 +1001,20 @@ static const struct file_operations nsim_pp_hold_fops = { .owner = THIS_MODULE, }; +static int nsim_vlan_show(struct seq_file *s, void *data) +{ + struct netdevsim *ns = s->private; + int vid; + + for_each_set_bit(vid, ns->vlan.ctag, VLAN_N_VID) + seq_printf(s, "ctag %d\n", vid); + for_each_set_bit(vid, ns->vlan.stag, VLAN_N_VID) + seq_printf(s, "stag %d\n", vid); + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(nsim_vlan); + static void nsim_setup(struct net_device *dev) { ether_setup(dev); @@ -979,14 +1027,18 @@ static void nsim_setup(struct net_device *dev) NETIF_F_FRAGLIST | NETIF_F_HW_CSUM | NETIF_F_LRO | - NETIF_F_TSO; + NETIF_F_TSO | + NETIF_F_HW_VLAN_CTAG_FILTER | + NETIF_F_HW_VLAN_STAG_FILTER; dev->hw_features |= NETIF_F_HW_TC | NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HW_CSUM | NETIF_F_LRO | NETIF_F_TSO | - NETIF_F_LOOPBACK; + NETIF_F_LOOPBACK | + NETIF_F_HW_VLAN_CTAG_FILTER | + NETIF_F_HW_VLAN_STAG_FILTER; dev->pcpu_stat_type = NETDEV_PCPU_STAT_DSTATS; dev->max_mtu = ETH_MAX_MTU; dev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_HW_OFFLOAD; @@ -1154,6 +1206,8 @@ struct netdevsim *nsim_create(struct nsim_dev *nsim_dev, ns->qr_dfs = debugfs_create_file("queue_reset", 0200, nsim_dev_port->ddir, ns, &nsim_qreset_fops); + ns->vlan_dfs = debugfs_create_file("vlan", 0400, nsim_dev_port->ddir, + ns, &nsim_vlan_fops); return ns; err_free_netdev: @@ -1166,6 +1220,7 @@ void nsim_destroy(struct netdevsim *ns) struct net_device *dev = ns->netdev; struct netdevsim *peer; + debugfs_remove(ns->vlan_dfs); debugfs_remove(ns->qr_dfs); debugfs_remove(ns->pp_dfs); diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h index f767fc8a7505..f844c27ca78b 100644 --- a/drivers/net/netdevsim/netdevsim.h +++ b/drivers/net/netdevsim/netdevsim.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -75,6 +76,11 @@ struct nsim_macsec { u8 nsim_secy_count; }; +struct nsim_vlan { + DECLARE_BITMAP(ctag, VLAN_N_VID); + DECLARE_BITMAP(stag, VLAN_N_VID); +}; + struct nsim_ethtool_pauseparam { bool rx; bool tx; @@ -135,6 +141,7 @@ struct netdevsim { bool bpf_map_accept; struct nsim_ipsec ipsec; struct nsim_macsec macsec; + struct nsim_vlan vlan; struct { u32 inject_error; u32 __ports[2][NSIM_UDP_TUNNEL_N_PORTS]; @@ -146,6 +153,7 @@ struct netdevsim { struct page *page; struct dentry *pp_dfs; struct dentry *qr_dfs; + struct dentry *vlan_dfs; struct nsim_ethtool ethtool; struct netdevsim __rcu *peer; -- 2.49.0