diff options
Diffstat (limited to 'drivers/net/bonding/bond_3ad.c')
-rw-r--r-- | drivers/net/bonding/bond_3ad.c | 123 |
1 files changed, 60 insertions, 63 deletions
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index c3fa31c..d69e683 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -446,6 +446,48 @@ static u16 __ad_timer_to_ticks(u16 timer_type, u16 par) ///////////////////////////////////////////////////////////////////////////////// /** + * __choose_matched - update a port's matched variable from a received lacpdu + * @lacpdu: the lacpdu we've received + * @port: the port we're looking at + * + * Update the value of the matched variable, using parameter values from a + * newly received lacpdu. Parameter values for the partner carried in the + * received PDU are compared with the corresponding operational parameter + * values for the actor. Matched is set to TRUE if all of these parameters + * match and the PDU parameter partner_state.aggregation has the same value as + * actor_oper_port_state.aggregation and lacp will actively maintain the link + * in the aggregation. Matched is also set to TRUE if the value of + * actor_state.aggregation in the received PDU is set to FALSE, i.e., indicates + * an individual link and lacp will actively maintain the link. Otherwise, + * matched is set to FALSE. LACP is considered to be actively maintaining the + * link if either the PDU's actor_state.lacp_activity variable is TRUE or both + * the actor's actor_oper_port_state.lacp_activity and the PDU's + * partner_state.lacp_activity variables are TRUE. + * + * Note: the AD_PORT_MATCHED "variable" is not specified by 802.3ad; it is + * used here to implement the language from 802.3ad 43.4.9 that requires + * recordPDU to "match" the LACPDU parameters to the stored values. + */ +static void __choose_matched(struct lacpdu *lacpdu, struct port *port) +{ + // check if all parameters are alike + if (((ntohs(lacpdu->partner_port) == port->actor_port_number) && + (ntohs(lacpdu->partner_port_priority) == port->actor_port_priority) && + !MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) && + (ntohs(lacpdu->partner_system_priority) == port->actor_system_priority) && + (ntohs(lacpdu->partner_key) == port->actor_oper_port_key) && + ((lacpdu->partner_state & AD_STATE_AGGREGATION) == (port->actor_oper_port_state & AD_STATE_AGGREGATION))) || + // or this is individual link(aggregation == FALSE) + ((lacpdu->actor_state & AD_STATE_AGGREGATION) == 0) + ) { + // update the state machine Matched variable + port->sm_vars |= AD_PORT_MATCHED; + } else { + port->sm_vars &= ~AD_PORT_MATCHED; + } +} + +/** * __record_pdu - record parameters from a received lacpdu * @lacpdu: the lacpdu we've received * @port: the port we're looking at @@ -459,6 +501,7 @@ static void __record_pdu(struct lacpdu *lacpdu, struct port *port) if (lacpdu && port) { struct port_params *partner = &port->partner_oper; + __choose_matched(lacpdu, port); // record the new parameter values for the partner operational partner->port_number = ntohs(lacpdu->actor_port); partner->port_priority = ntohs(lacpdu->actor_port_priority); @@ -518,12 +561,12 @@ static void __update_selected(struct lacpdu *lacpdu, struct port *port) const struct port_params *partner = &port->partner_oper; // check if any parameter is different - if (ntohs(lacpdu->actor_port) != partner->port_number - || ntohs(lacpdu->actor_port_priority) != partner->port_priority - || MAC_ADDRESS_COMPARE(&lacpdu->actor_system, &partner->system) - || ntohs(lacpdu->actor_system_priority) != partner->system_priority - || ntohs(lacpdu->actor_key) != partner->key - || (lacpdu->actor_state & AD_STATE_AGGREGATION) != (partner->port_state & AD_STATE_AGGREGATION)) { + if (ntohs(lacpdu->actor_port) != partner->port_number || + ntohs(lacpdu->actor_port_priority) != partner->port_priority || + MAC_ADDRESS_COMPARE(&lacpdu->actor_system, &partner->system) || + ntohs(lacpdu->actor_system_priority) != partner->system_priority || + ntohs(lacpdu->actor_key) != partner->key || + (lacpdu->actor_state & AD_STATE_AGGREGATION) != (partner->port_state & AD_STATE_AGGREGATION)) { // update the state machine Selected variable port->sm_vars &= ~AD_PORT_SELECTED; } @@ -549,12 +592,12 @@ static void __update_default_selected(struct port *port) const struct port_params *oper = &port->partner_oper; // check if any parameter is different - if (admin->port_number != oper->port_number - || admin->port_priority != oper->port_priority - || MAC_ADDRESS_COMPARE(&admin->system, &oper->system) - || admin->system_priority != oper->system_priority - || admin->key != oper->key - || (admin->port_state & AD_STATE_AGGREGATION) + if (admin->port_number != oper->port_number || + admin->port_priority != oper->port_priority || + MAC_ADDRESS_COMPARE(&admin->system, &oper->system) || + admin->system_priority != oper->system_priority || + admin->key != oper->key || + (admin->port_state & AD_STATE_AGGREGATION) != (oper->port_state & AD_STATE_AGGREGATION)) { // update the state machine Selected variable port->sm_vars &= ~AD_PORT_SELECTED; @@ -563,47 +606,6 @@ static void __update_default_selected(struct port *port) } /** - * __choose_matched - update a port's matched variable from a received lacpdu - * @lacpdu: the lacpdu we've received - * @port: the port we're looking at - * - * Update the value of the matched variable, using parameter values from a - * newly received lacpdu. Parameter values for the partner carried in the - * received PDU are compared with the corresponding operational parameter - * values for the actor. Matched is set to TRUE if all of these parameters - * match and the PDU parameter partner_state.aggregation has the same value as - * actor_oper_port_state.aggregation and lacp will actively maintain the link - * in the aggregation. Matched is also set to TRUE if the value of - * actor_state.aggregation in the received PDU is set to FALSE, i.e., indicates - * an individual link and lacp will actively maintain the link. Otherwise, - * matched is set to FALSE. LACP is considered to be actively maintaining the - * link if either the PDU's actor_state.lacp_activity variable is TRUE or both - * the actor's actor_oper_port_state.lacp_activity and the PDU's - * partner_state.lacp_activity variables are TRUE. - */ -static void __choose_matched(struct lacpdu *lacpdu, struct port *port) -{ - // validate lacpdu and port - if (lacpdu && port) { - // check if all parameters are alike - if (((ntohs(lacpdu->partner_port) == port->actor_port_number) && - (ntohs(lacpdu->partner_port_priority) == port->actor_port_priority) && - !MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) && - (ntohs(lacpdu->partner_system_priority) == port->actor_system_priority) && - (ntohs(lacpdu->partner_key) == port->actor_oper_port_key) && - ((lacpdu->partner_state & AD_STATE_AGGREGATION) == (port->actor_oper_port_state & AD_STATE_AGGREGATION))) || - // or this is individual link(aggregation == FALSE) - ((lacpdu->actor_state & AD_STATE_AGGREGATION) == 0) - ) { - // update the state machine Matched variable - port->sm_vars |= AD_PORT_MATCHED; - } else { - port->sm_vars &= ~AD_PORT_MATCHED; - } - } -} - -/** * __update_ntt - update a port's ntt variable from a received lacpdu * @lacpdu: the lacpdu we've received * @port: the port we're looking at @@ -1134,7 +1136,6 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) __update_selected(lacpdu, port); __update_ntt(lacpdu, port); __record_pdu(lacpdu, port); - __choose_matched(lacpdu, port); port->sm_rx_timer_counter = __ad_timer_to_ticks(AD_CURRENT_WHILE_TIMER, (u16)(port->actor_oper_port_state & AD_STATE_LACP_TIMEOUT)); port->actor_oper_port_state &= ~AD_STATE_EXPIRED; // verify that if the aggregator is enabled, the port is enabled too. @@ -1956,7 +1957,7 @@ void bond_3ad_unbind_slave(struct slave *slave) struct port *port, *prev_port, *temp_port; struct aggregator *aggregator, *new_aggregator, *temp_aggregator; int select_new_active_agg = 0; - + // find the aggregator related to this slave aggregator = &(SLAVE_AD_INFO(slave).aggregator); @@ -2024,7 +2025,7 @@ void bond_3ad_unbind_slave(struct slave *slave) // clear the aggregator ad_clear_agg(aggregator); - + if (select_new_active_agg) { ad_agg_selection_logic(__get_first_agg(port)); } @@ -2075,7 +2076,7 @@ void bond_3ad_unbind_slave(struct slave *slave) } } } - port->slave=NULL; + port->slave=NULL; } /** @@ -2301,7 +2302,7 @@ void bond_3ad_handle_link_change(struct slave *slave, char link) } /* - * set link state for bonding master: if we have an active + * set link state for bonding master: if we have an active * aggregator, we're up, if not, we're down. Presumes that we cannot * have an active aggregator if there are no slaves with link up. * @@ -2395,7 +2396,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) goto out; } - slave_agg_no = bond->xmit_hash_policy(skb, dev, slaves_in_agg); + slave_agg_no = bond->xmit_hash_policy(skb, slaves_in_agg); bond_for_each_slave(bond, slave, i) { struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator; @@ -2445,9 +2446,6 @@ int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct pac struct slave *slave = NULL; int ret = NET_RX_DROP; - if (dev_net(dev) != &init_net) - goto out; - if (!(dev->flags & IFF_MASTER)) goto out; @@ -2468,4 +2466,3 @@ out: return ret; } - |