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: Greg Rose <gregory.v.rose@intel.com>
Signed-off-by: Catherine Sullivan <catherine.sullivan@intel.com>
Tested-by: Kavindya Deegala <kavindya.s.deegala@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
Greg Rose 2014-03-06 08:59:55 +00:00 committed by Jeff Kirsher
parent 5a9d19ab76
commit 4ba0dea5b1
1 changed files with 97 additions and 0 deletions

View File

@ -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
};
/**