forked from Minki/linux
bonding: netlink error message support for options
Add support for reporting errors via extack in both bond_newlink and bond_changelink. Instead of having to look in the kernel log for why an option was not correct just report the error to the user via the extack variable. What is currently reported today: ip link add bond0 type bond ip link set bond0 up ip link set bond0 type bond mode 4 RTNETLINK answers: Device or resource busy After this change: ip link add bond0 type bond ip link set bond0 up ip link set bond0 type bond mode 4 Error: unable to set option because the bond is up. Signed-off-by: Jonathan Toppins <jtoppins@redhat.com> Acked-by: Jay Vosburgh <jay.vosburgh@canonical.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
ce1d8e74f7
commit
2bff369b23
@ -151,7 +151,8 @@ static int bond_slave_changelink(struct net_device *bond_dev,
|
|||||||
snprintf(queue_id_str, sizeof(queue_id_str), "%s:%u\n",
|
snprintf(queue_id_str, sizeof(queue_id_str), "%s:%u\n",
|
||||||
slave_dev->name, queue_id);
|
slave_dev->name, queue_id);
|
||||||
bond_opt_initstr(&newval, queue_id_str);
|
bond_opt_initstr(&newval, queue_id_str);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_QUEUE_ID, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_QUEUE_ID, &newval,
|
||||||
|
data[IFLA_BOND_SLAVE_QUEUE_ID], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -175,7 +176,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
int mode = nla_get_u8(data[IFLA_BOND_MODE]);
|
int mode = nla_get_u8(data[IFLA_BOND_MODE]);
|
||||||
|
|
||||||
bond_opt_initval(&newval, mode);
|
bond_opt_initval(&newval, mode);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_MODE, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_MODE, &newval,
|
||||||
|
data[IFLA_BOND_MODE], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -192,7 +194,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
active_slave = slave_dev->name;
|
active_slave = slave_dev->name;
|
||||||
}
|
}
|
||||||
bond_opt_initstr(&newval, active_slave);
|
bond_opt_initstr(&newval, active_slave);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_ACTIVE_SLAVE, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_ACTIVE_SLAVE, &newval,
|
||||||
|
data[IFLA_BOND_ACTIVE_SLAVE], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -200,7 +203,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
miimon = nla_get_u32(data[IFLA_BOND_MIIMON]);
|
miimon = nla_get_u32(data[IFLA_BOND_MIIMON]);
|
||||||
|
|
||||||
bond_opt_initval(&newval, miimon);
|
bond_opt_initval(&newval, miimon);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_MIIMON, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_MIIMON, &newval,
|
||||||
|
data[IFLA_BOND_MIIMON], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -208,7 +212,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
int updelay = nla_get_u32(data[IFLA_BOND_UPDELAY]);
|
int updelay = nla_get_u32(data[IFLA_BOND_UPDELAY]);
|
||||||
|
|
||||||
bond_opt_initval(&newval, updelay);
|
bond_opt_initval(&newval, updelay);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_UPDELAY, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_UPDELAY, &newval,
|
||||||
|
data[IFLA_BOND_UPDELAY], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -216,7 +221,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
int downdelay = nla_get_u32(data[IFLA_BOND_DOWNDELAY]);
|
int downdelay = nla_get_u32(data[IFLA_BOND_DOWNDELAY]);
|
||||||
|
|
||||||
bond_opt_initval(&newval, downdelay);
|
bond_opt_initval(&newval, downdelay);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_DOWNDELAY, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_DOWNDELAY, &newval,
|
||||||
|
data[IFLA_BOND_DOWNDELAY], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -224,7 +230,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
int delay = nla_get_u32(data[IFLA_BOND_PEER_NOTIF_DELAY]);
|
int delay = nla_get_u32(data[IFLA_BOND_PEER_NOTIF_DELAY]);
|
||||||
|
|
||||||
bond_opt_initval(&newval, delay);
|
bond_opt_initval(&newval, delay);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_PEER_NOTIF_DELAY, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_PEER_NOTIF_DELAY, &newval,
|
||||||
|
data[IFLA_BOND_PEER_NOTIF_DELAY], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -232,7 +239,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
int use_carrier = nla_get_u8(data[IFLA_BOND_USE_CARRIER]);
|
int use_carrier = nla_get_u8(data[IFLA_BOND_USE_CARRIER]);
|
||||||
|
|
||||||
bond_opt_initval(&newval, use_carrier);
|
bond_opt_initval(&newval, use_carrier);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_USE_CARRIER, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_USE_CARRIER, &newval,
|
||||||
|
data[IFLA_BOND_USE_CARRIER], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -240,12 +248,14 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
int arp_interval = nla_get_u32(data[IFLA_BOND_ARP_INTERVAL]);
|
int arp_interval = nla_get_u32(data[IFLA_BOND_ARP_INTERVAL]);
|
||||||
|
|
||||||
if (arp_interval && miimon) {
|
if (arp_interval && miimon) {
|
||||||
netdev_err(bond->dev, "ARP monitoring cannot be used with MII monitoring\n");
|
NL_SET_ERR_MSG_ATTR(extack, data[IFLA_BOND_ARP_INTERVAL],
|
||||||
|
"ARP monitoring cannot be used with MII monitoring");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bond_opt_initval(&newval, arp_interval);
|
bond_opt_initval(&newval, arp_interval);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_ARP_INTERVAL, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_ARP_INTERVAL, &newval,
|
||||||
|
data[IFLA_BOND_ARP_INTERVAL], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -264,7 +274,9 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
|
|
||||||
bond_opt_initval(&newval, (__force u64)target);
|
bond_opt_initval(&newval, (__force u64)target);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_ARP_TARGETS,
|
err = __bond_opt_set(bond, BOND_OPT_ARP_TARGETS,
|
||||||
&newval);
|
&newval,
|
||||||
|
data[IFLA_BOND_ARP_IP_TARGET],
|
||||||
|
extack);
|
||||||
if (err)
|
if (err)
|
||||||
break;
|
break;
|
||||||
i++;
|
i++;
|
||||||
@ -292,7 +304,9 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
|
|
||||||
bond_opt_initextra(&newval, &addr6, sizeof(addr6));
|
bond_opt_initextra(&newval, &addr6, sizeof(addr6));
|
||||||
err = __bond_opt_set(bond, BOND_OPT_NS_TARGETS,
|
err = __bond_opt_set(bond, BOND_OPT_NS_TARGETS,
|
||||||
&newval);
|
&newval,
|
||||||
|
data[IFLA_BOND_NS_IP6_TARGET],
|
||||||
|
extack);
|
||||||
if (err)
|
if (err)
|
||||||
break;
|
break;
|
||||||
i++;
|
i++;
|
||||||
@ -307,12 +321,14 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
int arp_validate = nla_get_u32(data[IFLA_BOND_ARP_VALIDATE]);
|
int arp_validate = nla_get_u32(data[IFLA_BOND_ARP_VALIDATE]);
|
||||||
|
|
||||||
if (arp_validate && miimon) {
|
if (arp_validate && miimon) {
|
||||||
netdev_err(bond->dev, "ARP validating cannot be used with MII monitoring\n");
|
NL_SET_ERR_MSG_ATTR(extack, data[IFLA_BOND_ARP_INTERVAL],
|
||||||
|
"ARP validating cannot be used with MII monitoring");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bond_opt_initval(&newval, arp_validate);
|
bond_opt_initval(&newval, arp_validate);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_ARP_VALIDATE, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_ARP_VALIDATE, &newval,
|
||||||
|
data[IFLA_BOND_ARP_VALIDATE], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -321,7 +337,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
nla_get_u32(data[IFLA_BOND_ARP_ALL_TARGETS]);
|
nla_get_u32(data[IFLA_BOND_ARP_ALL_TARGETS]);
|
||||||
|
|
||||||
bond_opt_initval(&newval, arp_all_targets);
|
bond_opt_initval(&newval, arp_all_targets);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_ARP_ALL_TARGETS, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_ARP_ALL_TARGETS, &newval,
|
||||||
|
data[IFLA_BOND_ARP_ALL_TARGETS], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -335,7 +352,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
primary = dev->name;
|
primary = dev->name;
|
||||||
|
|
||||||
bond_opt_initstr(&newval, primary);
|
bond_opt_initstr(&newval, primary);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_PRIMARY, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_PRIMARY, &newval,
|
||||||
|
data[IFLA_BOND_PRIMARY], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -344,7 +362,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
nla_get_u8(data[IFLA_BOND_PRIMARY_RESELECT]);
|
nla_get_u8(data[IFLA_BOND_PRIMARY_RESELECT]);
|
||||||
|
|
||||||
bond_opt_initval(&newval, primary_reselect);
|
bond_opt_initval(&newval, primary_reselect);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_PRIMARY_RESELECT, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_PRIMARY_RESELECT, &newval,
|
||||||
|
data[IFLA_BOND_PRIMARY_RESELECT], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -353,7 +372,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
nla_get_u8(data[IFLA_BOND_FAIL_OVER_MAC]);
|
nla_get_u8(data[IFLA_BOND_FAIL_OVER_MAC]);
|
||||||
|
|
||||||
bond_opt_initval(&newval, fail_over_mac);
|
bond_opt_initval(&newval, fail_over_mac);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_FAIL_OVER_MAC, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_FAIL_OVER_MAC, &newval,
|
||||||
|
data[IFLA_BOND_FAIL_OVER_MAC], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -362,7 +382,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
nla_get_u8(data[IFLA_BOND_XMIT_HASH_POLICY]);
|
nla_get_u8(data[IFLA_BOND_XMIT_HASH_POLICY]);
|
||||||
|
|
||||||
bond_opt_initval(&newval, xmit_hash_policy);
|
bond_opt_initval(&newval, xmit_hash_policy);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_XMIT_HASH, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_XMIT_HASH, &newval,
|
||||||
|
data[IFLA_BOND_XMIT_HASH_POLICY], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -371,7 +392,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
nla_get_u32(data[IFLA_BOND_RESEND_IGMP]);
|
nla_get_u32(data[IFLA_BOND_RESEND_IGMP]);
|
||||||
|
|
||||||
bond_opt_initval(&newval, resend_igmp);
|
bond_opt_initval(&newval, resend_igmp);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_RESEND_IGMP, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_RESEND_IGMP, &newval,
|
||||||
|
data[IFLA_BOND_RESEND_IGMP], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -380,7 +402,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
nla_get_u8(data[IFLA_BOND_NUM_PEER_NOTIF]);
|
nla_get_u8(data[IFLA_BOND_NUM_PEER_NOTIF]);
|
||||||
|
|
||||||
bond_opt_initval(&newval, num_peer_notif);
|
bond_opt_initval(&newval, num_peer_notif);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_NUM_PEER_NOTIF, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_NUM_PEER_NOTIF, &newval,
|
||||||
|
data[IFLA_BOND_NUM_PEER_NOTIF], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -389,7 +412,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
nla_get_u8(data[IFLA_BOND_ALL_SLAVES_ACTIVE]);
|
nla_get_u8(data[IFLA_BOND_ALL_SLAVES_ACTIVE]);
|
||||||
|
|
||||||
bond_opt_initval(&newval, all_slaves_active);
|
bond_opt_initval(&newval, all_slaves_active);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_ALL_SLAVES_ACTIVE, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_ALL_SLAVES_ACTIVE, &newval,
|
||||||
|
data[IFLA_BOND_ALL_SLAVES_ACTIVE], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -398,7 +422,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
nla_get_u32(data[IFLA_BOND_MIN_LINKS]);
|
nla_get_u32(data[IFLA_BOND_MIN_LINKS]);
|
||||||
|
|
||||||
bond_opt_initval(&newval, min_links);
|
bond_opt_initval(&newval, min_links);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_MINLINKS, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_MINLINKS, &newval,
|
||||||
|
data[IFLA_BOND_MIN_LINKS], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -407,7 +432,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
nla_get_u32(data[IFLA_BOND_LP_INTERVAL]);
|
nla_get_u32(data[IFLA_BOND_LP_INTERVAL]);
|
||||||
|
|
||||||
bond_opt_initval(&newval, lp_interval);
|
bond_opt_initval(&newval, lp_interval);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_LP_INTERVAL, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_LP_INTERVAL, &newval,
|
||||||
|
data[IFLA_BOND_LP_INTERVAL], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -416,7 +442,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
nla_get_u32(data[IFLA_BOND_PACKETS_PER_SLAVE]);
|
nla_get_u32(data[IFLA_BOND_PACKETS_PER_SLAVE]);
|
||||||
|
|
||||||
bond_opt_initval(&newval, packets_per_slave);
|
bond_opt_initval(&newval, packets_per_slave);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_PACKETS_PER_SLAVE, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_PACKETS_PER_SLAVE, &newval,
|
||||||
|
data[IFLA_BOND_PACKETS_PER_SLAVE], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -425,7 +452,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
int lacp_active = nla_get_u8(data[IFLA_BOND_AD_LACP_ACTIVE]);
|
int lacp_active = nla_get_u8(data[IFLA_BOND_AD_LACP_ACTIVE]);
|
||||||
|
|
||||||
bond_opt_initval(&newval, lacp_active);
|
bond_opt_initval(&newval, lacp_active);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_LACP_ACTIVE, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_LACP_ACTIVE, &newval,
|
||||||
|
data[IFLA_BOND_AD_LACP_ACTIVE], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -435,7 +463,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
nla_get_u8(data[IFLA_BOND_AD_LACP_RATE]);
|
nla_get_u8(data[IFLA_BOND_AD_LACP_RATE]);
|
||||||
|
|
||||||
bond_opt_initval(&newval, lacp_rate);
|
bond_opt_initval(&newval, lacp_rate);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_LACP_RATE, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_LACP_RATE, &newval,
|
||||||
|
data[IFLA_BOND_AD_LACP_RATE], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -444,7 +473,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
nla_get_u8(data[IFLA_BOND_AD_SELECT]);
|
nla_get_u8(data[IFLA_BOND_AD_SELECT]);
|
||||||
|
|
||||||
bond_opt_initval(&newval, ad_select);
|
bond_opt_initval(&newval, ad_select);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_AD_SELECT, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_AD_SELECT, &newval,
|
||||||
|
data[IFLA_BOND_AD_SELECT], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -453,7 +483,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
nla_get_u16(data[IFLA_BOND_AD_ACTOR_SYS_PRIO]);
|
nla_get_u16(data[IFLA_BOND_AD_ACTOR_SYS_PRIO]);
|
||||||
|
|
||||||
bond_opt_initval(&newval, actor_sys_prio);
|
bond_opt_initval(&newval, actor_sys_prio);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_AD_ACTOR_SYS_PRIO, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_AD_ACTOR_SYS_PRIO, &newval,
|
||||||
|
data[IFLA_BOND_AD_ACTOR_SYS_PRIO], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -462,7 +493,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
nla_get_u16(data[IFLA_BOND_AD_USER_PORT_KEY]);
|
nla_get_u16(data[IFLA_BOND_AD_USER_PORT_KEY]);
|
||||||
|
|
||||||
bond_opt_initval(&newval, port_key);
|
bond_opt_initval(&newval, port_key);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_AD_USER_PORT_KEY, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_AD_USER_PORT_KEY, &newval,
|
||||||
|
data[IFLA_BOND_AD_USER_PORT_KEY], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -472,7 +504,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
|
|
||||||
bond_opt_initval(&newval,
|
bond_opt_initval(&newval,
|
||||||
nla_get_u64(data[IFLA_BOND_AD_ACTOR_SYSTEM]));
|
nla_get_u64(data[IFLA_BOND_AD_ACTOR_SYSTEM]));
|
||||||
err = __bond_opt_set(bond, BOND_OPT_AD_ACTOR_SYSTEM, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_AD_ACTOR_SYSTEM, &newval,
|
||||||
|
data[IFLA_BOND_AD_ACTOR_SYSTEM], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -480,7 +513,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
int dynamic_lb = nla_get_u8(data[IFLA_BOND_TLB_DYNAMIC_LB]);
|
int dynamic_lb = nla_get_u8(data[IFLA_BOND_TLB_DYNAMIC_LB]);
|
||||||
|
|
||||||
bond_opt_initval(&newval, dynamic_lb);
|
bond_opt_initval(&newval, dynamic_lb);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_TLB_DYNAMIC_LB, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_TLB_DYNAMIC_LB, &newval,
|
||||||
|
data[IFLA_BOND_TLB_DYNAMIC_LB], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -489,7 +523,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||||||
int missed_max = nla_get_u8(data[IFLA_BOND_MISSED_MAX]);
|
int missed_max = nla_get_u8(data[IFLA_BOND_MISSED_MAX]);
|
||||||
|
|
||||||
bond_opt_initval(&newval, missed_max);
|
bond_opt_initval(&newval, missed_max);
|
||||||
err = __bond_opt_set(bond, BOND_OPT_MISSED_MAX, &newval);
|
err = __bond_opt_set(bond, BOND_OPT_MISSED_MAX, &newval,
|
||||||
|
data[IFLA_BOND_MISSED_MAX], extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -632,27 +632,35 @@ static int bond_opt_check_deps(struct bonding *bond,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void bond_opt_dep_print(struct bonding *bond,
|
static void bond_opt_dep_print(struct bonding *bond,
|
||||||
const struct bond_option *opt)
|
const struct bond_option *opt,
|
||||||
|
struct nlattr *bad_attr,
|
||||||
|
struct netlink_ext_ack *extack)
|
||||||
{
|
{
|
||||||
const struct bond_opt_value *modeval;
|
const struct bond_opt_value *modeval;
|
||||||
struct bond_params *params;
|
struct bond_params *params;
|
||||||
|
|
||||||
params = &bond->params;
|
params = &bond->params;
|
||||||
modeval = bond_opt_get_val(BOND_OPT_MODE, params->mode);
|
modeval = bond_opt_get_val(BOND_OPT_MODE, params->mode);
|
||||||
if (test_bit(params->mode, &opt->unsuppmodes))
|
if (test_bit(params->mode, &opt->unsuppmodes)) {
|
||||||
netdev_err(bond->dev, "option %s: mode dependency failed, not supported in mode %s(%llu)\n",
|
netdev_err(bond->dev, "option %s: mode dependency failed, not supported in mode %s(%llu)\n",
|
||||||
opt->name, modeval->string, modeval->value);
|
opt->name, modeval->string, modeval->value);
|
||||||
|
NL_SET_ERR_MSG_ATTR(extack, bad_attr,
|
||||||
|
"option not supported in mode");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bond_opt_error_interpret(struct bonding *bond,
|
static void bond_opt_error_interpret(struct bonding *bond,
|
||||||
const struct bond_option *opt,
|
const struct bond_option *opt,
|
||||||
int error, const struct bond_opt_value *val)
|
int error, const struct bond_opt_value *val,
|
||||||
|
struct nlattr *bad_attr,
|
||||||
|
struct netlink_ext_ack *extack)
|
||||||
{
|
{
|
||||||
const struct bond_opt_value *minval, *maxval;
|
const struct bond_opt_value *minval, *maxval;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
switch (error) {
|
switch (error) {
|
||||||
case -EINVAL:
|
case -EINVAL:
|
||||||
|
NL_SET_ERR_MSG_ATTR(extack, bad_attr, "invalid option value");
|
||||||
if (val) {
|
if (val) {
|
||||||
if (val->string) {
|
if (val->string) {
|
||||||
/* sometimes RAWVAL opts may have new lines */
|
/* sometimes RAWVAL opts may have new lines */
|
||||||
@ -674,13 +682,17 @@ static void bond_opt_error_interpret(struct bonding *bond,
|
|||||||
opt->name, minval ? minval->value : 0, maxval->value);
|
opt->name, minval ? minval->value : 0, maxval->value);
|
||||||
break;
|
break;
|
||||||
case -EACCES:
|
case -EACCES:
|
||||||
bond_opt_dep_print(bond, opt);
|
bond_opt_dep_print(bond, opt, bad_attr, extack);
|
||||||
break;
|
break;
|
||||||
case -ENOTEMPTY:
|
case -ENOTEMPTY:
|
||||||
|
NL_SET_ERR_MSG_ATTR(extack, bad_attr,
|
||||||
|
"unable to set option because the bond device has slaves");
|
||||||
netdev_err(bond->dev, "option %s: unable to set because the bond device has slaves\n",
|
netdev_err(bond->dev, "option %s: unable to set because the bond device has slaves\n",
|
||||||
opt->name);
|
opt->name);
|
||||||
break;
|
break;
|
||||||
case -EBUSY:
|
case -EBUSY:
|
||||||
|
NL_SET_ERR_MSG_ATTR(extack, bad_attr,
|
||||||
|
"unable to set option because the bond is up");
|
||||||
netdev_err(bond->dev, "option %s: unable to set because the bond device is up\n",
|
netdev_err(bond->dev, "option %s: unable to set because the bond device is up\n",
|
||||||
opt->name);
|
opt->name);
|
||||||
break;
|
break;
|
||||||
@ -691,6 +703,8 @@ static void bond_opt_error_interpret(struct bonding *bond,
|
|||||||
*p = '\0';
|
*p = '\0';
|
||||||
netdev_err(bond->dev, "option %s: interface %s does not exist!\n",
|
netdev_err(bond->dev, "option %s: interface %s does not exist!\n",
|
||||||
opt->name, val->string);
|
opt->name, val->string);
|
||||||
|
NL_SET_ERR_MSG_ATTR(extack, bad_attr,
|
||||||
|
"interface does not exist");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -703,13 +717,17 @@ static void bond_opt_error_interpret(struct bonding *bond,
|
|||||||
* @bond: target bond device
|
* @bond: target bond device
|
||||||
* @option: option to set
|
* @option: option to set
|
||||||
* @val: value to set it to
|
* @val: value to set it to
|
||||||
|
* @bad_attr: netlink attribue that caused the error
|
||||||
|
* @extack: extended netlink error structure, used when an error message
|
||||||
|
* needs to be returned to the caller via netlink
|
||||||
*
|
*
|
||||||
* This function is used to change the bond's option value, it can be
|
* This function is used to change the bond's option value, it can be
|
||||||
* used for both enabling/changing an option and for disabling it. RTNL lock
|
* used for both enabling/changing an option and for disabling it. RTNL lock
|
||||||
* must be obtained before calling this function.
|
* must be obtained before calling this function.
|
||||||
*/
|
*/
|
||||||
int __bond_opt_set(struct bonding *bond,
|
int __bond_opt_set(struct bonding *bond,
|
||||||
unsigned int option, struct bond_opt_value *val)
|
unsigned int option, struct bond_opt_value *val,
|
||||||
|
struct nlattr *bad_attr, struct netlink_ext_ack *extack)
|
||||||
{
|
{
|
||||||
const struct bond_opt_value *retval = NULL;
|
const struct bond_opt_value *retval = NULL;
|
||||||
const struct bond_option *opt;
|
const struct bond_option *opt;
|
||||||
@ -731,7 +749,7 @@ int __bond_opt_set(struct bonding *bond,
|
|||||||
ret = opt->set(bond, retval);
|
ret = opt->set(bond, retval);
|
||||||
out:
|
out:
|
||||||
if (ret)
|
if (ret)
|
||||||
bond_opt_error_interpret(bond, opt, ret, val);
|
bond_opt_error_interpret(bond, opt, ret, val, bad_attr, extack);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -753,7 +771,7 @@ int __bond_opt_set_notify(struct bonding *bond,
|
|||||||
|
|
||||||
ASSERT_RTNL();
|
ASSERT_RTNL();
|
||||||
|
|
||||||
ret = __bond_opt_set(bond, option, val);
|
ret = __bond_opt_set(bond, option, val, NULL, NULL);
|
||||||
|
|
||||||
if (!ret && (bond->dev->reg_state == NETREG_REGISTERED))
|
if (!ret && (bond->dev->reg_state == NETREG_REGISTERED))
|
||||||
call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev);
|
call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev);
|
||||||
|
@ -107,7 +107,8 @@ struct bond_option {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int __bond_opt_set(struct bonding *bond, unsigned int option,
|
int __bond_opt_set(struct bonding *bond, unsigned int option,
|
||||||
struct bond_opt_value *val);
|
struct bond_opt_value *val,
|
||||||
|
struct nlattr *bad_attr, struct netlink_ext_ack *extack);
|
||||||
int __bond_opt_set_notify(struct bonding *bond, unsigned int option,
|
int __bond_opt_set_notify(struct bonding *bond, unsigned int option,
|
||||||
struct bond_opt_value *val);
|
struct bond_opt_value *val);
|
||||||
int bond_opt_tryset_rtnl(struct bonding *bond, unsigned int option, char *buf);
|
int bond_opt_tryset_rtnl(struct bonding *bond, unsigned int option, char *buf);
|
||||||
|
Loading…
Reference in New Issue
Block a user