diff options
-rw-r--r-- | drivers/net/bonding/bond_netlink.c | 23 | ||||
-rw-r--r-- | include/uapi/linux/if_link.h | 1 |
2 files changed, 23 insertions, 1 deletions
diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c index a94f870a6b60..fe3500bb34e4 100644 --- a/drivers/net/bonding/bond_netlink.c +++ b/drivers/net/bonding/bond_netlink.c | |||
@@ -22,6 +22,7 @@ | |||
22 | 22 | ||
23 | static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = { | 23 | static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = { |
24 | [IFLA_BOND_MODE] = { .type = NLA_U8 }, | 24 | [IFLA_BOND_MODE] = { .type = NLA_U8 }, |
25 | [IFLA_BOND_ACTIVE_SLAVE] = { .type = NLA_U32 }, | ||
25 | }; | 26 | }; |
26 | 27 | ||
27 | static int bond_validate(struct nlattr *tb[], struct nlattr *data[]) | 28 | static int bond_validate(struct nlattr *tb[], struct nlattr *data[]) |
@@ -48,6 +49,22 @@ static int bond_changelink(struct net_device *bond_dev, | |||
48 | if (err) | 49 | if (err) |
49 | return err; | 50 | return err; |
50 | } | 51 | } |
52 | if (data && data[IFLA_BOND_ACTIVE_SLAVE]) { | ||
53 | int ifindex = nla_get_u32(data[IFLA_BOND_ACTIVE_SLAVE]); | ||
54 | struct net_device *slave_dev; | ||
55 | |||
56 | if (ifindex == 0) { | ||
57 | slave_dev = NULL; | ||
58 | } else { | ||
59 | slave_dev = __dev_get_by_index(dev_net(bond_dev), | ||
60 | ifindex); | ||
61 | if (!slave_dev) | ||
62 | return -ENODEV; | ||
63 | } | ||
64 | err = bond_option_active_slave_set(bond, slave_dev); | ||
65 | if (err) | ||
66 | return err; | ||
67 | } | ||
51 | return 0; | 68 | return 0; |
52 | } | 69 | } |
53 | 70 | ||
@@ -66,14 +83,18 @@ static int bond_newlink(struct net *src_net, struct net_device *bond_dev, | |||
66 | static size_t bond_get_size(const struct net_device *bond_dev) | 83 | static size_t bond_get_size(const struct net_device *bond_dev) |
67 | { | 84 | { |
68 | return nla_total_size(sizeof(u8)); /* IFLA_BOND_MODE */ | 85 | return nla_total_size(sizeof(u8)); /* IFLA_BOND_MODE */ |
86 | + nla_total_size(sizeof(u32)); /* IFLA_BOND_ACTIVE_SLAVE */ | ||
69 | } | 87 | } |
70 | 88 | ||
71 | static int bond_fill_info(struct sk_buff *skb, | 89 | static int bond_fill_info(struct sk_buff *skb, |
72 | const struct net_device *bond_dev) | 90 | const struct net_device *bond_dev) |
73 | { | 91 | { |
74 | struct bonding *bond = netdev_priv(bond_dev); | 92 | struct bonding *bond = netdev_priv(bond_dev); |
93 | struct net_device *slave_dev = bond_option_active_slave_get(bond); | ||
75 | 94 | ||
76 | if (nla_put_u8(skb, IFLA_BOND_MODE, bond->params.mode)) | 95 | if (nla_put_u8(skb, IFLA_BOND_MODE, bond->params.mode) || |
96 | (slave_dev && | ||
97 | nla_put_u32(skb, IFLA_BOND_ACTIVE_SLAVE, slave_dev->ifindex))) | ||
77 | goto nla_put_failure; | 98 | goto nla_put_failure; |
78 | return 0; | 99 | return 0; |
79 | 100 | ||
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index 06fd3fe10f3b..8a1e346243b7 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h | |||
@@ -330,6 +330,7 @@ struct ifla_vxlan_port_range { | |||
330 | enum { | 330 | enum { |
331 | IFLA_BOND_UNSPEC, | 331 | IFLA_BOND_UNSPEC, |
332 | IFLA_BOND_MODE, | 332 | IFLA_BOND_MODE, |
333 | IFLA_BOND_ACTIVE_SLAVE, | ||
333 | __IFLA_BOND_MAX, | 334 | __IFLA_BOND_MAX, |
334 | }; | 335 | }; |
335 | 336 | ||