mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	bonding: add an option to specify a delay between peer notifications
Currently, gratuitous ARP/ND packets are sent every `miimon'
milliseconds. This commit allows a user to specify a custom delay
through a new option, `peer_notif_delay'.
Like for `updelay' and `downdelay', this delay should be a multiple of
`miimon' to avoid managing an additional work queue. The configuration
logic is copied from `updelay' and `downdelay'. However, the default
value cannot be set using a module parameter: Netlink or sysfs should
be used to configure this feature.
When setting `miimon' to 100 and `peer_notif_delay' to 500, we can
observe the 500 ms delay is respected:
    20:30:19.354693 ARP, Request who-has 203.0.113.10 tell 203.0.113.10, length 28
    20:30:19.874892 ARP, Request who-has 203.0.113.10 tell 203.0.113.10, length 28
    20:30:20.394919 ARP, Request who-has 203.0.113.10 tell 203.0.113.10, length 28
    20:30:20.914963 ARP, Request who-has 203.0.113.10 tell 203.0.113.10, length 28
In bond_mii_monitor(), I have tried to keep the lock logic readable.
The change is due to the fact we cannot rely on a notification to
lower the value of `bond->send_peer_notif' as `NETDEV_NOTIFY_PEERS' is
only triggered once every N times, while we need to decrement the
counter each time.
iproute2 also needs to be updated to be able to specify this new
attribute through `ip link'.
Signed-off-by: Vincent Bernat <vincent@bernat.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
			
			
This commit is contained in:
		
							parent
							
								
									2368a870d6
								
							
						
					
					
						commit
						07a4ddec3c
					
				
					 9 changed files with 98 additions and 37 deletions
				
			
		| 
						 | 
					@ -796,6 +796,8 @@ static bool bond_should_notify_peers(struct bonding *bond)
 | 
				
			||||||
		   slave ? slave->dev->name : "NULL");
 | 
							   slave ? slave->dev->name : "NULL");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!slave || !bond->send_peer_notif ||
 | 
						if (!slave || !bond->send_peer_notif ||
 | 
				
			||||||
 | 
						    bond->send_peer_notif %
 | 
				
			||||||
 | 
						    max(1, bond->params.peer_notif_delay) != 0 ||
 | 
				
			||||||
	    !netif_carrier_ok(bond->dev) ||
 | 
						    !netif_carrier_ok(bond->dev) ||
 | 
				
			||||||
	    test_bit(__LINK_STATE_LINKWATCH_PENDING, &slave->dev->state))
 | 
						    test_bit(__LINK_STATE_LINKWATCH_PENDING, &slave->dev->state))
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
| 
						 | 
					@ -886,17 +888,20 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (netif_running(bond->dev)) {
 | 
								if (netif_running(bond->dev)) {
 | 
				
			||||||
				bond->send_peer_notif =
 | 
									bond->send_peer_notif =
 | 
				
			||||||
					bond->params.num_peer_notif;
 | 
										bond->params.num_peer_notif *
 | 
				
			||||||
 | 
										max(1, bond->params.peer_notif_delay);
 | 
				
			||||||
				should_notify_peers =
 | 
									should_notify_peers =
 | 
				
			||||||
					bond_should_notify_peers(bond);
 | 
										bond_should_notify_peers(bond);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			call_netdevice_notifiers(NETDEV_BONDING_FAILOVER, bond->dev);
 | 
								call_netdevice_notifiers(NETDEV_BONDING_FAILOVER, bond->dev);
 | 
				
			||||||
			if (should_notify_peers)
 | 
								if (should_notify_peers) {
 | 
				
			||||||
 | 
									bond->send_peer_notif--;
 | 
				
			||||||
				call_netdevice_notifiers(NETDEV_NOTIFY_PEERS,
 | 
									call_netdevice_notifiers(NETDEV_NOTIFY_PEERS,
 | 
				
			||||||
							 bond->dev);
 | 
												 bond->dev);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* resend IGMP joins since active slave has changed or
 | 
						/* resend IGMP joins since active slave has changed or
 | 
				
			||||||
	 * all were sent on curr_active_slave.
 | 
						 * all were sent on curr_active_slave.
 | 
				
			||||||
| 
						 | 
					@ -2279,6 +2284,7 @@ static void bond_mii_monitor(struct work_struct *work)
 | 
				
			||||||
	struct bonding *bond = container_of(work, struct bonding,
 | 
						struct bonding *bond = container_of(work, struct bonding,
 | 
				
			||||||
					    mii_work.work);
 | 
										    mii_work.work);
 | 
				
			||||||
	bool should_notify_peers = false;
 | 
						bool should_notify_peers = false;
 | 
				
			||||||
 | 
						bool commit;
 | 
				
			||||||
	unsigned long delay;
 | 
						unsigned long delay;
 | 
				
			||||||
	struct slave *slave;
 | 
						struct slave *slave;
 | 
				
			||||||
	struct list_head *iter;
 | 
						struct list_head *iter;
 | 
				
			||||||
| 
						 | 
					@ -2289,12 +2295,19 @@ static void bond_mii_monitor(struct work_struct *work)
 | 
				
			||||||
		goto re_arm;
 | 
							goto re_arm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rcu_read_lock();
 | 
						rcu_read_lock();
 | 
				
			||||||
 | 
					 | 
				
			||||||
	should_notify_peers = bond_should_notify_peers(bond);
 | 
						should_notify_peers = bond_should_notify_peers(bond);
 | 
				
			||||||
 | 
						commit = !!bond_miimon_inspect(bond);
 | 
				
			||||||
	if (bond_miimon_inspect(bond)) {
 | 
						if (bond->send_peer_notif) {
 | 
				
			||||||
		rcu_read_unlock();
 | 
							rcu_read_unlock();
 | 
				
			||||||
 | 
							if (rtnl_trylock()) {
 | 
				
			||||||
 | 
								bond->send_peer_notif--;
 | 
				
			||||||
 | 
								rtnl_unlock();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							rcu_read_unlock();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (commit) {
 | 
				
			||||||
		/* Race avoidance with bond_close cancel of workqueue */
 | 
							/* Race avoidance with bond_close cancel of workqueue */
 | 
				
			||||||
		if (!rtnl_trylock()) {
 | 
							if (!rtnl_trylock()) {
 | 
				
			||||||
			delay = 1;
 | 
								delay = 1;
 | 
				
			||||||
| 
						 | 
					@ -2308,8 +2321,7 @@ static void bond_mii_monitor(struct work_struct *work)
 | 
				
			||||||
		bond_miimon_commit(bond);
 | 
							bond_miimon_commit(bond);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		rtnl_unlock();	/* might sleep, hold no other locks */
 | 
							rtnl_unlock();	/* might sleep, hold no other locks */
 | 
				
			||||||
	} else
 | 
						}
 | 
				
			||||||
		rcu_read_unlock();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
re_arm:
 | 
					re_arm:
 | 
				
			||||||
	if (bond->params.miimon)
 | 
						if (bond->params.miimon)
 | 
				
			||||||
| 
						 | 
					@ -3065,10 +3077,6 @@ static int bond_master_netdev_event(unsigned long event,
 | 
				
			||||||
	case NETDEV_REGISTER:
 | 
						case NETDEV_REGISTER:
 | 
				
			||||||
		bond_create_proc_entry(event_bond);
 | 
							bond_create_proc_entry(event_bond);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case NETDEV_NOTIFY_PEERS:
 | 
					 | 
				
			||||||
		if (event_bond->send_peer_notif)
 | 
					 | 
				
			||||||
			event_bond->send_peer_notif--;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -4691,6 +4699,7 @@ static int bond_check_params(struct bond_params *params)
 | 
				
			||||||
	params->arp_all_targets = arp_all_targets_value;
 | 
						params->arp_all_targets = arp_all_targets_value;
 | 
				
			||||||
	params->updelay = updelay;
 | 
						params->updelay = updelay;
 | 
				
			||||||
	params->downdelay = downdelay;
 | 
						params->downdelay = downdelay;
 | 
				
			||||||
 | 
						params->peer_notif_delay = 0;
 | 
				
			||||||
	params->use_carrier = use_carrier;
 | 
						params->use_carrier = use_carrier;
 | 
				
			||||||
	params->lacp_fast = lacp_fast;
 | 
						params->lacp_fast = lacp_fast;
 | 
				
			||||||
	params->primary[0] = 0;
 | 
						params->primary[0] = 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -108,6 +108,7 @@ static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = {
 | 
				
			||||||
	[IFLA_BOND_AD_ACTOR_SYSTEM]	= { .type = NLA_BINARY,
 | 
						[IFLA_BOND_AD_ACTOR_SYSTEM]	= { .type = NLA_BINARY,
 | 
				
			||||||
					    .len  = ETH_ALEN },
 | 
										    .len  = ETH_ALEN },
 | 
				
			||||||
	[IFLA_BOND_TLB_DYNAMIC_LB]	= { .type = NLA_U8 },
 | 
						[IFLA_BOND_TLB_DYNAMIC_LB]	= { .type = NLA_U8 },
 | 
				
			||||||
 | 
						[IFLA_BOND_PEER_NOTIF_DELAY]    = { .type = NLA_U32 },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct nla_policy bond_slave_policy[IFLA_BOND_SLAVE_MAX + 1] = {
 | 
					static const struct nla_policy bond_slave_policy[IFLA_BOND_SLAVE_MAX + 1] = {
 | 
				
			||||||
| 
						 | 
					@ -215,6 +216,14 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
 | 
				
			||||||
		if (err)
 | 
							if (err)
 | 
				
			||||||
			return err;
 | 
								return err;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if (data[IFLA_BOND_PEER_NOTIF_DELAY]) {
 | 
				
			||||||
 | 
							int delay = nla_get_u32(data[IFLA_BOND_PEER_NOTIF_DELAY]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							bond_opt_initval(&newval, delay);
 | 
				
			||||||
 | 
							err = __bond_opt_set(bond, BOND_OPT_PEER_NOTIF_DELAY, &newval);
 | 
				
			||||||
 | 
							if (err)
 | 
				
			||||||
 | 
								return err;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if (data[IFLA_BOND_USE_CARRIER]) {
 | 
						if (data[IFLA_BOND_USE_CARRIER]) {
 | 
				
			||||||
		int use_carrier = nla_get_u8(data[IFLA_BOND_USE_CARRIER]);
 | 
							int use_carrier = nla_get_u8(data[IFLA_BOND_USE_CARRIER]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -494,6 +503,7 @@ static size_t bond_get_size(const struct net_device *bond_dev)
 | 
				
			||||||
		nla_total_size(sizeof(u16)) + /* IFLA_BOND_AD_USER_PORT_KEY */
 | 
							nla_total_size(sizeof(u16)) + /* IFLA_BOND_AD_USER_PORT_KEY */
 | 
				
			||||||
		nla_total_size(ETH_ALEN) + /* IFLA_BOND_AD_ACTOR_SYSTEM */
 | 
							nla_total_size(ETH_ALEN) + /* IFLA_BOND_AD_ACTOR_SYSTEM */
 | 
				
			||||||
		nla_total_size(sizeof(u8)) + /* IFLA_BOND_TLB_DYNAMIC_LB */
 | 
							nla_total_size(sizeof(u8)) + /* IFLA_BOND_TLB_DYNAMIC_LB */
 | 
				
			||||||
 | 
							nla_total_size(sizeof(u32)) +	/* IFLA_BOND_PEER_NOTIF_DELAY */
 | 
				
			||||||
		0;
 | 
							0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -536,6 +546,10 @@ static int bond_fill_info(struct sk_buff *skb,
 | 
				
			||||||
			bond->params.downdelay * bond->params.miimon))
 | 
								bond->params.downdelay * bond->params.miimon))
 | 
				
			||||||
		goto nla_put_failure;
 | 
							goto nla_put_failure;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (nla_put_u32(skb, IFLA_BOND_PEER_NOTIF_DELAY,
 | 
				
			||||||
 | 
								bond->params.downdelay * bond->params.miimon))
 | 
				
			||||||
 | 
							goto nla_put_failure;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (nla_put_u8(skb, IFLA_BOND_USE_CARRIER, bond->params.use_carrier))
 | 
						if (nla_put_u8(skb, IFLA_BOND_USE_CARRIER, bond->params.use_carrier))
 | 
				
			||||||
		goto nla_put_failure;
 | 
							goto nla_put_failure;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,6 +24,8 @@ static int bond_option_updelay_set(struct bonding *bond,
 | 
				
			||||||
				   const struct bond_opt_value *newval);
 | 
									   const struct bond_opt_value *newval);
 | 
				
			||||||
static int bond_option_downdelay_set(struct bonding *bond,
 | 
					static int bond_option_downdelay_set(struct bonding *bond,
 | 
				
			||||||
				     const struct bond_opt_value *newval);
 | 
									     const struct bond_opt_value *newval);
 | 
				
			||||||
 | 
					static int bond_option_peer_notif_delay_set(struct bonding *bond,
 | 
				
			||||||
 | 
										    const struct bond_opt_value *newval);
 | 
				
			||||||
static int bond_option_use_carrier_set(struct bonding *bond,
 | 
					static int bond_option_use_carrier_set(struct bonding *bond,
 | 
				
			||||||
				       const struct bond_opt_value *newval);
 | 
									       const struct bond_opt_value *newval);
 | 
				
			||||||
static int bond_option_arp_interval_set(struct bonding *bond,
 | 
					static int bond_option_arp_interval_set(struct bonding *bond,
 | 
				
			||||||
| 
						 | 
					@ -424,6 +426,13 @@ static const struct bond_option bond_opts[BOND_OPT_LAST] = {
 | 
				
			||||||
		.desc = "Number of peer notifications to send on failover event",
 | 
							.desc = "Number of peer notifications to send on failover event",
 | 
				
			||||||
		.values = bond_num_peer_notif_tbl,
 | 
							.values = bond_num_peer_notif_tbl,
 | 
				
			||||||
		.set = bond_option_num_peer_notif_set
 | 
							.set = bond_option_num_peer_notif_set
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						[BOND_OPT_PEER_NOTIF_DELAY] = {
 | 
				
			||||||
 | 
							.id = BOND_OPT_PEER_NOTIF_DELAY,
 | 
				
			||||||
 | 
							.name = "peer_notif_delay",
 | 
				
			||||||
 | 
							.desc = "Delay between each peer notification on failover event, in milliseconds",
 | 
				
			||||||
 | 
							.values = bond_intmax_tbl,
 | 
				
			||||||
 | 
							.set = bond_option_peer_notif_delay_set
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -841,6 +850,9 @@ static int bond_option_miimon_set(struct bonding *bond,
 | 
				
			||||||
	if (bond->params.downdelay)
 | 
						if (bond->params.downdelay)
 | 
				
			||||||
		netdev_dbg(bond->dev, "Note: Updating downdelay (to %d) since it is a multiple of the miimon value\n",
 | 
							netdev_dbg(bond->dev, "Note: Updating downdelay (to %d) since it is a multiple of the miimon value\n",
 | 
				
			||||||
			   bond->params.downdelay * bond->params.miimon);
 | 
								   bond->params.downdelay * bond->params.miimon);
 | 
				
			||||||
 | 
						if (bond->params.peer_notif_delay)
 | 
				
			||||||
 | 
							netdev_dbg(bond->dev, "Note: Updating peer_notif_delay (to %d) since it is a multiple of the miimon value\n",
 | 
				
			||||||
 | 
								   bond->params.peer_notif_delay * bond->params.miimon);
 | 
				
			||||||
	if (newval->value && bond->params.arp_interval) {
 | 
						if (newval->value && bond->params.arp_interval) {
 | 
				
			||||||
		netdev_dbg(bond->dev, "MII monitoring cannot be used with ARP monitoring - disabling ARP monitoring...\n");
 | 
							netdev_dbg(bond->dev, "MII monitoring cannot be used with ARP monitoring - disabling ARP monitoring...\n");
 | 
				
			||||||
		bond->params.arp_interval = 0;
 | 
							bond->params.arp_interval = 0;
 | 
				
			||||||
| 
						 | 
					@ -864,52 +876,59 @@ static int bond_option_miimon_set(struct bonding *bond,
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Set up and down delays. These must be multiples of the
 | 
					/* Set up, down and peer notification delays. These must be multiples
 | 
				
			||||||
 * MII monitoring value, and are stored internally as the multiplier.
 | 
					 * of the MII monitoring value, and are stored internally as the
 | 
				
			||||||
 * Thus, we must translate to MS for the real world.
 | 
					 * multiplier. Thus, we must translate to MS for the real world.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int bond_option_updelay_set(struct bonding *bond,
 | 
					static int _bond_option_delay_set(struct bonding *bond,
 | 
				
			||||||
				   const struct bond_opt_value *newval)
 | 
									  const struct bond_opt_value *newval,
 | 
				
			||||||
 | 
									  const char *name,
 | 
				
			||||||
 | 
									  int *target)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int value = newval->value;
 | 
						int value = newval->value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!bond->params.miimon) {
 | 
						if (!bond->params.miimon) {
 | 
				
			||||||
		netdev_err(bond->dev, "Unable to set up delay as MII monitoring is disabled\n");
 | 
							netdev_err(bond->dev, "Unable to set %s as MII monitoring is disabled\n",
 | 
				
			||||||
 | 
								   name);
 | 
				
			||||||
		return -EPERM;
 | 
							return -EPERM;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if ((value % bond->params.miimon) != 0) {
 | 
						if ((value % bond->params.miimon) != 0) {
 | 
				
			||||||
		netdev_warn(bond->dev, "up delay (%d) is not a multiple of miimon (%d), updelay rounded to %d ms\n",
 | 
							netdev_warn(bond->dev,
 | 
				
			||||||
 | 
								    "%s (%d) is not a multiple of miimon (%d), value rounded to %d ms\n",
 | 
				
			||||||
 | 
								    name,
 | 
				
			||||||
			    value, bond->params.miimon,
 | 
								    value, bond->params.miimon,
 | 
				
			||||||
			    (value / bond->params.miimon) *
 | 
								    (value / bond->params.miimon) *
 | 
				
			||||||
			    bond->params.miimon);
 | 
								    bond->params.miimon);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	bond->params.updelay = value / bond->params.miimon;
 | 
						*target = value / bond->params.miimon;
 | 
				
			||||||
	netdev_dbg(bond->dev, "Setting up delay to %d\n",
 | 
						netdev_dbg(bond->dev, "Setting %s to %d\n",
 | 
				
			||||||
		   bond->params.updelay * bond->params.miimon);
 | 
							   name,
 | 
				
			||||||
 | 
							   *target * bond->params.miimon);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int bond_option_updelay_set(struct bonding *bond,
 | 
				
			||||||
 | 
									   const struct bond_opt_value *newval)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return _bond_option_delay_set(bond, newval, "up delay",
 | 
				
			||||||
 | 
									      &bond->params.updelay);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int bond_option_downdelay_set(struct bonding *bond,
 | 
					static int bond_option_downdelay_set(struct bonding *bond,
 | 
				
			||||||
				     const struct bond_opt_value *newval)
 | 
									     const struct bond_opt_value *newval)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int value = newval->value;
 | 
						return _bond_option_delay_set(bond, newval, "down delay",
 | 
				
			||||||
 | 
									      &bond->params.downdelay);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!bond->params.miimon) {
 | 
					static int bond_option_peer_notif_delay_set(struct bonding *bond,
 | 
				
			||||||
		netdev_err(bond->dev, "Unable to set down delay as MII monitoring is disabled\n");
 | 
										    const struct bond_opt_value *newval)
 | 
				
			||||||
		return -EPERM;
 | 
					{
 | 
				
			||||||
	}
 | 
						int ret = _bond_option_delay_set(bond, newval,
 | 
				
			||||||
	if ((value % bond->params.miimon) != 0) {
 | 
										 "peer notification delay",
 | 
				
			||||||
		netdev_warn(bond->dev, "down delay (%d) is not a multiple of miimon (%d), delay rounded to %d ms\n",
 | 
										 &bond->params.peer_notif_delay);
 | 
				
			||||||
			    value, bond->params.miimon,
 | 
						return ret;
 | 
				
			||||||
			    (value / bond->params.miimon) *
 | 
					 | 
				
			||||||
			    bond->params.miimon);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	bond->params.downdelay = value / bond->params.miimon;
 | 
					 | 
				
			||||||
	netdev_dbg(bond->dev, "Setting down delay to %d\n",
 | 
					 | 
				
			||||||
		   bond->params.downdelay * bond->params.miimon);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int bond_option_use_carrier_set(struct bonding *bond,
 | 
					static int bond_option_use_carrier_set(struct bonding *bond,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -104,6 +104,8 @@ static void bond_info_show_master(struct seq_file *seq)
 | 
				
			||||||
		   bond->params.updelay * bond->params.miimon);
 | 
							   bond->params.updelay * bond->params.miimon);
 | 
				
			||||||
	seq_printf(seq, "Down Delay (ms): %d\n",
 | 
						seq_printf(seq, "Down Delay (ms): %d\n",
 | 
				
			||||||
		   bond->params.downdelay * bond->params.miimon);
 | 
							   bond->params.downdelay * bond->params.miimon);
 | 
				
			||||||
 | 
						seq_printf(seq, "Peer Notification Delay (ms): %d\n",
 | 
				
			||||||
 | 
							   bond->params.peer_notif_delay * bond->params.miimon);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* ARP information */
 | 
						/* ARP information */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -327,6 +327,18 @@ static ssize_t bonding_show_updelay(struct device *d,
 | 
				
			||||||
static DEVICE_ATTR(updelay, 0644,
 | 
					static DEVICE_ATTR(updelay, 0644,
 | 
				
			||||||
		   bonding_show_updelay, bonding_sysfs_store_option);
 | 
							   bonding_show_updelay, bonding_sysfs_store_option);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static ssize_t bonding_show_peer_notif_delay(struct device *d,
 | 
				
			||||||
 | 
										     struct device_attribute *attr,
 | 
				
			||||||
 | 
										     char *buf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct bonding *bond = to_bond(d);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return sprintf(buf, "%d\n",
 | 
				
			||||||
 | 
							       bond->params.peer_notif_delay * bond->params.miimon);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static DEVICE_ATTR(peer_notif_delay, 0644,
 | 
				
			||||||
 | 
							   bonding_show_peer_notif_delay, bonding_sysfs_store_option);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Show the LACP interval. */
 | 
					/* Show the LACP interval. */
 | 
				
			||||||
static ssize_t bonding_show_lacp(struct device *d,
 | 
					static ssize_t bonding_show_lacp(struct device *d,
 | 
				
			||||||
				 struct device_attribute *attr,
 | 
									 struct device_attribute *attr,
 | 
				
			||||||
| 
						 | 
					@ -718,6 +730,7 @@ static struct attribute *per_bond_attrs[] = {
 | 
				
			||||||
	&dev_attr_arp_ip_target.attr,
 | 
						&dev_attr_arp_ip_target.attr,
 | 
				
			||||||
	&dev_attr_downdelay.attr,
 | 
						&dev_attr_downdelay.attr,
 | 
				
			||||||
	&dev_attr_updelay.attr,
 | 
						&dev_attr_updelay.attr,
 | 
				
			||||||
 | 
						&dev_attr_peer_notif_delay.attr,
 | 
				
			||||||
	&dev_attr_lacp_rate.attr,
 | 
						&dev_attr_lacp_rate.attr,
 | 
				
			||||||
	&dev_attr_ad_select.attr,
 | 
						&dev_attr_ad_select.attr,
 | 
				
			||||||
	&dev_attr_xmit_hash_policy.attr,
 | 
						&dev_attr_xmit_hash_policy.attr,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -63,6 +63,7 @@ enum {
 | 
				
			||||||
	BOND_OPT_AD_ACTOR_SYSTEM,
 | 
						BOND_OPT_AD_ACTOR_SYSTEM,
 | 
				
			||||||
	BOND_OPT_AD_USER_PORT_KEY,
 | 
						BOND_OPT_AD_USER_PORT_KEY,
 | 
				
			||||||
	BOND_OPT_NUM_PEER_NOTIF_ALIAS,
 | 
						BOND_OPT_NUM_PEER_NOTIF_ALIAS,
 | 
				
			||||||
 | 
						BOND_OPT_PEER_NOTIF_DELAY,
 | 
				
			||||||
	BOND_OPT_LAST
 | 
						BOND_OPT_LAST
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -123,6 +123,7 @@ struct bond_params {
 | 
				
			||||||
	int fail_over_mac;
 | 
						int fail_over_mac;
 | 
				
			||||||
	int updelay;
 | 
						int updelay;
 | 
				
			||||||
	int downdelay;
 | 
						int downdelay;
 | 
				
			||||||
 | 
						int peer_notif_delay;
 | 
				
			||||||
	int lacp_fast;
 | 
						int lacp_fast;
 | 
				
			||||||
	unsigned int min_links;
 | 
						unsigned int min_links;
 | 
				
			||||||
	int ad_select;
 | 
						int ad_select;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -636,6 +636,7 @@ enum {
 | 
				
			||||||
	IFLA_BOND_AD_USER_PORT_KEY,
 | 
						IFLA_BOND_AD_USER_PORT_KEY,
 | 
				
			||||||
	IFLA_BOND_AD_ACTOR_SYSTEM,
 | 
						IFLA_BOND_AD_ACTOR_SYSTEM,
 | 
				
			||||||
	IFLA_BOND_TLB_DYNAMIC_LB,
 | 
						IFLA_BOND_TLB_DYNAMIC_LB,
 | 
				
			||||||
 | 
						IFLA_BOND_PEER_NOTIF_DELAY,
 | 
				
			||||||
	__IFLA_BOND_MAX,
 | 
						__IFLA_BOND_MAX,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -636,6 +636,7 @@ enum {
 | 
				
			||||||
	IFLA_BOND_AD_USER_PORT_KEY,
 | 
						IFLA_BOND_AD_USER_PORT_KEY,
 | 
				
			||||||
	IFLA_BOND_AD_ACTOR_SYSTEM,
 | 
						IFLA_BOND_AD_ACTOR_SYSTEM,
 | 
				
			||||||
	IFLA_BOND_TLB_DYNAMIC_LB,
 | 
						IFLA_BOND_TLB_DYNAMIC_LB,
 | 
				
			||||||
 | 
						IFLA_BOND_PEER_NOTIF_DELAY,
 | 
				
			||||||
	__IFLA_BOND_MAX,
 | 
						__IFLA_BOND_MAX,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue