From: Nikolay Aleksandrov <nikolay@redhat.com>
To: Veaceslav Falico <vfalico@redhat.com>
Cc: netdev@vger.kernel.org, fubar@us.ibm.com, andy@greyhouse.net,
davem@davemloft.net, linux@8192.net, nicolas.2p.debian@free.fr,
rick.jones2@hp.com, mkubecek@suse.cz
Subject: Re: [PATCH v3 net-next 6/6] bonding: add an option to fail when any of arp_ip_target is inaccessible
Date: Fri, 21 Jun 2013 20:07:34 +0200 [thread overview]
Message-ID: <51C49666.1030407@redhat.com> (raw)
In-Reply-To: <1371820284-13280-7-git-send-email-vfalico@redhat.com>
On 06/21/2013 03:11 PM, Veaceslav Falico wrote:
> @@ -590,10 +633,11 @@ static ssize_t bonding_store_arp_targets(struct device *d,
> struct device_attribute *attr,
> const char *buf, size_t count)
> {
> - __be32 newtarget;
> - int i = 0, ret = -EINVAL;
> struct bonding *bond = to_bond(d);
> - __be32 *targets;
> + struct slave *slave;
> + __be32 newtarget, *targets;
> + unsigned long *targets_rx;
> + int ind, i, j, ret = -EINVAL;
>
> targets = bond->params.arp_targets;
> newtarget = in_aton(buf + 1);
> @@ -611,8 +655,8 @@ static ssize_t bonding_store_arp_targets(struct device *d,
> goto out;
> }
>
> - i = bond_get_targets_ip(targets, 0); /* first free slot */
> - if (i == -1) {
> + ind = bond_get_targets_ip(targets, 0); /* first free slot */
> + if (ind == -1) {
> pr_err("%s: ARP target table is full!\n",
> bond->dev->name);
> goto out;
> @@ -620,7 +664,12 @@ static ssize_t bonding_store_arp_targets(struct device *d,
>
> pr_info("%s: adding ARP target %pI4.\n", bond->dev->name,
> &newtarget);
> - targets[i] = newtarget;
> + /* not to race with bond_arp_rcv */
> + write_lock_bh(&bond->lock);
> + bond_for_each_slave(bond, slave, i)
> + slave->target_last_arp_rx[ind] = jiffies;
> + targets[ind] = newtarget;
> + write_unlock_bh(&bond->lock);
> } else if (buf[0] == '-') {
> if ((newtarget == 0) || (newtarget == htonl(INADDR_BROADCAST))) {
> pr_err("%s: invalid ARP target %pI4 specified for removal\n",
> @@ -628,18 +677,32 @@ static ssize_t bonding_store_arp_targets(struct device *d,
> goto out;
> }
>
> - i = bond_get_targets_ip(targets, newtarget);
> - if (i == -1) {
> - pr_info("%s: unable to remove nonexistent ARP target %pI4.\n",
> + ind = bond_get_targets_ip(targets, newtarget);
> + if (ind == -1) {
> + pr_err("%s: unable to remove nonexistent ARP target %pI4.\n",
> bond->dev->name, &newtarget);
> goto out;
> }
>
> + if (ind == 0 && !targets[1] && bond->params.arp_validate)
> + pr_warn("%s: removing last arp target with arp_validate on\n",
> + bond->dev->name);
> +
> pr_info("%s: removing ARP target %pI4.\n", bond->dev->name,
> &newtarget);
> - for (; (i < BOND_MAX_ARP_TARGETS-1) && targets[i+1]; i++)
> +
> + write_lock_bh(&bond->lock);
> + bond_for_each_slave(bond, slave, i) {
> + targets_rx = slave->target_last_arp_rx;
> + j = ind;
> + for (; (j < BOND_MAX_ARP_TARGETS-1) && targets[j+1]; j++)
> + targets_rx[j] = targets_rx[j+1];
> + targets_rx[j] = 0;
> + }
> + for (i = ind; (i < BOND_MAX_ARP_TARGETS-1) && targets[i+1]; i++)
> targets[i] = targets[i+1];
> targets[i] = 0;
> + write_unlock_bh(&bond->lock);
> } else {
> pr_err("no command found in arp_ip_targets file for bond %s. Use +<addr> or -<addr>.\n",
> bond->dev->name);
> @@ -649,6 +712,7 @@ static ssize_t bonding_store_arp_targets(struct device *d,
>
> ret = count;
> out:
> + rtnl_unlock();
A leftover rtnl_unlock here.
Nik
> return ret;
> }
> static DEVICE_ATTR(arp_ip_target, S_IRUGO | S_IWUSR , bonding_show_arp_targets, bonding_store_arp_targets);
> @@ -1623,6 +1687,7 @@ static struct attribute *per_bond_attrs[] = {
> &dev_attr_mode.attr,
> &dev_attr_fail_over_mac.attr,
> &dev_attr_arp_validate.attr,
> + &dev_attr_arp_all_targets.attr,
> &dev_attr_arp_interval.attr,
> &dev_attr_arp_ip_target.attr,
> &dev_attr_downdelay.attr,
> diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
> index 486e532..3fb73cc 100644
> --- a/drivers/net/bonding/bonding.h
> +++ b/drivers/net/bonding/bonding.h
> @@ -144,6 +144,7 @@ struct bond_params {
> u8 num_peer_notif;
> int arp_interval;
> int arp_validate;
> + int arp_all_targets;
> int use_carrier;
> int fail_over_mac;
> int updelay;
> @@ -179,6 +180,7 @@ struct slave {
> int delay;
> unsigned long jiffies;
> unsigned long last_arp_rx;
> + unsigned long target_last_arp_rx[BOND_MAX_ARP_TARGETS];
> s8 link; /* one of BOND_LINK_XXXX */
> s8 new_link;
> u8 backup:1, /* indicates backup slave. Value corresponds with
> @@ -322,6 +324,9 @@ static inline bool bond_is_active_slave(struct slave *slave)
> #define BOND_FOM_ACTIVE 1
> #define BOND_FOM_FOLLOW 2
>
> +#define BOND_ARP_TARGETS_ANY 0
> +#define BOND_ARP_TARGETS_ALL 1
> +
> #define BOND_ARP_VALIDATE_NONE 0
> #define BOND_ARP_VALIDATE_ACTIVE (1 << BOND_STATE_ACTIVE)
> #define BOND_ARP_VALIDATE_BACKUP (1 << BOND_STATE_BACKUP)
> @@ -334,11 +339,31 @@ static inline int slave_do_arp_validate(struct bonding *bond,
> return bond->params.arp_validate & (1 << bond_slave_state(slave));
> }
>
> +/* Get the oldest arp which we've received on this slave for bond's
> + * arp_targets.
> + */
> +static inline unsigned long slave_oldest_target_arp_rx(struct bonding *bond,
> + struct slave *slave)
> +{
> + int i = 1;
> + unsigned long ret = slave->target_last_arp_rx[0];
> +
> + for (; (i < BOND_MAX_ARP_TARGETS) && bond->params.arp_targets[i]; i++)
> + if (time_before(slave->target_last_arp_rx[i], ret))
> + ret = slave->target_last_arp_rx[i];
> +
> + return ret;
> +}
> +
> static inline unsigned long slave_last_rx(struct bonding *bond,
> struct slave *slave)
> {
> - if (slave_do_arp_validate(bond, slave))
> - return slave->last_arp_rx;
> + if (slave_do_arp_validate(bond, slave)) {
> + if (bond->params.arp_all_targets == BOND_ARP_TARGETS_ALL)
> + return slave_oldest_target_arp_rx(bond, slave);
> + else
> + return slave->last_arp_rx;
> + }
>
> return slave->dev->last_rx;
> }
> @@ -486,6 +511,7 @@ extern const struct bond_parm_tbl bond_lacp_tbl[];
> extern const struct bond_parm_tbl bond_mode_tbl[];
> extern const struct bond_parm_tbl xmit_hashtype_tbl[];
> extern const struct bond_parm_tbl arp_validate_tbl[];
> +extern const struct bond_parm_tbl arp_all_targets_tbl[];
> extern const struct bond_parm_tbl fail_over_mac_tbl[];
> extern const struct bond_parm_tbl pri_reselect_tbl[];
> extern struct bond_parm_tbl ad_select_tbl[];
>
next prev parent reply other threads:[~2013-06-21 18:09 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-06-21 13:11 [PATCH v3 net-next 6/6] bonding: add an option to fail when any of arp_ip_target is inaccessible Veaceslav Falico
2013-06-21 18:07 ` Nikolay Aleksandrov [this message]
2013-06-21 18:53 ` Veaceslav Falico
2013-06-21 18:21 ` Jay Vosburgh
2013-06-21 19:21 ` Veaceslav Falico
2013-06-24 9:26 ` Veaceslav Falico
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=51C49666.1030407@redhat.com \
--to=nikolay@redhat.com \
--cc=andy@greyhouse.net \
--cc=davem@davemloft.net \
--cc=fubar@us.ibm.com \
--cc=linux@8192.net \
--cc=mkubecek@suse.cz \
--cc=netdev@vger.kernel.org \
--cc=nicolas.2p.debian@free.fr \
--cc=rick.jones2@hp.com \
--cc=vfalico@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).