Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4ba0dea5 authored by Greg Rose's avatar Greg Rose Committed by Jeff Kirsher
Browse files

i40e: Add bridge FDB add/del/dump ops



Add the netdev ops to support addition of static FDB entries in the
physical function (PF)  MAC/VLAN filter table so that virtual functions
(VFs) can communicate with bridged virtual Ethernet ports such as those
provided by the virtio driver.

Change-ID: Ifbd6817a75074e3b5cdf945a5635f26440bf15df
Signed-off-by: default avatarGreg Rose <gregory.v.rose@intel.com>
Signed-off-by: default avatarCatherine Sullivan <catherine.sullivan@intel.com>
Tested-by: default avatarKavindya Deegala <kavindya.s.deegala@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 5a9d19ab
Loading
Loading
Loading
Loading
+97 −0
Original line number Diff line number Diff line
@@ -6644,6 +6644,96 @@ static void i40e_del_vxlan_port(struct net_device *netdev,
}

#endif
#ifdef HAVE_FDB_OPS
#ifdef USE_CONST_DEV_UC_CHAR
static int i40e_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
			    struct net_device *dev,
			    const unsigned char *addr,
			    u16 flags)
#else
static int i40e_ndo_fdb_add(struct ndmsg *ndm,
			    struct net_device *dev,
			    unsigned char *addr,
			    u16 flags)
#endif
{
	struct i40e_netdev_priv *np = netdev_priv(dev);
	struct i40e_pf *pf = np->vsi->back;
	int err = 0;

	if (!(pf->flags & I40E_FLAG_SRIOV_ENABLED))
		return -EOPNOTSUPP;

	/* Hardware does not support aging addresses so if a
	 * ndm_state is given only allow permanent addresses
	 */
	if (ndm->ndm_state && !(ndm->ndm_state & NUD_PERMANENT)) {
		netdev_info(dev, "FDB only supports static addresses\n");
		return -EINVAL;
	}

	if (is_unicast_ether_addr(addr) || is_link_local_ether_addr(addr))
		err = dev_uc_add_excl(dev, addr);
	else if (is_multicast_ether_addr(addr))
		err = dev_mc_add_excl(dev, addr);
	else
		err = -EINVAL;

	/* Only return duplicate errors if NLM_F_EXCL is set */
	if (err == -EEXIST && !(flags & NLM_F_EXCL))
		err = 0;

	return err;
}

#ifndef USE_DEFAULT_FDB_DEL_DUMP
#ifdef USE_CONST_DEV_UC_CHAR
static int i40e_ndo_fdb_del(struct ndmsg *ndm,
			    struct net_device *dev,
			    const unsigned char *addr)
#else
static int i40e_ndo_fdb_del(struct ndmsg *ndm,
			    struct net_device *dev,
			    unsigned char *addr)
#endif
{
	struct i40e_netdev_priv *np = netdev_priv(dev);
	struct i40e_pf *pf = np->vsi->back;
	int err = -EOPNOTSUPP;

	if (ndm->ndm_state & NUD_PERMANENT) {
		netdev_info(dev, "FDB only supports static addresses\n");
		return -EINVAL;
	}

	if (pf->flags & I40E_FLAG_SRIOV_ENABLED) {
		if (is_unicast_ether_addr(addr))
			err = dev_uc_del(dev, addr);
		else if (is_multicast_ether_addr(addr))
			err = dev_mc_del(dev, addr);
		else
			err = -EINVAL;
	}

	return err;
}

static int i40e_ndo_fdb_dump(struct sk_buff *skb,
			     struct netlink_callback *cb,
			     struct net_device *dev,
			     int idx)
{
	struct i40e_netdev_priv *np = netdev_priv(dev);
	struct i40e_pf *pf = np->vsi->back;

	if (pf->flags & I40E_FLAG_SRIOV_ENABLED)
		idx = ndo_dflt_fdb_dump(skb, cb, dev, idx);

	return idx;
}

#endif /* USE_DEFAULT_FDB_DEL_DUMP */
#endif /* HAVE_FDB_OPS */
static const struct net_device_ops i40e_netdev_ops = {
	.ndo_open		= i40e_open,
	.ndo_stop		= i40e_close,
@@ -6671,6 +6761,13 @@ static const struct net_device_ops i40e_netdev_ops = {
	.ndo_add_vxlan_port	= i40e_add_vxlan_port,
	.ndo_del_vxlan_port	= i40e_del_vxlan_port,
#endif
#ifdef HAVE_FDB_OPS
	.ndo_fdb_add		= i40e_ndo_fdb_add,
#ifndef USE_DEFAULT_FDB_DEL_DUMP
	.ndo_fdb_del		= i40e_ndo_fdb_del,
	.ndo_fdb_dump		= i40e_ndo_fdb_dump,
#endif
#endif
};

/**