bonding: add arp_all_targets netlink support
authorsfeldma@cumulusnetworks.com <sfeldma@cumulusnetworks.com>
Thu, 12 Dec 2013 22:10:45 +0000 (14:10 -0800)
committerDavid S. Miller <davem@davemloft.net>
Sat, 14 Dec 2013 06:07:32 +0000 (01:07 -0500)
Add IFLA_BOND_ARP_ALL_TARGETS to allow get/set of bonding parameter
arp_all_targets via netlink.

Signed-off-by: Scott Feldman <sfeldma@cumulusnetworks.com>
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/bonding/bond_netlink.c
drivers/net/bonding/bond_options.c
drivers/net/bonding/bond_sysfs.c
drivers/net/bonding/bonding.h
include/uapi/linux/if_link.h

index 8588cb91caa99c4c69efcd143e73756872bff98f..d7d84db9eed7b834f34bc5cb4c9240792fb642ed 100644 (file)
@@ -31,6 +31,7 @@ static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = {
        [IFLA_BOND_ARP_INTERVAL]        = { .type = NLA_U32 },
        [IFLA_BOND_ARP_IP_TARGET]       = { .type = NLA_NESTED },
        [IFLA_BOND_ARP_VALIDATE]        = { .type = NLA_U32 },
+       [IFLA_BOND_ARP_ALL_TARGETS]     = { .type = NLA_U32 },
 };
 
 static int bond_validate(struct nlattr *tb[], struct nlattr *data[])
@@ -145,6 +146,14 @@ static int bond_changelink(struct net_device *bond_dev,
                if (err)
                        return err;
        }
+       if (data[IFLA_BOND_ARP_ALL_TARGETS]) {
+               int arp_all_targets =
+                       nla_get_u32(data[IFLA_BOND_ARP_ALL_TARGETS]);
+
+               err = bond_option_arp_all_targets_set(bond, arp_all_targets);
+               if (err)
+                       return err;
+       }
        return 0;
 }
 
@@ -172,6 +181,7 @@ static size_t bond_get_size(const struct net_device *bond_dev)
                                                /* IFLA_BOND_ARP_IP_TARGET */
                nla_total_size(sizeof(u32)) * BOND_MAX_ARP_TARGETS +
                nla_total_size(sizeof(u32)) +   /* IFLA_BOND_ARP_VALIDATE */
+               nla_total_size(sizeof(u32)) +   /* IFLA_BOND_ARP_ALL_TARGETS */
                0;
 }
 
@@ -227,6 +237,10 @@ static int bond_fill_info(struct sk_buff *skb,
        if (nla_put_u32(skb, IFLA_BOND_ARP_VALIDATE, bond->params.arp_validate))
                goto nla_put_failure;
 
+       if (nla_put_u32(skb, IFLA_BOND_ARP_ALL_TARGETS,
+                       bond->params.arp_all_targets))
+               goto nla_put_failure;
+
        return 0;
 
 nla_put_failure:
index 698079e94e74442e01572272f55695b4d3be3877..dfef673d53d1089617aa1c25557987c7b9e2856c 100644 (file)
@@ -458,3 +458,14 @@ int bond_option_arp_validate_set(struct bonding *bond, int arp_validate)
 
        return 0;
 }
+
+int bond_option_arp_all_targets_set(struct bonding *bond, int arp_all_targets)
+{
+       pr_info("%s: setting arp_all_targets to %s (%d).\n",
+               bond->dev->name, arp_all_targets_tbl[arp_all_targets].modename,
+               arp_all_targets);
+
+       bond->params.arp_all_targets = arp_all_targets;
+
+       return 0;
+}
index bda00a01393adccb951c654bc33da2ed711f9c8c..dad9bea95122d30ff6a41bbee618fa093e4e2682 100644 (file)
@@ -399,7 +399,7 @@ static ssize_t bonding_store_arp_all_targets(struct device *d,
                                          const char *buf, size_t count)
 {
        struct bonding *bond = to_bond(d);
-       int new_value;
+       int new_value, ret;
 
        new_value = bond_parse_parm(buf, arp_all_targets_tbl);
        if (new_value < 0) {
@@ -407,13 +407,17 @@ static ssize_t bonding_store_arp_all_targets(struct device *d,
                       bond->dev->name, buf);
                return -EINVAL;
        }
-       pr_info("%s: setting arp_all_targets to %s (%d).\n",
-               bond->dev->name, arp_all_targets_tbl[new_value].modename,
-               new_value);
 
-       bond->params.arp_all_targets = new_value;
+       if (!rtnl_trylock())
+               return restart_syscall();
 
-       return count;
+       ret = bond_option_arp_all_targets_set(bond, new_value);
+       if (!ret)
+               ret = count;
+
+       rtnl_unlock();
+
+       return ret;
 }
 
 static DEVICE_ATTR(arp_all_targets, S_IRUGO | S_IWUSR,
index cef10adac6e654b5e2f01f958500cb1bcb923de7..8283cbdec50aa40099b380b5954a5e73308e6b36 100644 (file)
@@ -449,6 +449,7 @@ int bond_option_arp_ip_targets_set(struct bonding *bond, __be32 *targets,
 int bond_option_arp_ip_target_add(struct bonding *bond, __be32 target);
 int bond_option_arp_ip_target_rem(struct bonding *bond, __be32 target);
 int bond_option_arp_validate_set(struct bonding *bond, int arp_validate);
+int bond_option_arp_all_targets_set(struct bonding *bond, int arp_all_targets);
 struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond);
 struct net_device *bond_option_active_slave_get(struct bonding *bond);
 
index 3ba16fa9ad6c3dcf5c6615702bbf038a4dba836a..a897b7e22541dc51af02db9d9049527ed152bb0d 100644 (file)
@@ -338,6 +338,7 @@ enum {
        IFLA_BOND_ARP_INTERVAL,
        IFLA_BOND_ARP_IP_TARGET,
        IFLA_BOND_ARP_VALIDATE,
+       IFLA_BOND_ARP_ALL_TARGETS,
        __IFLA_BOND_MAX,
 };