|
@@ -3459,6 +3459,28 @@ static int bond_xmit_hash_policy_l34(struct sk_buff *skb, int count)
|
|
|
|
|
|
/*-------------------------- Device entry points ----------------------------*/
|
|
/*-------------------------- Device entry points ----------------------------*/
|
|
|
|
|
|
|
|
+static void bond_work_init_all(struct bonding *bond)
|
|
|
|
+{
|
|
|
|
+ INIT_DELAYED_WORK(&bond->mcast_work,
|
|
|
|
+ bond_resend_igmp_join_requests_delayed);
|
|
|
|
+ INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor);
|
|
|
|
+ INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor);
|
|
|
|
+ if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
|
|
|
|
+ INIT_DELAYED_WORK(&bond->arp_work, bond_activebackup_arp_mon);
|
|
|
|
+ else
|
|
|
|
+ INIT_DELAYED_WORK(&bond->arp_work, bond_loadbalance_arp_mon);
|
|
|
|
+ INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void bond_work_cancel_all(struct bonding *bond)
|
|
|
|
+{
|
|
|
|
+ cancel_delayed_work_sync(&bond->mii_work);
|
|
|
|
+ cancel_delayed_work_sync(&bond->arp_work);
|
|
|
|
+ cancel_delayed_work_sync(&bond->alb_work);
|
|
|
|
+ cancel_delayed_work_sync(&bond->ad_work);
|
|
|
|
+ cancel_delayed_work_sync(&bond->mcast_work);
|
|
|
|
+}
|
|
|
|
+
|
|
static int bond_open(struct net_device *bond_dev)
|
|
static int bond_open(struct net_device *bond_dev)
|
|
{
|
|
{
|
|
struct bonding *bond = netdev_priv(bond_dev);
|
|
struct bonding *bond = netdev_priv(bond_dev);
|
|
@@ -3481,41 +3503,27 @@ static int bond_open(struct net_device *bond_dev)
|
|
}
|
|
}
|
|
read_unlock(&bond->lock);
|
|
read_unlock(&bond->lock);
|
|
|
|
|
|
- INIT_DELAYED_WORK(&bond->mcast_work, bond_resend_igmp_join_requests_delayed);
|
|
|
|
|
|
+ bond_work_init_all(bond);
|
|
|
|
|
|
if (bond_is_lb(bond)) {
|
|
if (bond_is_lb(bond)) {
|
|
/* bond_alb_initialize must be called before the timer
|
|
/* bond_alb_initialize must be called before the timer
|
|
* is started.
|
|
* is started.
|
|
*/
|
|
*/
|
|
- if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB))) {
|
|
|
|
- /* something went wrong - fail the open operation */
|
|
|
|
|
|
+ if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB)))
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
- }
|
|
|
|
-
|
|
|
|
- INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor);
|
|
|
|
queue_delayed_work(bond->wq, &bond->alb_work, 0);
|
|
queue_delayed_work(bond->wq, &bond->alb_work, 0);
|
|
}
|
|
}
|
|
|
|
|
|
- if (bond->params.miimon) { /* link check interval, in milliseconds. */
|
|
|
|
- INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor);
|
|
|
|
|
|
+ if (bond->params.miimon) /* link check interval, in milliseconds. */
|
|
queue_delayed_work(bond->wq, &bond->mii_work, 0);
|
|
queue_delayed_work(bond->wq, &bond->mii_work, 0);
|
|
- }
|
|
|
|
|
|
|
|
if (bond->params.arp_interval) { /* arp interval, in milliseconds. */
|
|
if (bond->params.arp_interval) { /* arp interval, in milliseconds. */
|
|
- if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
|
|
|
|
- INIT_DELAYED_WORK(&bond->arp_work,
|
|
|
|
- bond_activebackup_arp_mon);
|
|
|
|
- else
|
|
|
|
- INIT_DELAYED_WORK(&bond->arp_work,
|
|
|
|
- bond_loadbalance_arp_mon);
|
|
|
|
-
|
|
|
|
queue_delayed_work(bond->wq, &bond->arp_work, 0);
|
|
queue_delayed_work(bond->wq, &bond->arp_work, 0);
|
|
if (bond->params.arp_validate)
|
|
if (bond->params.arp_validate)
|
|
bond->recv_probe = bond_arp_rcv;
|
|
bond->recv_probe = bond_arp_rcv;
|
|
}
|
|
}
|
|
|
|
|
|
if (bond->params.mode == BOND_MODE_8023AD) {
|
|
if (bond->params.mode == BOND_MODE_8023AD) {
|
|
- INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler);
|
|
|
|
queue_delayed_work(bond->wq, &bond->ad_work, 0);
|
|
queue_delayed_work(bond->wq, &bond->ad_work, 0);
|
|
/* register to receive LACPDUs */
|
|
/* register to receive LACPDUs */
|
|
bond->recv_probe = bond_3ad_lacpdu_recv;
|
|
bond->recv_probe = bond_3ad_lacpdu_recv;
|
|
@@ -3530,34 +3538,10 @@ static int bond_close(struct net_device *bond_dev)
|
|
struct bonding *bond = netdev_priv(bond_dev);
|
|
struct bonding *bond = netdev_priv(bond_dev);
|
|
|
|
|
|
write_lock_bh(&bond->lock);
|
|
write_lock_bh(&bond->lock);
|
|
-
|
|
|
|
bond->send_peer_notif = 0;
|
|
bond->send_peer_notif = 0;
|
|
-
|
|
|
|
write_unlock_bh(&bond->lock);
|
|
write_unlock_bh(&bond->lock);
|
|
|
|
|
|
- if (bond->params.miimon) { /* link check interval, in milliseconds. */
|
|
|
|
- cancel_delayed_work_sync(&bond->mii_work);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (bond->params.arp_interval) { /* arp interval, in milliseconds. */
|
|
|
|
- cancel_delayed_work_sync(&bond->arp_work);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- switch (bond->params.mode) {
|
|
|
|
- case BOND_MODE_8023AD:
|
|
|
|
- cancel_delayed_work_sync(&bond->ad_work);
|
|
|
|
- break;
|
|
|
|
- case BOND_MODE_TLB:
|
|
|
|
- case BOND_MODE_ALB:
|
|
|
|
- cancel_delayed_work_sync(&bond->alb_work);
|
|
|
|
- break;
|
|
|
|
- default:
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (delayed_work_pending(&bond->mcast_work))
|
|
|
|
- cancel_delayed_work_sync(&bond->mcast_work);
|
|
|
|
-
|
|
|
|
|
|
+ bond_work_cancel_all(bond);
|
|
if (bond_is_lb(bond)) {
|
|
if (bond_is_lb(bond)) {
|
|
/* Must be called only after all
|
|
/* Must be called only after all
|
|
* slaves have been released
|
|
* slaves have been released
|
|
@@ -4436,26 +4420,6 @@ static void bond_setup(struct net_device *bond_dev)
|
|
bond_dev->features |= bond_dev->hw_features;
|
|
bond_dev->features |= bond_dev->hw_features;
|
|
}
|
|
}
|
|
|
|
|
|
-static void bond_work_cancel_all(struct bonding *bond)
|
|
|
|
-{
|
|
|
|
- if (bond->params.miimon && delayed_work_pending(&bond->mii_work))
|
|
|
|
- cancel_delayed_work_sync(&bond->mii_work);
|
|
|
|
-
|
|
|
|
- if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work))
|
|
|
|
- cancel_delayed_work_sync(&bond->arp_work);
|
|
|
|
-
|
|
|
|
- if (bond->params.mode == BOND_MODE_ALB &&
|
|
|
|
- delayed_work_pending(&bond->alb_work))
|
|
|
|
- cancel_delayed_work_sync(&bond->alb_work);
|
|
|
|
-
|
|
|
|
- if (bond->params.mode == BOND_MODE_8023AD &&
|
|
|
|
- delayed_work_pending(&bond->ad_work))
|
|
|
|
- cancel_delayed_work_sync(&bond->ad_work);
|
|
|
|
-
|
|
|
|
- if (delayed_work_pending(&bond->mcast_work))
|
|
|
|
- cancel_delayed_work_sync(&bond->mcast_work);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
/*
|
|
/*
|
|
* Destroy a bonding device.
|
|
* Destroy a bonding device.
|
|
* Must be under rtnl_lock when this function is called.
|
|
* Must be under rtnl_lock when this function is called.
|
|
@@ -4706,12 +4670,13 @@ static int bond_check_params(struct bond_params *params)
|
|
arp_ip_count++) {
|
|
arp_ip_count++) {
|
|
/* not complete check, but should be good enough to
|
|
/* not complete check, but should be good enough to
|
|
catch mistakes */
|
|
catch mistakes */
|
|
- if (!isdigit(arp_ip_target[arp_ip_count][0])) {
|
|
|
|
|
|
+ __be32 ip = in_aton(arp_ip_target[arp_ip_count]);
|
|
|
|
+ if (!isdigit(arp_ip_target[arp_ip_count][0]) ||
|
|
|
|
+ ip == 0 || ip == htonl(INADDR_BROADCAST)) {
|
|
pr_warning("Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed\n",
|
|
pr_warning("Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed\n",
|
|
arp_ip_target[arp_ip_count]);
|
|
arp_ip_target[arp_ip_count]);
|
|
arp_interval = 0;
|
|
arp_interval = 0;
|
|
} else {
|
|
} else {
|
|
- __be32 ip = in_aton(arp_ip_target[arp_ip_count]);
|
|
|
|
arp_target[arp_ip_count] = ip;
|
|
arp_target[arp_ip_count] = ip;
|
|
}
|
|
}
|
|
}
|
|
}
|