Skip to content

Commit

Permalink
bonding: netlink error message support for options
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jonathan Toppins authored and Jakub Kicinski committed Jun 10, 2022
1 parent ce1d8e7 commit 2bff369
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 41 deletions.
101 changes: 68 additions & 33 deletions drivers/net/bonding/bond_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -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",
slave_dev->name, queue_id);
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)
return err;
}
Expand All @@ -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]);

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)
return err;
}
Expand All @@ -192,60 +194,68 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
active_slave = slave_dev->name;
}
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)
return err;
}
if (data[IFLA_BOND_MIIMON]) {
miimon = nla_get_u32(data[IFLA_BOND_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)
return err;
}
if (data[IFLA_BOND_UPDELAY]) {
int updelay = nla_get_u32(data[IFLA_BOND_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)
return err;
}
if (data[IFLA_BOND_DOWNDELAY]) {
int downdelay = nla_get_u32(data[IFLA_BOND_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)
return err;
}
if (data[IFLA_BOND_PEER_NOTIF_DELAY]) {
int delay = nla_get_u32(data[IFLA_BOND_PEER_NOTIF_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)
return err;
}
if (data[IFLA_BOND_USE_CARRIER]) {
int use_carrier = nla_get_u8(data[IFLA_BOND_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)
return err;
}
if (data[IFLA_BOND_ARP_INTERVAL]) {
int arp_interval = nla_get_u32(data[IFLA_BOND_ARP_INTERVAL]);

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;
}

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)
return err;
}
Expand All @@ -264,7 +274,9 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],

bond_opt_initval(&newval, (__force u64)target);
err = __bond_opt_set(bond, BOND_OPT_ARP_TARGETS,
&newval);
&newval,
data[IFLA_BOND_ARP_IP_TARGET],
extack);
if (err)
break;
i++;
Expand Down Expand Up @@ -292,7 +304,9 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],

bond_opt_initextra(&newval, &addr6, sizeof(addr6));
err = __bond_opt_set(bond, BOND_OPT_NS_TARGETS,
&newval);
&newval,
data[IFLA_BOND_NS_IP6_TARGET],
extack);
if (err)
break;
i++;
Expand All @@ -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]);

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;
}

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)
return err;
}
Expand All @@ -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]);

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)
return err;
}
Expand All @@ -335,7 +352,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
primary = dev->name;

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)
return err;
}
Expand All @@ -344,7 +362,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
nla_get_u8(data[IFLA_BOND_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)
return err;
}
Expand All @@ -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]);

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)
return err;
}
Expand All @@ -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]);

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)
return err;
}
Expand All @@ -371,7 +392,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
nla_get_u32(data[IFLA_BOND_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)
return err;
}
Expand All @@ -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]);

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)
return err;
}
Expand All @@ -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]);

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)
return err;
}
Expand All @@ -398,7 +422,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
nla_get_u32(data[IFLA_BOND_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)
return err;
}
Expand All @@ -407,7 +432,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
nla_get_u32(data[IFLA_BOND_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)
return err;
}
Expand All @@ -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]);

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)
return err;
}
Expand All @@ -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]);

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)
return err;
}
Expand All @@ -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]);

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)
return err;
}
Expand All @@ -444,7 +473,8 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
nla_get_u8(data[IFLA_BOND_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)
return err;
}
Expand All @@ -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]);

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)
return err;
}
Expand All @@ -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]);

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)
return err;
}
Expand All @@ -472,15 +504,17 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],

bond_opt_initval(&newval,
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)
return err;
}
if (data[IFLA_BOND_TLB_DYNAMIC_LB]) {
int dynamic_lb = nla_get_u8(data[IFLA_BOND_TLB_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)
return err;
}
Expand All @@ -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]);

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)
return err;
}
Expand Down
Loading

0 comments on commit 2bff369

Please sign in to comment.