diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c index a0a2e8c32fe533567d14ffd7481b6defbc4a62b4..7edf6399cea242e5191390be10dffc6e795151f7 100644 --- a/drivers/net/bonding/bond_netlink.c +++ b/drivers/net/bonding/bond_netlink.c @@ -27,6 +27,7 @@ static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = { [IFLA_BOND_MIIMON] = { .type = NLA_U32 }, [IFLA_BOND_UPDELAY] = { .type = NLA_U32 }, [IFLA_BOND_DOWNDELAY] = { .type = NLA_U32 }, + [IFLA_BOND_USE_CARRIER] = { .type = NLA_U8 }, }; static int bond_validate(struct nlattr *tb[], struct nlattr *data[]) @@ -93,6 +94,13 @@ static int bond_changelink(struct net_device *bond_dev, if (err) return err; } + if (data[IFLA_BOND_USE_CARRIER]) { + int use_carrier = nla_get_u8(data[IFLA_BOND_USE_CARRIER]); + + err = bond_option_use_carrier_set(bond, use_carrier); + if (err) + return err; + } return 0; } @@ -115,6 +123,7 @@ static size_t bond_get_size(const struct net_device *bond_dev) nla_total_size(sizeof(u32)) + /* IFLA_BOND_MIIMON */ nla_total_size(sizeof(u32)) + /* IFLA_BOND_UPDELAY */ nla_total_size(sizeof(u32)) + /* IFLA_BOND_DOWNDELAY */ + nla_total_size(sizeof(u8)) + /* IFLA_BOND_USE_CARRIER */ 0; } @@ -142,6 +151,9 @@ static int bond_fill_info(struct sk_buff *skb, bond->params.downdelay * bond->params.miimon)) goto nla_put_failure; + if (nla_put_u8(skb, IFLA_BOND_USE_CARRIER, bond->params.use_carrier)) + goto nla_put_failure; + return 0; nla_put_failure: diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index 2914d649ee3484e51b58b2c76215672e40dd95c0..6fc7bbf0b85f9690b621a84c03f177125e180c09 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c @@ -245,3 +245,17 @@ int bond_option_downdelay_set(struct bonding *bond, int downdelay) return 0; } + +int bond_option_use_carrier_set(struct bonding *bond, int use_carrier) +{ + if ((use_carrier == 0) || (use_carrier == 1)) { + bond->params.use_carrier = use_carrier; + pr_info("%s: Setting use_carrier to %d.\n", + bond->dev->name, use_carrier); + } else { + pr_info("%s: Ignoring invalid use_carrier value %d.\n", + bond->dev->name, use_carrier); + } + + return 0; +} diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index bec20bc08d31baf6381b6736ba88f2bcd60bae4b..114760af9a6dbe1b94484ad32d8bda1a96c05732 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -1097,25 +1097,23 @@ static ssize_t bonding_store_carrier(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { - int new_value, ret = count; + int new_value, ret; struct bonding *bond = to_bond(d); - if (sscanf(buf, "%d", &new_value) != 1) { pr_err("%s: no use_carrier value specified.\n", bond->dev->name); - ret = -EINVAL; - goto out; - } - if ((new_value == 0) || (new_value == 1)) { - bond->params.use_carrier = new_value; - pr_info("%s: Setting use_carrier to %d.\n", - bond->dev->name, new_value); - } else { - pr_info("%s: Ignoring invalid use_carrier value %d.\n", - bond->dev->name, new_value); + return -EINVAL; } -out: + + if (!rtnl_trylock()) + return restart_syscall(); + + ret = bond_option_use_carrier_set(bond, new_value); + if (!ret) + ret = count; + + rtnl_unlock(); return ret; } static DEVICE_ATTR(use_carrier, S_IRUGO | S_IWUSR, diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index f5749b18d1681221bf18458163687aaff8746939..df159da8db3097d0b377e0f382920670edb231b6 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -442,6 +442,7 @@ int bond_option_active_slave_set(struct bonding *bond, struct net_device *slave_ int bond_option_miimon_set(struct bonding *bond, int miimon); int bond_option_updelay_set(struct bonding *bond, int updelay); int bond_option_downdelay_set(struct bonding *bond, int downdelay); +int bond_option_use_carrier_set(struct bonding *bond, int use_carrier); struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond); struct net_device *bond_option_active_slave_get(struct bonding *bond); diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index f955067777101a12d17aeea1433282f3907d79ad..77c41bda36a42893c298ab975ecde15fd37e05d2 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h @@ -334,6 +334,7 @@ enum { IFLA_BOND_MIIMON, IFLA_BOND_UPDELAY, IFLA_BOND_DOWNDELAY, + IFLA_BOND_USE_CARRIER, __IFLA_BOND_MAX, };