Skip to content

Commit 1d3ee88

Browse files
sfeldma@cumulusnetworks.comdavem330
authored andcommitted
bonding: add netlink attributes to slave link dev
If link is IFF_SLAVE, extend link dev netlink attributes to include slave attributes with new IFLA_SLAVE nest. Add netlink notification (RTM_NEWLINK) when slave status changes from backup to active, or visa-versa. Adds new ndo_get_slave op to net_device_ops to fill skb with IFLA_SLAVE attributes. Currently only used by bonding driver, but could be used by other aggregating devices with slaves. Signed-off-by: Scott Feldman <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 07699f9 commit 1d3ee88

File tree

6 files changed

+118
-2
lines changed

6 files changed

+118
-2
lines changed

drivers/net/bonding/bond_main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3883,6 +3883,7 @@ static const struct net_device_ops bond_netdev_ops = {
38833883
#endif
38843884
.ndo_add_slave = bond_enslave,
38853885
.ndo_del_slave = bond_release,
3886+
.ndo_get_slave = bond_get_slave,
38863887
.ndo_fix_features = bond_fix_features,
38873888
};
38883889

drivers/net/bonding/bond_netlink.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,42 @@
2222
#include <linux/reciprocal_div.h>
2323
#include "bonding.h"
2424

25+
int bond_get_slave(struct net_device *slave_dev, struct sk_buff *skb)
26+
{
27+
struct slave *slave = bond_slave_get_rtnl(slave_dev);
28+
const struct aggregator *agg;
29+
30+
if (nla_put_u8(skb, IFLA_SLAVE_STATE, bond_slave_state(slave)))
31+
goto nla_put_failure;
32+
33+
if (nla_put_u8(skb, IFLA_SLAVE_MII_STATUS, slave->link))
34+
goto nla_put_failure;
35+
36+
if (nla_put_u32(skb, IFLA_SLAVE_LINK_FAILURE_COUNT,
37+
slave->link_failure_count))
38+
goto nla_put_failure;
39+
40+
if (nla_put(skb, IFLA_SLAVE_PERM_HWADDR,
41+
slave_dev->addr_len, slave->perm_hwaddr))
42+
goto nla_put_failure;
43+
44+
if (nla_put_u16(skb, IFLA_SLAVE_QUEUE_ID, slave->queue_id))
45+
goto nla_put_failure;
46+
47+
if (slave->bond->params.mode == BOND_MODE_8023AD) {
48+
agg = SLAVE_AD_INFO(slave).port.aggregator;
49+
if (agg)
50+
if (nla_put_u16(skb, IFLA_SLAVE_AD_AGGREGATOR_ID,
51+
agg->aggregator_identifier))
52+
goto nla_put_failure;
53+
}
54+
55+
return 0;
56+
57+
nla_put_failure:
58+
return -EMSGSIZE;
59+
}
60+
2561
static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = {
2662
[IFLA_BOND_MODE] = { .type = NLA_U8 },
2763
[IFLA_BOND_ACTIVE_SLAVE] = { .type = NLA_U32 },

drivers/net/bonding/bonding.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,12 +285,18 @@ static inline bool bond_is_lb(const struct bonding *bond)
285285

286286
static inline void bond_set_active_slave(struct slave *slave)
287287
{
288-
slave->backup = 0;
288+
if (slave->backup) {
289+
slave->backup = 0;
290+
rtmsg_ifinfo(RTM_NEWLINK, slave->dev, 0, GFP_KERNEL);
291+
}
289292
}
290293

291294
static inline void bond_set_backup_slave(struct slave *slave)
292295
{
293-
slave->backup = 1;
296+
if (!slave->backup) {
297+
slave->backup = 1;
298+
rtmsg_ifinfo(RTM_NEWLINK, slave->dev, 0, GFP_KERNEL);
299+
}
294300
}
295301

296302
static inline int bond_slave_state(struct slave *slave)
@@ -426,6 +432,7 @@ int bond_sysfs_slave_add(struct slave *slave);
426432
void bond_sysfs_slave_del(struct slave *slave);
427433
int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev);
428434
int bond_release(struct net_device *bond_dev, struct net_device *slave_dev);
435+
int bond_get_slave(struct net_device *slave_dev, struct sk_buff *skb);
429436
int bond_xmit_hash(struct bonding *bond, struct sk_buff *skb, int count);
430437
int bond_parse_parm(const char *mode_arg, const struct bond_parm_tbl *tbl);
431438
int bond_parm_tbl_lookup(int mode, const struct bond_parm_tbl *tbl);

include/linux/netdevice.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -921,6 +921,9 @@ struct netdev_phys_port_id {
921921
* int (*ndo_del_slave)(struct net_device *dev, struct net_device *slave_dev);
922922
* Called to release previously enslaved netdev.
923923
*
924+
* int (*ndo_get_slave)(struct net_device *slave_dev, struct sk_buff *skb);
925+
* Called to fill netlink skb with slave info.
926+
*
924927
* Feature/offload setting functions.
925928
* netdev_features_t (*ndo_fix_features)(struct net_device *dev,
926929
* netdev_features_t features);
@@ -1093,6 +1096,8 @@ struct net_device_ops {
10931096
struct net_device *slave_dev);
10941097
int (*ndo_del_slave)(struct net_device *dev,
10951098
struct net_device *slave_dev);
1099+
int (*ndo_get_slave)(struct net_device *slave_dev,
1100+
struct sk_buff *skb);
10961101
netdev_features_t (*ndo_fix_features)(struct net_device *dev,
10971102
netdev_features_t features);
10981103
int (*ndo_set_features)(struct net_device *dev,

include/uapi/linux/if_link.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ enum {
144144
IFLA_NUM_RX_QUEUES,
145145
IFLA_CARRIER,
146146
IFLA_PHYS_PORT_ID,
147+
IFLA_SLAVE,
147148
__IFLA_MAX
148149
};
149150

@@ -368,6 +369,18 @@ enum {
368369

369370
#define IFLA_BOND_AD_INFO_MAX (__IFLA_BOND_AD_INFO_MAX - 1)
370371

372+
enum {
373+
IFLA_SLAVE_STATE,
374+
IFLA_SLAVE_MII_STATUS,
375+
IFLA_SLAVE_LINK_FAILURE_COUNT,
376+
IFLA_SLAVE_PERM_HWADDR,
377+
IFLA_SLAVE_QUEUE_ID,
378+
IFLA_SLAVE_AD_AGGREGATOR_ID,
379+
__IFLA_SLAVE_MAX,
380+
};
381+
382+
#define IFLA_SLAVE_MAX (__IFLA_SLAVE_MAX - 1)
383+
371384
/* SR-IOV virtual function management section */
372385

373386
enum {

net/core/rtnetlink.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,28 @@ static size_t rtnl_port_size(const struct net_device *dev)
721721
return port_self_size;
722722
}
723723

724+
static size_t rtnl_bond_slave_size(const struct net_device *dev)
725+
{
726+
struct net_device *bond;
727+
size_t slave_size =
728+
nla_total_size(sizeof(struct nlattr)) + /* IFLA_SLAVE */
729+
nla_total_size(1) + /* IFLA_SLAVE_STATE */
730+
nla_total_size(1) + /* IFLA_SLAVE_MII_STATUS */
731+
nla_total_size(4) + /* IFLA_SLAVE_LINK_FAILURE_COUNT */
732+
nla_total_size(MAX_ADDR_LEN) + /* IFLA_SLAVE_PERM_HWADDR */
733+
nla_total_size(2) + /* IFLA_SLAVE_QUEUE_ID */
734+
nla_total_size(2) + /* IFLA_SLAVE_AD_AGGREGATOR_ID */
735+
0;
736+
737+
if (netif_is_bond_slave((struct net_device *)dev)) {
738+
bond = netdev_master_upper_dev_get((struct net_device *)dev);
739+
if (bond && bond->netdev_ops->ndo_get_slave)
740+
return slave_size;
741+
}
742+
743+
return 0;
744+
}
745+
724746
static noinline size_t if_nlmsg_size(const struct net_device *dev,
725747
u32 ext_filter_mask)
726748
{
@@ -750,6 +772,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev,
750772
+ rtnl_port_size(dev) /* IFLA_VF_PORTS + IFLA_PORT_SELF */
751773
+ rtnl_link_get_size(dev) /* IFLA_LINKINFO */
752774
+ rtnl_link_get_af_size(dev) /* IFLA_AF_SPEC */
775+
+ rtnl_bond_slave_size(dev) /* IFLA_SLAVE */
753776
+ nla_total_size(MAX_PHYS_PORT_ID_LEN); /* IFLA_PHYS_PORT_ID */
754777
}
755778

@@ -847,6 +870,34 @@ static int rtnl_phys_port_id_fill(struct sk_buff *skb, struct net_device *dev)
847870
return 0;
848871
}
849872

873+
static size_t rtnl_bond_slave_fill(struct sk_buff *skb, struct net_device *dev)
874+
{
875+
struct net_device *bond;
876+
struct nlattr *nest;
877+
int err;
878+
879+
if (!netif_is_bond_slave(dev))
880+
return 0;
881+
882+
bond = netdev_master_upper_dev_get(dev);
883+
if (!bond || !bond->netdev_ops->ndo_get_slave)
884+
return 0;
885+
886+
nest = nla_nest_start(skb, IFLA_SLAVE);
887+
if (!nest)
888+
return -EMSGSIZE;
889+
890+
err = bond->netdev_ops->ndo_get_slave(dev, skb);
891+
if (err) {
892+
nla_nest_cancel(skb, nest);
893+
return (err == -EMSGSIZE) ? err : 0;
894+
}
895+
896+
nla_nest_end(skb, nest);
897+
898+
return 0;
899+
}
900+
850901
static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
851902
int type, u32 pid, u32 seq, u32 change,
852903
unsigned int flags, u32 ext_filter_mask)
@@ -1001,6 +1052,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
10011052
if (rtnl_port_fill(skb, dev))
10021053
goto nla_put_failure;
10031054

1055+
if (rtnl_bond_slave_fill(skb, dev))
1056+
goto nla_put_failure;
1057+
10041058
if (dev->rtnl_link_ops) {
10051059
if (rtnl_link_fill(skb, dev) < 0)
10061060
goto nla_put_failure;

0 commit comments

Comments
 (0)