📄 bond_3ad.c
字号:
* %AD_LINK_SPEED_BITMASK_10MBPS, * %AD_LINK_SPEED_BITMASK_100MBPS, * %AD_LINK_SPEED_BITMASK_1000MBPS */static u16 __get_link_speed(struct port *port){ struct slave *slave = port->slave; u16 speed; /* this if covers only a special case: when the configuration starts with * link down, it sets the speed to 0. * This is done in spite of the fact that the e100 driver reports 0 to be * compatible with MVT in the future.*/ if (slave->link != BOND_LINK_UP) { speed=0; } else { switch (slave->speed) { case SPEED_10: speed = AD_LINK_SPEED_BITMASK_10MBPS; break; case SPEED_100: speed = AD_LINK_SPEED_BITMASK_100MBPS; break; case SPEED_1000: speed = AD_LINK_SPEED_BITMASK_1000MBPS; break; default: speed = 0; // unknown speed value from ethtool. shouldn't happen break; } } dprintk("Port %d Received link speed %d update from adapter\n", port->actor_port_number, speed); return speed;}/** * __get_duplex - get a port's duplex * @port: the port we're looking at * * Return @port's duplex in 802.3ad bitmask format. i.e.: * 0x01 if in full duplex * 0x00 otherwise */static u8 __get_duplex(struct port *port){ struct slave *slave = port->slave; u8 retval; // handling a special case: when the configuration starts with // link down, it sets the duplex to 0. if (slave->link != BOND_LINK_UP) { retval=0x0; } else { switch (slave->duplex) { case DUPLEX_FULL: retval=0x1; dprintk("Port %d Received status full duplex update from adapter\n", port->actor_port_number); break; case DUPLEX_HALF: default: retval=0x0; dprintk("Port %d Received status NOT full duplex update from adapter\n", port->actor_port_number); break; } } return retval;}/** * __initialize_port_locks - initialize a port's RX machine spinlock * @port: the port we're looking at * */static inline void __initialize_port_locks(struct port *port){ // make sure it isn't called twice spin_lock_init(&(SLAVE_AD_INFO(port->slave).rx_machine_lock));}//conversions/** * __ntohs_lacpdu - convert the contents of a LACPDU to host byte order * @lacpdu: the speicifed lacpdu * * For each multi-byte field in the lacpdu, convert its content */static void __ntohs_lacpdu(struct lacpdu *lacpdu){ if (lacpdu) { lacpdu->actor_system_priority = ntohs(lacpdu->actor_system_priority); lacpdu->actor_key = ntohs(lacpdu->actor_key); lacpdu->actor_port_priority = ntohs(lacpdu->actor_port_priority); lacpdu->actor_port = ntohs(lacpdu->actor_port); lacpdu->partner_system_priority = ntohs(lacpdu->partner_system_priority); lacpdu->partner_key = ntohs(lacpdu->partner_key); lacpdu->partner_port_priority = ntohs(lacpdu->partner_port_priority); lacpdu->partner_port = ntohs(lacpdu->partner_port); lacpdu->collector_max_delay = ntohs(lacpdu->collector_max_delay); }}/** * __ad_timer_to_ticks - convert a given timer type to AD module ticks * @timer_type: which timer to operate * @par: timer parameter. see below * * If @timer_type is %current_while_timer, @par indicates long/short timer. * If @timer_type is %periodic_timer, @par is one of %FAST_PERIODIC_TIME, * %SLOW_PERIODIC_TIME. */static u16 __ad_timer_to_ticks(u16 timer_type, u16 par){ u16 retval=0; //to silence the compiler switch (timer_type) { case AD_CURRENT_WHILE_TIMER: // for rx machine usage if (par) { // for short or long timeout retval = (AD_SHORT_TIMEOUT_TIME*ad_ticks_per_sec); // short timeout } else { retval = (AD_LONG_TIMEOUT_TIME*ad_ticks_per_sec); // long timeout } break; case AD_ACTOR_CHURN_TIMER: // for local churn machine retval = (AD_CHURN_DETECTION_TIME*ad_ticks_per_sec); break; case AD_PERIODIC_TIMER: // for periodic machine retval = (par*ad_ticks_per_sec); // long timeout break; case AD_PARTNER_CHURN_TIMER: // for remote churn machine retval = (AD_CHURN_DETECTION_TIME*ad_ticks_per_sec); break; case AD_WAIT_WHILE_TIMER: // for selection machine retval = (AD_AGGREGATE_WAIT_TIME*ad_ticks_per_sec); break; } return retval;}/////////////////////////////////////////////////////////////////////////////////// ================= ad_rx_machine helper functions ==================//////////////////////////////////////////////////////////////////////////////////** * __record_pdu - record parameters from a received lacpdu * @lacpdu: the lacpdu we've received * @port: the port we're looking at * * Record the parameter values for the Actor carried in a received lacpdu as * the current partner operational parameter values and sets * actor_oper_port_state.defaulted to FALSE. */static void __record_pdu(struct lacpdu *lacpdu, struct port *port){ // validate lacpdu and port if (lacpdu && port) { // record the new parameter values for the partner operational port->partner_oper_port_number = lacpdu->actor_port; port->partner_oper_port_priority = lacpdu->actor_port_priority; port->partner_oper_system = lacpdu->actor_system; port->partner_oper_system_priority = lacpdu->actor_system_priority; port->partner_oper_key = lacpdu->actor_key; // zero partener's lase states port->partner_oper_port_state = 0; port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_LACP_ACTIVITY); port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_LACP_TIMEOUT); port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_AGGREGATION); port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_SYNCHRONIZATION); port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_COLLECTING); port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_DISTRIBUTING); port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_DEFAULTED); port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_EXPIRED); // set actor_oper_port_state.defaulted to FALSE port->actor_oper_port_state &= ~AD_STATE_DEFAULTED; // set the partner sync. to on if the partner is sync. and the port is matched if ((port->sm_vars & AD_PORT_MATCHED) && (lacpdu->actor_state & AD_STATE_SYNCHRONIZATION)) { port->partner_oper_port_state |= AD_STATE_SYNCHRONIZATION; } else { port->partner_oper_port_state &= ~AD_STATE_SYNCHRONIZATION; } }}/** * __record_default - record default parameters * @port: the port we're looking at * * This function records the default parameter values for the partner carried * in the Partner Admin parameters as the current partner operational parameter * values and sets actor_oper_port_state.defaulted to TRUE. */static void __record_default(struct port *port){ // validate the port if (port) { // record the partner admin parameters port->partner_oper_port_number = port->partner_admin_port_number; port->partner_oper_port_priority = port->partner_admin_port_priority; port->partner_oper_system = port->partner_admin_system; port->partner_oper_system_priority = port->partner_admin_system_priority; port->partner_oper_key = port->partner_admin_key; port->partner_oper_port_state = port->partner_admin_port_state; // set actor_oper_port_state.defaulted to true port->actor_oper_port_state |= AD_STATE_DEFAULTED; }}/** * __update_selected - update a port's Selected variable from a received lacpdu * @lacpdu: the lacpdu we've received * @port: the port we're looking at * * Update the value of the selected variable, using parameter values from a * newly received lacpdu. The parameter values for the Actor carried in the * received PDU are compared with the corresponding operational parameter * values for the ports partner. If one or more of the comparisons shows that * the value(s) received in the PDU differ from the current operational values, * then selected is set to FALSE and actor_oper_port_state.synchronization is * set to out_of_sync. Otherwise, selected remains unchanged. */static void __update_selected(struct lacpdu *lacpdu, struct port *port){ // validate lacpdu and port if (lacpdu && port) { // check if any parameter is different if ((lacpdu->actor_port != port->partner_oper_port_number) || (lacpdu->actor_port_priority != port->partner_oper_port_priority) || MAC_ADDRESS_COMPARE(&(lacpdu->actor_system), &(port->partner_oper_system)) || (lacpdu->actor_system_priority != port->partner_oper_system_priority) || (lacpdu->actor_key != port->partner_oper_key) || ((lacpdu->actor_state & AD_STATE_AGGREGATION) != (port->partner_oper_port_state & AD_STATE_AGGREGATION)) ) { // update the state machine Selected variable port->sm_vars &= ~AD_PORT_SELECTED; } }}/** * __update_default_selected - update a port's Selected variable from Partner * @port: the port we're looking at * * This function updates the value of the selected variable, using the partner * administrative parameter values. The administrative values are compared with * the corresponding operational parameter values for the partner. If one or * more of the comparisons shows that the administrative value(s) differ from * the current operational values, then Selected is set to FALSE and * actor_oper_port_state.synchronization is set to OUT_OF_SYNC. Otherwise, * Selected remains unchanged. */static void __update_default_selected(struct port *port){ // validate the port if (port) { // check if any parameter is different if ((port->partner_admin_port_number != port->partner_oper_port_number) || (port->partner_admin_port_priority != port->partner_oper_port_priority) || MAC_ADDRESS_COMPARE(&(port->partner_admin_system), &(port->partner_oper_system)) || (port->partner_admin_system_priority != port->partner_oper_system_priority) || (port->partner_admin_key != port->partner_oper_key) || ((port->partner_admin_port_state & AD_STATE_AGGREGATION) != (port->partner_oper_port_state & AD_STATE_AGGREGATION)) ) { // update the state machine Selected variable port->sm_vars &= ~AD_PORT_SELECTED; } }}/** * __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 (((lacpdu->partner_port == port->actor_port_number) && (lacpdu->partner_port_priority == port->actor_port_priority) && !MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) && (lacpdu->partner_system_priority == port->actor_system_priority) && (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 * * Updates the value of the ntt variable, using parameter values from a newly * received lacpdu. The parameter values for the partner carried in the * received PDU are compared with the corresponding operational parameter * values for the Actor. If one or more of the comparisons shows that the * value(s) received in the PDU differ from the current operational values, * then ntt is set to TRUE. Otherwise, ntt remains unchanged. */static void __update_ntt(struct lacpdu *lacpdu, struct port *port){ // validate lacpdu and port if (lacpdu && port) { // check if any parameter is different if ((lacpdu->partner_port != port->actor_port_number) || (lacpdu->partner_port_priority != port->actor_port_priority) || MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) || (lacpdu->partner_system_priority != port->actor_system_priority) || (lacpdu->partner_key != port->actor_oper_port_key) || ((lacpdu->partner_state & AD_STATE_LACP_ACTIVITY) != (port->actor_oper_port_state & AD_STATE_LACP_ACTIVITY)) || ((lacpdu->partner_state & AD_STATE_LACP_TIMEOUT) != (port->actor_oper_port_state & AD_STATE_LACP_TIMEOUT)) || ((lacpdu->partner_state & AD_STATE_SYNCHRONIZATION) != (port->actor_oper_port_state & AD_STATE_SYNCHRONIZATION)) || ((lacpdu->partner_state & AD_STATE_AGGREGATION) != (port->actor_oper_port_state & AD_STATE_AGGREGATION)) ) { // set ntt to be TRUE port->ntt = 1; } }}/** * __attach_bond_to_agg * @port: the port we're looking at * * Handle the attaching of the port's control parser/multiplexer and the * aggregator. This function does nothing since the parser/multiplexer of the * receive and the parser/multiplexer of the aggregator are already combined. */static void __attach_bond_to_agg(struct port *port){ port=NULL; // just to satisfy the compiler // This function does nothing since the parser/multiplexer of the receive
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -