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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.