bonding: add slave_changelink support and use it for queue_id
authorNikolay Aleksandrov <nikolay@redhat.com>
Wed, 27 Aug 2014 14:06:46 +0000 (16:06 +0200)
committerDavid S. Miller <davem@davemloft.net>
Tue, 2 Sep 2014 01:32:22 +0000 (18:32 -0700)
This patch adds support for slave_changelink to the bonding and uses it
to give the ability to change the queue_id of the enslaved devices via
netlink. It sets slave_maxtype and uses bond_changelink as a prototype for
bond_slave_changelink.
Example/test command after the iproute2 patch:
 ip link set eth0 type bond_slave queue_id 10

CC: David S. Miller <davem@davemloft.net>
CC: Jay Vosburgh <j.vosburgh@gmail.com>
CC: Veaceslav Falico <vfalico@gmail.com>
CC: Andy Gospodarek <andy@greyhouse.net>
Suggested-by: Jiri Pirko <jiri@resnulli.us>
Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com>
Acked-by: Jiri Pirko <jiri@resnulli.us>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/bonding/bond_netlink.c

index d163e112f04ce00956fedd17221c3c283ff8a3c6..1570deab112e15682db717c331d9323f722d5836 100644 (file)
@@ -107,6 +107,33 @@ static int bond_validate(struct nlattr *tb[], struct nlattr *data[])
        return 0;
 }
 
+static int bond_slave_changelink(struct net_device *bond_dev,
+                                struct net_device *slave_dev,
+                                struct nlattr *tb[], struct nlattr *data[])
+{
+       struct bonding *bond = netdev_priv(bond_dev);
+       struct bond_opt_value newval;
+       int err;
+
+       if (!data)
+               return 0;
+
+       if (data[IFLA_BOND_SLAVE_QUEUE_ID]) {
+               u16 queue_id = nla_get_u16(data[IFLA_BOND_SLAVE_QUEUE_ID]);
+               char queue_id_str[IFNAMSIZ + 7];
+
+               /* queue_id option setting expects slave_name:queue_id */
+               snprintf(queue_id_str, sizeof(queue_id_str), "%s:%u\n",
+                        slave_dev->name, queue_id);
+               bond_opt_initstr(&newval, queue_id_str);
+               err = __bond_opt_set(bond, BOND_OPT_QUEUE_ID, &newval);
+               if (err)
+                       return err;
+       }
+
+       return 0;
+}
+
 static int bond_changelink(struct net_device *bond_dev,
                           struct nlattr *tb[], struct nlattr *data[])
 {
@@ -553,10 +580,12 @@ struct rtnl_link_ops bond_link_ops __read_mostly = {
        .priv_size              = sizeof(struct bonding),
        .setup                  = bond_setup,
        .maxtype                = IFLA_BOND_MAX,
+       .slave_maxtype          = IFLA_BOND_SLAVE_MAX,
        .policy                 = bond_policy,
        .validate               = bond_validate,
        .newlink                = bond_newlink,
        .changelink             = bond_changelink,
+       .slave_changelink       = bond_slave_changelink,
        .get_size               = bond_get_size,
        .fill_info              = bond_fill_info,
        .get_num_tx_queues      = bond_get_num_tx_queues,