Skip to content

Commit 2f61e6e

Browse files
Cindy Lumstsirkin
authored andcommitted
vdpa/mlx5: reuse common function for MAC address updates
Factor out MAC address update logic and reuse it from handle_ctrl_mac(). This ensures that old MAC entries are removed from the MPFS table before adding a new one and that the forwarding rules are updated accordingly. If updating the flow table fails, the original MAC and rules are restored as much as possible to keep the software and hardware state consistent. Signed-off-by: Cindy Lu <lulu@redhat.com> Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Message-Id: <20260126094848.9601-3-lulu@redhat.com>
1 parent 719d959 commit 2f61e6e

1 file changed

Lines changed: 71 additions & 60 deletions

File tree

drivers/vdpa/mlx5/net/mlx5_vnet.c

Lines changed: 71 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2125,86 +2125,97 @@ static void teardown_steering(struct mlx5_vdpa_net *ndev)
21252125
mlx5_destroy_flow_table(ndev->rxft);
21262126
}
21272127

2128-
static virtio_net_ctrl_ack handle_ctrl_mac(struct mlx5_vdpa_dev *mvdev, u8 cmd)
2128+
static int mlx5_vdpa_change_mac(struct mlx5_vdpa_net *ndev,
2129+
struct mlx5_core_dev *pfmdev,
2130+
const u8 *new_mac)
21292131
{
2130-
struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
2131-
struct mlx5_control_vq *cvq = &mvdev->cvq;
2132-
virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
2133-
struct mlx5_core_dev *pfmdev;
2134-
size_t read;
2135-
u8 mac[ETH_ALEN], mac_back[ETH_ALEN];
2132+
struct mlx5_vdpa_dev *mvdev = &ndev->mvdev;
2133+
u8 old_mac[ETH_ALEN];
21362134

2137-
pfmdev = pci_get_drvdata(pci_physfn(mvdev->mdev->pdev));
2138-
switch (cmd) {
2139-
case VIRTIO_NET_CTRL_MAC_ADDR_SET:
2140-
read = vringh_iov_pull_iotlb(&cvq->vring, &cvq->riov, (void *)mac, ETH_ALEN);
2141-
if (read != ETH_ALEN)
2142-
break;
2135+
if (is_zero_ether_addr(new_mac))
2136+
return -EINVAL;
21432137

2144-
if (!memcmp(ndev->config.mac, mac, 6)) {
2145-
status = VIRTIO_NET_OK;
2146-
break;
2138+
if (!is_zero_ether_addr(ndev->config.mac)) {
2139+
if (mlx5_mpfs_del_mac(pfmdev, ndev->config.mac)) {
2140+
mlx5_vdpa_warn(mvdev, "failed to delete old MAC %pM from MPFS table\n",
2141+
ndev->config.mac);
2142+
return -EIO;
21472143
}
2144+
}
21482145

2149-
if (is_zero_ether_addr(mac))
2150-
break;
2146+
if (mlx5_mpfs_add_mac(pfmdev, (u8 *)new_mac)) {
2147+
mlx5_vdpa_warn(mvdev, "failed to insert new MAC %pM into MPFS table\n",
2148+
new_mac);
2149+
return -EIO;
2150+
}
21512151

2152-
if (!is_zero_ether_addr(ndev->config.mac)) {
2153-
if (mlx5_mpfs_del_mac(pfmdev, ndev->config.mac)) {
2154-
mlx5_vdpa_warn(mvdev, "failed to delete old MAC %pM from MPFS table\n",
2155-
ndev->config.mac);
2156-
break;
2157-
}
2158-
}
2152+
/* backup the original mac address so that if failed to add the forward rules
2153+
* we could restore it
2154+
*/
2155+
ether_addr_copy(old_mac, ndev->config.mac);
21592156

2160-
if (mlx5_mpfs_add_mac(pfmdev, mac)) {
2161-
mlx5_vdpa_warn(mvdev, "failed to insert new MAC %pM into MPFS table\n",
2162-
mac);
2163-
break;
2164-
}
2157+
ether_addr_copy(ndev->config.mac, new_mac);
21652158

2166-
/* backup the original mac address so that if failed to add the forward rules
2167-
* we could restore it
2168-
*/
2169-
memcpy(mac_back, ndev->config.mac, ETH_ALEN);
2159+
/* Need recreate the flow table entry, so that the packet could forward back
2160+
*/
2161+
mac_vlan_del(ndev, old_mac, 0, false);
21702162

2171-
memcpy(ndev->config.mac, mac, ETH_ALEN);
2163+
if (mac_vlan_add(ndev, ndev->config.mac, 0, false)) {
2164+
mlx5_vdpa_warn(mvdev, "failed to insert forward rules, try to restore\n");
21722165

2173-
/* Need recreate the flow table entry, so that the packet could forward back
2166+
/* Although it hardly run here, we still need double check */
2167+
if (is_zero_ether_addr(old_mac)) {
2168+
mlx5_vdpa_warn(mvdev, "restore mac failed: Original MAC is zero\n");
2169+
return -EIO;
2170+
}
2171+
2172+
/* Try to restore original mac address to MFPS table, and try to restore
2173+
* the forward rule entry.
21742174
*/
2175-
mac_vlan_del(ndev, mac_back, 0, false);
2175+
if (mlx5_mpfs_del_mac(pfmdev, ndev->config.mac)) {
2176+
mlx5_vdpa_warn(mvdev, "restore mac failed: delete MAC %pM from MPFS table failed\n",
2177+
ndev->config.mac);
2178+
}
21762179

2177-
if (mac_vlan_add(ndev, ndev->config.mac, 0, false)) {
2178-
mlx5_vdpa_warn(mvdev, "failed to insert forward rules, try to restore\n");
2180+
if (mlx5_mpfs_add_mac(pfmdev, old_mac)) {
2181+
mlx5_vdpa_warn(mvdev, "restore mac failed: insert old MAC %pM into MPFS table failed\n",
2182+
old_mac);
2183+
}
21792184

2180-
/* Although it hardly run here, we still need double check */
2181-
if (is_zero_ether_addr(mac_back)) {
2182-
mlx5_vdpa_warn(mvdev, "restore mac failed: Original MAC is zero\n");
2183-
break;
2184-
}
2185+
ether_addr_copy(ndev->config.mac, old_mac);
21852186

2186-
/* Try to restore original mac address to MFPS table, and try to restore
2187-
* the forward rule entry.
2188-
*/
2189-
if (mlx5_mpfs_del_mac(pfmdev, ndev->config.mac)) {
2190-
mlx5_vdpa_warn(mvdev, "restore mac failed: delete MAC %pM from MPFS table failed\n",
2191-
ndev->config.mac);
2192-
}
2187+
if (mac_vlan_add(ndev, ndev->config.mac, 0, false))
2188+
mlx5_vdpa_warn(mvdev, "restore forward rules failed: insert forward rules failed\n");
21932189

2194-
if (mlx5_mpfs_add_mac(pfmdev, mac_back)) {
2195-
mlx5_vdpa_warn(mvdev, "restore mac failed: insert old MAC %pM into MPFS table failed\n",
2196-
mac_back);
2197-
}
2190+
return -EIO;
2191+
}
21982192

2199-
memcpy(ndev->config.mac, mac_back, ETH_ALEN);
2193+
return 0;
2194+
}
22002195

2201-
if (mac_vlan_add(ndev, ndev->config.mac, 0, false))
2202-
mlx5_vdpa_warn(mvdev, "restore forward rules failed: insert forward rules failed\n");
2196+
static virtio_net_ctrl_ack handle_ctrl_mac(struct mlx5_vdpa_dev *mvdev, u8 cmd)
2197+
{
2198+
struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
2199+
struct mlx5_control_vq *cvq = &mvdev->cvq;
2200+
virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
2201+
struct mlx5_core_dev *pfmdev;
2202+
size_t read;
2203+
u8 mac[ETH_ALEN];
22032204

2205+
pfmdev = pci_get_drvdata(pci_physfn(mvdev->mdev->pdev));
2206+
switch (cmd) {
2207+
case VIRTIO_NET_CTRL_MAC_ADDR_SET:
2208+
read = vringh_iov_pull_iotlb(&cvq->vring, &cvq->riov,
2209+
(void *)mac, ETH_ALEN);
2210+
if (read != ETH_ALEN)
22042211
break;
2205-
}
22062212

2207-
status = VIRTIO_NET_OK;
2213+
if (!memcmp(ndev->config.mac, mac, 6)) {
2214+
status = VIRTIO_NET_OK;
2215+
break;
2216+
}
2217+
status = mlx5_vdpa_change_mac(ndev, pfmdev, mac) ? VIRTIO_NET_ERR :
2218+
VIRTIO_NET_OK;
22082219
break;
22092220

22102221
default:

0 commit comments

Comments
 (0)