Skip to content

Commit

Permalink
net/mlx4: Spoofcheck and zero MAC can't coexist
Browse files Browse the repository at this point in the history
Spoofcheck can't be enabled if VF MAC is zero.
Vice versa, can't zero MAC if spoofcheck is on.

Fixes: 8f7ba3c ('net/mlx4: Add set VF mac address support')
Signed-off-by: Eugenia Emantayev <eugenia@mellanox.com>
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Eugenia Emantayev authored and David S. Miller committed Feb 23, 2017
1 parent 423b3ae commit 745d8ae
Showing 4 changed files with 32 additions and 8 deletions.
22 changes: 20 additions & 2 deletions drivers/net/ethernet/mellanox/mlx4/cmd.c
Original file line number Diff line number Diff line change
@@ -43,6 +43,7 @@
#include <linux/semaphore.h>
#include <rdma/ib_smi.h>
#include <linux/delay.h>
#include <linux/etherdevice.h>

#include <asm/io.h>

@@ -2955,7 +2956,7 @@ static bool mlx4_valid_vf_state_change(struct mlx4_dev *dev, int port,
return false;
}

int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac)
int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u8 *mac)
{
struct mlx4_priv *priv = mlx4_priv(dev);
struct mlx4_vport_state *s_info;
@@ -2964,13 +2965,22 @@ int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac)
if (!mlx4_is_master(dev))
return -EPROTONOSUPPORT;

if (is_multicast_ether_addr(mac))
return -EINVAL;

slave = mlx4_get_slave_indx(dev, vf);
if (slave < 0)
return -EINVAL;

port = mlx4_slaves_closest_port(dev, slave, port);
s_info = &priv->mfunc.master.vf_admin[slave].vport[port];
s_info->mac = mac;

if (s_info->spoofchk && is_zero_ether_addr(mac)) {
mlx4_info(dev, "MAC invalidation is not allowed when spoofchk is on\n");
return -EPERM;
}

s_info->mac = mlx4_mac_to_u64(mac);
mlx4_info(dev, "default mac on vf %d port %d to %llX will take effect only after vf restart\n",
vf, port, s_info->mac);
return 0;
@@ -3143,6 +3153,7 @@ int mlx4_set_vf_spoofchk(struct mlx4_dev *dev, int port, int vf, bool setting)
struct mlx4_priv *priv = mlx4_priv(dev);
struct mlx4_vport_state *s_info;
int slave;
u8 mac[ETH_ALEN];

if ((!mlx4_is_master(dev)) ||
!(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_FSM))
@@ -3154,6 +3165,13 @@ int mlx4_set_vf_spoofchk(struct mlx4_dev *dev, int port, int vf, bool setting)

port = mlx4_slaves_closest_port(dev, slave, port);
s_info = &priv->mfunc.master.vf_admin[slave].vport[port];

mlx4_u64_to_mac(mac, s_info->mac);
if (setting && !is_valid_ether_addr(mac)) {
mlx4_info(dev, "Illegal MAC with spoofchk\n");
return -EPERM;
}

s_info->spoofchk = setting;

return 0;
6 changes: 1 addition & 5 deletions drivers/net/ethernet/mellanox/mlx4/en_netdev.c
Original file line number Diff line number Diff line change
@@ -2485,12 +2485,8 @@ static int mlx4_en_set_vf_mac(struct net_device *dev, int queue, u8 *mac)
{
struct mlx4_en_priv *en_priv = netdev_priv(dev);
struct mlx4_en_dev *mdev = en_priv->mdev;
u64 mac_u64 = mlx4_mac_to_u64(mac);

if (is_multicast_ether_addr(mac))
return -EINVAL;

return mlx4_set_vf_mac(mdev->dev, en_priv->port, queue, mac_u64);
return mlx4_set_vf_mac(mdev->dev, en_priv->port, queue, mac);
}

static int mlx4_en_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos,
2 changes: 1 addition & 1 deletion include/linux/mlx4/cmd.h
Original file line number Diff line number Diff line change
@@ -308,7 +308,7 @@ int mlx4_get_counter_stats(struct mlx4_dev *dev, int counter_index,
int mlx4_get_vf_stats(struct mlx4_dev *dev, int port, int vf_idx,
struct ifla_vf_stats *vf_stats);
u32 mlx4_comm_get_version(void);
int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac);
int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u8 *mac);
int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan,
u8 qos, __be16 proto);
int mlx4_set_vf_rate(struct mlx4_dev *dev, int port, int vf, int min_tx_rate,
10 changes: 10 additions & 0 deletions include/linux/mlx4/driver.h
Original file line number Diff line number Diff line change
@@ -104,4 +104,14 @@ static inline u64 mlx4_mac_to_u64(u8 *addr)
return mac;
}

static inline void mlx4_u64_to_mac(u8 *addr, u64 mac)
{
int i;

for (i = ETH_ALEN; i > 0; i--) {
addr[i - 1] = mac && 0xFF;
mac >>= 8;
}
}

#endif /* MLX4_DRIVER_H */

0 comments on commit 745d8ae

Please sign in to comment.