diff options
author | Eugenia Emantayev <eugenia@mellanox.com> | 2017-02-23 05:02:42 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-02-23 10:57:56 -0500 |
commit | 745d8ae4622c6808b22e33a944c7decb30074be4 (patch) | |
tree | 56b55f8e44f2678025ad8551d0e8d8e983f31ab1 | |
parent | 423b3aecf29085a52530d4f9167c56a84b081042 (diff) |
net/mlx4: Spoofcheck and zero MAC can't coexist
Spoofcheck can't be enabled if VF MAC is zero.
Vice versa, can't zero MAC if spoofcheck is on.
Fixes: 8f7ba3ca12f6 ('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>
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/cmd.c | 22 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 6 | ||||
-rw-r--r-- | include/linux/mlx4/cmd.h | 2 | ||||
-rw-r--r-- | include/linux/mlx4/driver.h | 10 |
4 files changed, 32 insertions, 8 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index a49072b4fa52..e8c105164931 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/semaphore.h> | 43 | #include <linux/semaphore.h> |
44 | #include <rdma/ib_smi.h> | 44 | #include <rdma/ib_smi.h> |
45 | #include <linux/delay.h> | 45 | #include <linux/delay.h> |
46 | #include <linux/etherdevice.h> | ||
46 | 47 | ||
47 | #include <asm/io.h> | 48 | #include <asm/io.h> |
48 | 49 | ||
@@ -2955,7 +2956,7 @@ static bool mlx4_valid_vf_state_change(struct mlx4_dev *dev, int port, | |||
2955 | return false; | 2956 | return false; |
2956 | } | 2957 | } |
2957 | 2958 | ||
2958 | int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac) | 2959 | int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u8 *mac) |
2959 | { | 2960 | { |
2960 | struct mlx4_priv *priv = mlx4_priv(dev); | 2961 | struct mlx4_priv *priv = mlx4_priv(dev); |
2961 | struct mlx4_vport_state *s_info; | 2962 | 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) | |||
2964 | if (!mlx4_is_master(dev)) | 2965 | if (!mlx4_is_master(dev)) |
2965 | return -EPROTONOSUPPORT; | 2966 | return -EPROTONOSUPPORT; |
2966 | 2967 | ||
2968 | if (is_multicast_ether_addr(mac)) | ||
2969 | return -EINVAL; | ||
2970 | |||
2967 | slave = mlx4_get_slave_indx(dev, vf); | 2971 | slave = mlx4_get_slave_indx(dev, vf); |
2968 | if (slave < 0) | 2972 | if (slave < 0) |
2969 | return -EINVAL; | 2973 | return -EINVAL; |
2970 | 2974 | ||
2971 | port = mlx4_slaves_closest_port(dev, slave, port); | 2975 | port = mlx4_slaves_closest_port(dev, slave, port); |
2972 | s_info = &priv->mfunc.master.vf_admin[slave].vport[port]; | 2976 | s_info = &priv->mfunc.master.vf_admin[slave].vport[port]; |
2973 | s_info->mac = mac; | 2977 | |
2978 | if (s_info->spoofchk && is_zero_ether_addr(mac)) { | ||
2979 | mlx4_info(dev, "MAC invalidation is not allowed when spoofchk is on\n"); | ||
2980 | return -EPERM; | ||
2981 | } | ||
2982 | |||
2983 | s_info->mac = mlx4_mac_to_u64(mac); | ||
2974 | mlx4_info(dev, "default mac on vf %d port %d to %llX will take effect only after vf restart\n", | 2984 | mlx4_info(dev, "default mac on vf %d port %d to %llX will take effect only after vf restart\n", |
2975 | vf, port, s_info->mac); | 2985 | vf, port, s_info->mac); |
2976 | return 0; | 2986 | return 0; |
@@ -3143,6 +3153,7 @@ int mlx4_set_vf_spoofchk(struct mlx4_dev *dev, int port, int vf, bool setting) | |||
3143 | struct mlx4_priv *priv = mlx4_priv(dev); | 3153 | struct mlx4_priv *priv = mlx4_priv(dev); |
3144 | struct mlx4_vport_state *s_info; | 3154 | struct mlx4_vport_state *s_info; |
3145 | int slave; | 3155 | int slave; |
3156 | u8 mac[ETH_ALEN]; | ||
3146 | 3157 | ||
3147 | if ((!mlx4_is_master(dev)) || | 3158 | if ((!mlx4_is_master(dev)) || |
3148 | !(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_FSM)) | 3159 | !(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) | |||
3154 | 3165 | ||
3155 | port = mlx4_slaves_closest_port(dev, slave, port); | 3166 | port = mlx4_slaves_closest_port(dev, slave, port); |
3156 | s_info = &priv->mfunc.master.vf_admin[slave].vport[port]; | 3167 | s_info = &priv->mfunc.master.vf_admin[slave].vport[port]; |
3168 | |||
3169 | mlx4_u64_to_mac(mac, s_info->mac); | ||
3170 | if (setting && !is_valid_ether_addr(mac)) { | ||
3171 | mlx4_info(dev, "Illegal MAC with spoofchk\n"); | ||
3172 | return -EPERM; | ||
3173 | } | ||
3174 | |||
3157 | s_info->spoofchk = setting; | 3175 | s_info->spoofchk = setting; |
3158 | 3176 | ||
3159 | return 0; | 3177 | return 0; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index afe4444e5434..61420473fe5f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c | |||
@@ -2485,12 +2485,8 @@ static int mlx4_en_set_vf_mac(struct net_device *dev, int queue, u8 *mac) | |||
2485 | { | 2485 | { |
2486 | struct mlx4_en_priv *en_priv = netdev_priv(dev); | 2486 | struct mlx4_en_priv *en_priv = netdev_priv(dev); |
2487 | struct mlx4_en_dev *mdev = en_priv->mdev; | 2487 | struct mlx4_en_dev *mdev = en_priv->mdev; |
2488 | u64 mac_u64 = mlx4_mac_to_u64(mac); | ||
2489 | 2488 | ||
2490 | if (is_multicast_ether_addr(mac)) | 2489 | return mlx4_set_vf_mac(mdev->dev, en_priv->port, queue, mac); |
2491 | return -EINVAL; | ||
2492 | |||
2493 | return mlx4_set_vf_mac(mdev->dev, en_priv->port, queue, mac_u64); | ||
2494 | } | 2490 | } |
2495 | 2491 | ||
2496 | static int mlx4_en_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos, | 2492 | static int mlx4_en_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos, |
diff --git a/include/linux/mlx4/cmd.h b/include/linux/mlx4/cmd.h index 1f3568694a57..7b74afcbbab2 100644 --- a/include/linux/mlx4/cmd.h +++ b/include/linux/mlx4/cmd.h | |||
@@ -308,7 +308,7 @@ int mlx4_get_counter_stats(struct mlx4_dev *dev, int counter_index, | |||
308 | int mlx4_get_vf_stats(struct mlx4_dev *dev, int port, int vf_idx, | 308 | int mlx4_get_vf_stats(struct mlx4_dev *dev, int port, int vf_idx, |
309 | struct ifla_vf_stats *vf_stats); | 309 | struct ifla_vf_stats *vf_stats); |
310 | u32 mlx4_comm_get_version(void); | 310 | u32 mlx4_comm_get_version(void); |
311 | int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac); | 311 | int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u8 *mac); |
312 | int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, | 312 | int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, |
313 | u8 qos, __be16 proto); | 313 | u8 qos, __be16 proto); |
314 | int mlx4_set_vf_rate(struct mlx4_dev *dev, int port, int vf, int min_tx_rate, | 314 | int mlx4_set_vf_rate(struct mlx4_dev *dev, int port, int vf, int min_tx_rate, |
diff --git a/include/linux/mlx4/driver.h b/include/linux/mlx4/driver.h index bd0e7075ea6d..e965e5090d96 100644 --- a/include/linux/mlx4/driver.h +++ b/include/linux/mlx4/driver.h | |||
@@ -104,4 +104,14 @@ static inline u64 mlx4_mac_to_u64(u8 *addr) | |||
104 | return mac; | 104 | return mac; |
105 | } | 105 | } |
106 | 106 | ||
107 | static inline void mlx4_u64_to_mac(u8 *addr, u64 mac) | ||
108 | { | ||
109 | int i; | ||
110 | |||
111 | for (i = ETH_ALEN; i > 0; i--) { | ||
112 | addr[i - 1] = mac && 0xFF; | ||
113 | mac >>= 8; | ||
114 | } | ||
115 | } | ||
116 | |||
107 | #endif /* MLX4_DRIVER_H */ | 117 | #endif /* MLX4_DRIVER_H */ |