}
static void _rocker_neigh_add(struct rocker *rocker,
+ enum switchdev_trans trans,
struct rocker_neigh_tbl_entry *entry)
{
- entry->index = rocker->neigh_tbl_next_index++;
+ entry->index = rocker->neigh_tbl_next_index;
+ if (trans == SWITCHDEV_TRANS_PREPARE)
+ return;
+ rocker->neigh_tbl_next_index++;
entry->ref_count++;
hash_add(rocker->neigh_tbl, &entry->entry,
be32_to_cpu(entry->ip_addr));
enum switchdev_trans trans,
struct rocker_neigh_tbl_entry *entry)
{
+ if (trans == SWITCHDEV_TRANS_PREPARE)
+ return;
if (--entry->ref_count == 0) {
hash_del(&entry->entry);
rocker_port_kfree(rocker_port, trans, entry);
}
static void _rocker_neigh_update(struct rocker_neigh_tbl_entry *entry,
+ enum switchdev_trans trans,
u8 *eth_dst, bool ttl_check)
{
if (eth_dst) {
ether_addr_copy(entry->eth_dst, eth_dst);
entry->ttl_check = ttl_check;
- } else {
+ } else if (trans != SWITCHDEV_TRANS_PREPARE) {
entry->ref_count++;
}
}
entry->dev = rocker_port->dev;
ether_addr_copy(entry->eth_dst, eth_dst);
entry->ttl_check = true;
- _rocker_neigh_add(rocker, entry);
+ _rocker_neigh_add(rocker, trans, entry);
} else if (removing) {
memcpy(entry, found, sizeof(*entry));
_rocker_neigh_del(rocker_port, trans, found);
} else if (updating) {
- _rocker_neigh_update(found, eth_dst, true);
+ _rocker_neigh_update(found, trans, eth_dst, true);
memcpy(entry, found, sizeof(*entry));
} else {
err = -ENOENT;
if (adding) {
entry->ip_addr = ip_addr;
entry->dev = rocker_port->dev;
- _rocker_neigh_add(rocker, entry);
+ _rocker_neigh_add(rocker, trans, entry);
*index = entry->index;
resolved = false;
} else if (removing) {
_rocker_neigh_del(rocker_port, trans, found);
} else if (updating) {
- _rocker_neigh_update(found, NULL, false);
+ _rocker_neigh_update(found, trans, NULL, false);
resolved = !is_zero_ether_addr(found->eth_dst);
} else {
err = -ENOENT;
if (removing && found) {
rocker_port_kfree(rocker_port, trans, fdb);
- hash_del(&found->entry);
+ if (trans != SWITCHDEV_TRANS_PREPARE)
+ hash_del(&found->entry);
} else if (!removing && !found) {
- hash_add(rocker->fdb_tbl, &fdb->entry, fdb->key_crc32);
+ if (trans != SWITCHDEV_TRANS_PREPARE)
+ hash_add(rocker->fdb_tbl, &fdb->entry, fdb->key_crc32);
}
spin_unlock_irqrestore(&rocker->fdb_tbl_lock, lock_flags);
found->key.vlan_id);
if (err)
goto err_out;
- hash_del(&found->entry);
+ if (trans != SWITCHDEV_TRANS_PREPARE)
+ hash_del(&found->entry);
}
err_out:
}
static __be16 rocker_port_internal_vlan_id_get(struct rocker_port *rocker_port,
- enum switchdev_trans trans,
int ifindex)
{
struct rocker *rocker = rocker_port->rocker;
unsigned long lock_flags;
int i;
- entry = rocker_port_kzalloc(rocker_port, trans, sizeof(*entry));
+ entry = kzalloc(sizeof(*entry), GFP_KERNEL);
if (!entry)
return 0;
found = rocker_internal_vlan_tbl_find(rocker, ifindex);
if (found) {
- rocker_port_kfree(rocker_port, trans, entry);
+ kfree(entry);
goto found;
}
}
static void rocker_port_internal_vlan_id_put(struct rocker_port *rocker_port,
- enum switchdev_trans trans,
int ifindex)
{
struct rocker *rocker = rocker_port->rocker;
bit = ntohs(found->vlan_id) - ROCKER_INTERNAL_VLAN_ID_BASE;
clear_bit(bit, rocker->internal_vlan_bitmap);
hash_del(&found->entry);
- rocker_port_kfree(rocker_port, trans, found);
+ kfree(found);
}
not_found:
rocker_port_set_learning(rocker_port, SWITCHDEV_TRANS_NONE);
rocker_port->internal_vlan_id =
- rocker_port_internal_vlan_id_get(rocker_port,
- SWITCHDEV_TRANS_NONE,
- dev->ifindex);
+ rocker_port_internal_vlan_id_get(rocker_port, dev->ifindex);
err = rocker_port_ig_tbl(rocker_port, SWITCHDEV_TRANS_NONE, 0);
if (err) {
dev_err(&pdev->dev, "install ig port table failed\n");
{
int err;
- rocker_port_internal_vlan_id_put(rocker_port, SWITCHDEV_TRANS_NONE,
+ rocker_port_internal_vlan_id_put(rocker_port,
rocker_port->dev->ifindex);
rocker_port->bridge_dev = bridge;
if (err)
return err;
rocker_port->internal_vlan_id =
- rocker_port_internal_vlan_id_get(rocker_port,
- SWITCHDEV_TRANS_NONE,
- bridge->ifindex);
+ rocker_port_internal_vlan_id_get(rocker_port, bridge->ifindex);
return rocker_port_vlan(rocker_port, SWITCHDEV_TRANS_NONE, 0, 0);
}
{
int err;
- rocker_port_internal_vlan_id_put(rocker_port, SWITCHDEV_TRANS_NONE,
+ rocker_port_internal_vlan_id_put(rocker_port,
rocker_port->bridge_dev->ifindex);
rocker_port->bridge_dev = NULL;
return err;
rocker_port->internal_vlan_id =
rocker_port_internal_vlan_id_get(rocker_port,
- SWITCHDEV_TRANS_NONE,
rocker_port->dev->ifindex);
err = rocker_port_vlan(rocker_port, SWITCHDEV_TRANS_NONE, 0, 0);
if (err)