bonding: add Netlink support mode option
authorJiri Pirko <jiri@resnulli.us>
Fri, 18 Oct 2013 15:43:38 +0000 (17:43 +0200)
committerDavid S. Miller <davem@davemloft.net>
Sat, 19 Oct 2013 22:58:46 +0000 (18:58 -0400)
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/bonding/bond_netlink.c
include/uapi/linux/if_link.h

index 3e5c5f80c32085af920d7ec4a5b9c5d9366d8ad9..a94f870a6b60327783bfdc945c7ddbefe2b4d53f 100644 (file)
 #include <net/rtnetlink.h>
 #include "bonding.h"
 
+static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = {
+       [IFLA_BOND_MODE]                = { .type = NLA_U8 },
+};
+
 static int bond_validate(struct nlattr *tb[], struct nlattr *data[])
 {
        if (tb[IFLA_ADDRESS]) {
@@ -31,11 +35,63 @@ static int bond_validate(struct nlattr *tb[], struct nlattr *data[])
        return 0;
 }
 
+static int bond_changelink(struct net_device *bond_dev,
+                          struct nlattr *tb[], struct nlattr *data[])
+{
+       struct bonding *bond = netdev_priv(bond_dev);
+       int err;
+
+       if (data && data[IFLA_BOND_MODE]) {
+               int mode = nla_get_u8(data[IFLA_BOND_MODE]);
+
+               err = bond_option_mode_set(bond, mode);
+               if (err)
+                       return err;
+       }
+       return 0;
+}
+
+static int bond_newlink(struct net *src_net, struct net_device *bond_dev,
+                       struct nlattr *tb[], struct nlattr *data[])
+{
+       int err;
+
+       err = bond_changelink(bond_dev, tb, data);
+       if (err < 0)
+               return err;
+
+       return register_netdevice(bond_dev);
+}
+
+static size_t bond_get_size(const struct net_device *bond_dev)
+{
+       return nla_total_size(sizeof(u8));      /* IFLA_BOND_MODE */
+}
+
+static int bond_fill_info(struct sk_buff *skb,
+                         const struct net_device *bond_dev)
+{
+       struct bonding *bond = netdev_priv(bond_dev);
+
+       if (nla_put_u8(skb, IFLA_BOND_MODE, bond->params.mode))
+               goto nla_put_failure;
+       return 0;
+
+nla_put_failure:
+       return -EMSGSIZE;
+}
+
 struct rtnl_link_ops bond_link_ops __read_mostly = {
        .kind                   = "bond",
        .priv_size              = sizeof(struct bonding),
        .setup                  = bond_setup,
+       .maxtype                = IFLA_BOND_MAX,
+       .policy                 = bond_policy,
        .validate               = bond_validate,
+       .newlink                = bond_newlink,
+       .changelink             = bond_changelink,
+       .get_size               = bond_get_size,
+       .fill_info              = bond_fill_info,
        .get_num_tx_queues      = bond_get_num_tx_queues,
        .get_num_rx_queues      = bond_get_num_tx_queues, /* Use the same number
                                                             as for TX queues */
index 80394e8dc3a348ed6ac7779a410c0bcda80ac284..06fd3fe10f3b2108a04fc8c51ae59e7dc8d45e5e 100644 (file)
@@ -325,6 +325,16 @@ struct ifla_vxlan_port_range {
        __be16  high;
 };
 
+/* Bonding section */
+
+enum {
+       IFLA_BOND_UNSPEC,
+       IFLA_BOND_MODE,
+       __IFLA_BOND_MAX,
+};
+
+#define IFLA_BOND_MAX  (__IFLA_BOND_MAX - 1)
+
 /* SR-IOV virtual function management section */
 
 enum {