--- zzzz-none-000/linux-4.4.271/drivers/net/bonding/bond_options.c 2021-06-03 06:22:09.000000000 +0000 +++ hawkeye-5590-750/linux-4.4.271/drivers/net/bonding/bond_options.c 2023-04-19 10:22:29.000000000 +0000 @@ -17,6 +17,7 @@ #include #include #include +#include static int bond_option_active_slave_set(struct bonding *bond, const struct bond_opt_value *newval); @@ -86,6 +87,7 @@ { "802.3ad", BOND_MODE_8023AD, 0}, { "balance-tlb", BOND_MODE_TLB, 0}, { "balance-alb", BOND_MODE_ALB, 0}, + { "l2da", BOND_MODE_L2DA, 0}, { NULL, -1, 0}, }; @@ -204,6 +206,12 @@ { NULL, -1, 0}, }; +static struct bond_opt_value bond_l2da_multimac_tbl[] = { + { "off", 0, BOND_VALFLAG_DEFAULT}, + { "on", 1, 0}, + { NULL, -1, 0} +}; + static const struct bond_option bond_opts[BOND_OPT_LAST] = { [BOND_OPT_MODE] = { .id = BOND_OPT_MODE, @@ -257,7 +265,7 @@ .name = "arp_interval", .desc = "arp interval in milliseconds", .unsuppmodes = BIT(BOND_MODE_8023AD) | BIT(BOND_MODE_TLB) | - BIT(BOND_MODE_ALB), + BIT(BOND_MODE_ALB) | BIT(BOND_MODE_L2DA), .values = bond_intmax_tbl, .set = bond_option_arp_interval_set }, @@ -427,6 +435,14 @@ .desc = "Number of peer notifications to send on failover event", .values = bond_num_peer_notif_tbl, .set = bond_option_num_peer_notif_set + }, + [BOND_OPT_L2DA_MULTIMAC] = { + .id = BOND_OPT_L2DA_MULTIMAC, + .name = "l2da_multimac", + .desc = "Keeps MAC addresses of slaves in L2DA mode", + .flags = BOND_OPTFLAG_NOSLAVES, + .values = bond_l2da_multimac_tbl, + .set = bond_option_l2da_multimac_set } }; @@ -719,7 +735,8 @@ static int bond_option_mode_set(struct bonding *bond, const struct bond_opt_value *newval) { - if (!bond_mode_uses_arp(newval->value) && bond->params.arp_interval) { + if ((!bond_mode_uses_arp(newval->value) || bond_is_l2da(bond)) && + bond->params.arp_interval) { netdev_info(bond->dev, "%s mode is incompatible with arp monitoring, start mii monitoring\n", newval->string); /* disable arp monitoring */ @@ -730,6 +747,20 @@ bond->params.miimon); } + if (bond->params.mode != newval->value) { + if (newval->value == BOND_MODE_L2DA) { + int ret = bond_l2da_initialize(bond); + + if (ret) { + pr_err("%s: l2da mode cannot be initialized\n", + bond->dev->name); + return ret; + } + } else if (bond_is_l2da(bond)) { + bond_l2da_deinitialize(bond); + } + } + /* don't cache arp_validate between modes */ bond->params.arp_validate = BOND_ARP_VALIDATE_NONE; bond->params.mode = newval->value; @@ -1428,3 +1459,12 @@ bond->params.ad_user_port_key = newval->value; return 0; } + +int bond_option_l2da_multimac_set(struct bonding *bond, + const struct bond_opt_value *newval) +{ + pr_info("%s: Setting l2da_multimac to (%llu).\n", + bond->dev->name, newval->value); + bond->l2da_info.multimac = newval->value; + return 0; +}