diff options
author | sfeldma@cumulusnetworks.com <sfeldma@cumulusnetworks.com> | 2013-12-12 17:10:38 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-12-14 01:07:32 -0500 |
commit | 29c4948293bfc426e52a921f4259eb3676961e81 (patch) | |
tree | 88afaa4d455ab1feb4143275e9a359e4834e720a /drivers/net/bonding | |
parent | 7f28fa10e21376a10d3b9faad5836869465cc376 (diff) |
bonding: add arp_validate netlink support
Add IFLA_BOND_ARP_VALIDATE to allow get/set of bonding parameter
arp_validate 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>
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r-- | drivers/net/bonding/bond_netlink.c | 18 | ||||
-rw-r--r-- | drivers/net/bonding/bond_options.c | 22 | ||||
-rw-r--r-- | drivers/net/bonding/bond_sysfs.c | 30 | ||||
-rw-r--r-- | drivers/net/bonding/bonding.h | 1 |
4 files changed, 49 insertions, 22 deletions
diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c index 6d30e5db9e3c..8588cb91caa9 100644 --- a/drivers/net/bonding/bond_netlink.c +++ b/drivers/net/bonding/bond_netlink.c | |||
@@ -30,6 +30,7 @@ static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = { | |||
30 | [IFLA_BOND_USE_CARRIER] = { .type = NLA_U8 }, | 30 | [IFLA_BOND_USE_CARRIER] = { .type = NLA_U8 }, |
31 | [IFLA_BOND_ARP_INTERVAL] = { .type = NLA_U32 }, | 31 | [IFLA_BOND_ARP_INTERVAL] = { .type = NLA_U32 }, |
32 | [IFLA_BOND_ARP_IP_TARGET] = { .type = NLA_NESTED }, | 32 | [IFLA_BOND_ARP_IP_TARGET] = { .type = NLA_NESTED }, |
33 | [IFLA_BOND_ARP_VALIDATE] = { .type = NLA_U32 }, | ||
33 | }; | 34 | }; |
34 | 35 | ||
35 | static int bond_validate(struct nlattr *tb[], struct nlattr *data[]) | 36 | static int bond_validate(struct nlattr *tb[], struct nlattr *data[]) |
@@ -131,6 +132,19 @@ static int bond_changelink(struct net_device *bond_dev, | |||
131 | if (err) | 132 | if (err) |
132 | return err; | 133 | return err; |
133 | } | 134 | } |
135 | if (data[IFLA_BOND_ARP_VALIDATE]) { | ||
136 | int arp_validate = nla_get_u32(data[IFLA_BOND_ARP_VALIDATE]); | ||
137 | |||
138 | if (arp_validate && miimon) { | ||
139 | pr_err("%s: ARP validating cannot be used with MII monitoring.\n", | ||
140 | bond->dev->name); | ||
141 | return -EINVAL; | ||
142 | } | ||
143 | |||
144 | err = bond_option_arp_validate_set(bond, arp_validate); | ||
145 | if (err) | ||
146 | return err; | ||
147 | } | ||
134 | return 0; | 148 | return 0; |
135 | } | 149 | } |
136 | 150 | ||
@@ -157,6 +171,7 @@ static size_t bond_get_size(const struct net_device *bond_dev) | |||
157 | nla_total_size(sizeof(u32)) + /* IFLA_BOND_ARP_INTERVAL */ | 171 | nla_total_size(sizeof(u32)) + /* IFLA_BOND_ARP_INTERVAL */ |
158 | /* IFLA_BOND_ARP_IP_TARGET */ | 172 | /* IFLA_BOND_ARP_IP_TARGET */ |
159 | nla_total_size(sizeof(u32)) * BOND_MAX_ARP_TARGETS + | 173 | nla_total_size(sizeof(u32)) * BOND_MAX_ARP_TARGETS + |
174 | nla_total_size(sizeof(u32)) + /* IFLA_BOND_ARP_VALIDATE */ | ||
160 | 0; | 175 | 0; |
161 | } | 176 | } |
162 | 177 | ||
@@ -209,6 +224,9 @@ static int bond_fill_info(struct sk_buff *skb, | |||
209 | else | 224 | else |
210 | nla_nest_cancel(skb, targets); | 225 | nla_nest_cancel(skb, targets); |
211 | 226 | ||
227 | if (nla_put_u32(skb, IFLA_BOND_ARP_VALIDATE, bond->params.arp_validate)) | ||
228 | goto nla_put_failure; | ||
229 | |||
212 | return 0; | 230 | return 0; |
213 | 231 | ||
214 | nla_put_failure: | 232 | nla_put_failure: |
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index f8c2e4f17066..698079e94e74 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c | |||
@@ -436,3 +436,25 @@ int bond_option_arp_ip_targets_set(struct bonding *bond, __be32 *targets, | |||
436 | write_unlock_bh(&bond->lock); | 436 | write_unlock_bh(&bond->lock); |
437 | return ret; | 437 | return ret; |
438 | } | 438 | } |
439 | |||
440 | int bond_option_arp_validate_set(struct bonding *bond, int arp_validate) | ||
441 | { | ||
442 | if (bond->params.mode != BOND_MODE_ACTIVEBACKUP) { | ||
443 | pr_err("%s: arp_validate only supported in active-backup mode.\n", | ||
444 | bond->dev->name); | ||
445 | return -EINVAL; | ||
446 | } | ||
447 | pr_info("%s: setting arp_validate to %s (%d).\n", | ||
448 | bond->dev->name, arp_validate_tbl[arp_validate].modename, | ||
449 | arp_validate); | ||
450 | |||
451 | if (bond->dev->flags & IFF_UP) { | ||
452 | if (!arp_validate) | ||
453 | bond->recv_probe = NULL; | ||
454 | else if (bond->params.arp_interval) | ||
455 | bond->recv_probe = bond_arp_rcv; | ||
456 | } | ||
457 | bond->params.arp_validate = arp_validate; | ||
458 | |||
459 | return 0; | ||
460 | } | ||
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index a443bbd0fe86..bda00a01393a 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
@@ -358,35 +358,21 @@ static ssize_t bonding_store_arp_validate(struct device *d, | |||
358 | const char *buf, size_t count) | 358 | const char *buf, size_t count) |
359 | { | 359 | { |
360 | struct bonding *bond = to_bond(d); | 360 | struct bonding *bond = to_bond(d); |
361 | int new_value, ret = count; | 361 | int new_value, ret; |
362 | 362 | ||
363 | if (!rtnl_trylock()) | ||
364 | return restart_syscall(); | ||
365 | new_value = bond_parse_parm(buf, arp_validate_tbl); | 363 | new_value = bond_parse_parm(buf, arp_validate_tbl); |
366 | if (new_value < 0) { | 364 | if (new_value < 0) { |
367 | pr_err("%s: Ignoring invalid arp_validate value %s\n", | 365 | pr_err("%s: Ignoring invalid arp_validate value %s\n", |
368 | bond->dev->name, buf); | 366 | bond->dev->name, buf); |
369 | ret = -EINVAL; | 367 | return -EINVAL; |
370 | goto out; | ||
371 | } | ||
372 | if (bond->params.mode != BOND_MODE_ACTIVEBACKUP) { | ||
373 | pr_err("%s: arp_validate only supported in active-backup mode.\n", | ||
374 | bond->dev->name); | ||
375 | ret = -EINVAL; | ||
376 | goto out; | ||
377 | } | 368 | } |
378 | pr_info("%s: setting arp_validate to %s (%d).\n", | 369 | if (!rtnl_trylock()) |
379 | bond->dev->name, arp_validate_tbl[new_value].modename, | 370 | return restart_syscall(); |
380 | new_value); | 371 | |
372 | ret = bond_option_arp_validate_set(bond, new_value); | ||
373 | if (!ret) | ||
374 | ret = count; | ||
381 | 375 | ||
382 | if (bond->dev->flags & IFF_UP) { | ||
383 | if (!new_value) | ||
384 | bond->recv_probe = NULL; | ||
385 | else if (bond->params.arp_interval) | ||
386 | bond->recv_probe = bond_arp_rcv; | ||
387 | } | ||
388 | bond->params.arp_validate = new_value; | ||
389 | out: | ||
390 | rtnl_unlock(); | 376 | rtnl_unlock(); |
391 | 377 | ||
392 | return ret; | 378 | return ret; |
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index dcdc8095c169..cef10adac6e6 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
@@ -448,6 +448,7 @@ int bond_option_arp_ip_targets_set(struct bonding *bond, __be32 *targets, | |||
448 | int count); | 448 | int count); |
449 | int bond_option_arp_ip_target_add(struct bonding *bond, __be32 target); | 449 | int bond_option_arp_ip_target_add(struct bonding *bond, __be32 target); |
450 | int bond_option_arp_ip_target_rem(struct bonding *bond, __be32 target); | 450 | int bond_option_arp_ip_target_rem(struct bonding *bond, __be32 target); |
451 | int bond_option_arp_validate_set(struct bonding *bond, int arp_validate); | ||
451 | struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond); | 452 | struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond); |
452 | struct net_device *bond_option_active_slave_get(struct bonding *bond); | 453 | struct net_device *bond_option_active_slave_get(struct bonding *bond); |
453 | 454 | ||