bond_arp_send_all() will pass the vlan tags supplied by the user to bond_arp_send(). If vlan tags have not been supplied the vlans in the path to the target will be discovered by bond_verify_device_path(). The discovered vlan tags are then saved to be used on future calls to bond_arp_send(). bonding_exit() is also updated to free vlan tags when a bond is destroyed. Signed-off-by: David Wilder --- drivers/net/bonding/bond_main.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 7e938077bbde..2f153c89e401 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -3161,18 +3161,19 @@ struct bond_vlan_tag *bond_verify_device_path(struct net_device *start_dev, static void bond_arp_send_all(struct bonding *bond, struct slave *slave) { - struct rtable *rt; - struct bond_vlan_tag *tags; struct bond_arp_target *targets = bond->params.arp_targets; + char pbuf[BOND_OPTION_STRING_MAX_SIZE]; + struct bond_vlan_tag *tags; __be32 target_ip, addr; + struct rtable *rt; int i; for (i = 0; i < BOND_MAX_ARP_TARGETS && targets[i].target_ip; i++) { target_ip = targets[i].target_ip; tags = targets[i].tags; - slave_dbg(bond->dev, slave->dev, "%s: target %pI4\n", - __func__, &target_ip); + slave_dbg(bond->dev, slave->dev, "%s: target %s\n", __func__, + bond_arp_target_to_string(&targets[i], pbuf, sizeof(pbuf))); /* Find out through which dev should the packet go */ rt = ip_route_output(dev_net(bond->dev), target_ip, 0, 0, 0, @@ -3194,9 +3195,13 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) if (rt->dst.dev == bond->dev) goto found; - rcu_read_lock(); - tags = bond_verify_device_path(bond->dev, rt->dst.dev, 0); - rcu_read_unlock(); + if (!tags) { + rcu_read_lock(); + tags = bond_verify_device_path(bond->dev, rt->dst.dev, 0); + /* cache the tags */ + targets[i].tags = tags; + rcu_read_unlock(); + } if (!IS_ERR_OR_NULL(tags)) goto found; @@ -3212,7 +3217,6 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) addr = bond_confirm_addr(rt->dst.dev, target_ip, 0); ip_rt_put(rt); bond_arp_send(slave, ARPOP_REQUEST, target_ip, addr, tags); - kfree(tags); } } @@ -6732,7 +6736,7 @@ static void __exit bonding_exit(void) bond_netlink_fini(); unregister_pernet_subsys(&bond_net_ops); - + bond_free_vlan_tags(bonding_defaults.arp_targets); bond_destroy_debugfs(); #ifdef CONFIG_NET_POLL_CONTROLLER -- 2.43.5