aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorsfeldma@cumulusnetworks.com <sfeldma@cumulusnetworks.com>2014-01-17 01:57:56 -0500
committerDavid S. Miller <davem@davemloft.net>2014-01-17 21:51:58 -0500
commit1d3ee88ae0d605629bf369ab0b868dae8ca62a48 (patch)
tree7d547bb8ba12b9417a8f0055a08f1026d6392cf2 /net/core
parent07699f9a7c8d1002e07011d5aa382cd63241eea8 (diff)
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 <sfeldma@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/rtnetlink.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index e6e7d582f901..4f85de7aca33 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -721,6 +721,28 @@ static size_t rtnl_port_size(const struct net_device *dev)
721 return port_self_size; 721 return port_self_size;
722} 722}
723 723
724static 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
724static noinline size_t if_nlmsg_size(const struct net_device *dev, 746static noinline size_t if_nlmsg_size(const struct net_device *dev,
725 u32 ext_filter_mask) 747 u32 ext_filter_mask)
726{ 748{
@@ -750,6 +772,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev,
750 + rtnl_port_size(dev) /* IFLA_VF_PORTS + IFLA_PORT_SELF */ 772 + rtnl_port_size(dev) /* IFLA_VF_PORTS + IFLA_PORT_SELF */
751 + rtnl_link_get_size(dev) /* IFLA_LINKINFO */ 773 + rtnl_link_get_size(dev) /* IFLA_LINKINFO */
752 + rtnl_link_get_af_size(dev) /* IFLA_AF_SPEC */ 774 + rtnl_link_get_af_size(dev) /* IFLA_AF_SPEC */
775 + rtnl_bond_slave_size(dev) /* IFLA_SLAVE */
753 + nla_total_size(MAX_PHYS_PORT_ID_LEN); /* IFLA_PHYS_PORT_ID */ 776 + nla_total_size(MAX_PHYS_PORT_ID_LEN); /* IFLA_PHYS_PORT_ID */
754} 777}
755 778
@@ -847,6 +870,34 @@ static int rtnl_phys_port_id_fill(struct sk_buff *skb, struct net_device *dev)
847 return 0; 870 return 0;
848} 871}
849 872
873static 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
850static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, 901static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
851 int type, u32 pid, u32 seq, u32 change, 902 int type, u32 pid, u32 seq, u32 change,
852 unsigned int flags, u32 ext_filter_mask) 903 unsigned int flags, u32 ext_filter_mask)
@@ -1001,6 +1052,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
1001 if (rtnl_port_fill(skb, dev)) 1052 if (rtnl_port_fill(skb, dev))
1002 goto nla_put_failure; 1053 goto nla_put_failure;
1003 1054
1055 if (rtnl_bond_slave_fill(skb, dev))
1056 goto nla_put_failure;
1057
1004 if (dev->rtnl_link_ops) { 1058 if (dev->rtnl_link_ops) {
1005 if (rtnl_link_fill(skb, dev) < 0) 1059 if (rtnl_link_fill(skb, dev) < 0)
1006 goto nla_put_failure; 1060 goto nla_put_failure;