⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bond_3ad.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	// and the parser/multiplexer of the aggregator are already combined}/** * __detach_bond_from_agg * @port: the port we're looking at * * Handle the detaching of the port's control parser/multiplexer from 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 __detach_bond_from_agg(struct port *port){	port=NULL; // just to satisfy the compiler	// This function does nothing sience the parser/multiplexer of the receive	// and the parser/multiplexer of the aggregator are already combined}/** * __agg_ports_are_ready - check if all ports in an aggregator are ready * @aggregator: the aggregator we're looking at * */static int __agg_ports_are_ready(struct aggregator *aggregator){	struct port *port;	int retval = 1;	if (aggregator) {		// scan all ports in this aggregator to verfy if they are all ready		for (port=aggregator->lag_ports; port; port=port->next_port_in_aggregator) {			if (!(port->sm_vars & AD_PORT_READY_N)) {				retval = 0;				break;			}		}	}	return retval;}/** * __set_agg_ports_ready - set value of Ready bit in all ports of an aggregator * @aggregator: the aggregator we're looking at * @val: Should the ports' ready bit be set on or off * */static void __set_agg_ports_ready(struct aggregator *aggregator, int val){	struct port *port;	for (port=aggregator->lag_ports; port; port=port->next_port_in_aggregator) {		if (val) {			port->sm_vars |= AD_PORT_READY;		} else {			port->sm_vars &= ~AD_PORT_READY;		}	}}/** * __get_agg_bandwidth - get the total bandwidth of an aggregator * @aggregator: the aggregator we're looking at * */static u32 __get_agg_bandwidth(struct aggregator *aggregator){	u32 bandwidth=0;	u32 basic_speed;	if (aggregator->num_of_ports) {		basic_speed = __get_link_speed(aggregator->lag_ports);		switch (basic_speed) {		case AD_LINK_SPEED_BITMASK_1MBPS:			bandwidth = aggregator->num_of_ports;			break;		case AD_LINK_SPEED_BITMASK_10MBPS:			bandwidth = aggregator->num_of_ports * 10;			break;		case AD_LINK_SPEED_BITMASK_100MBPS:			bandwidth = aggregator->num_of_ports * 100;			break;		case AD_LINK_SPEED_BITMASK_1000MBPS:			bandwidth = aggregator->num_of_ports * 1000;			break;		default:			bandwidth=0; // to silent the compilor ....		}	}	return bandwidth;}/** * __get_active_agg - get the current active aggregator * @aggregator: the aggregator we're looking at * */static struct aggregator *__get_active_agg(struct aggregator *aggregator){	struct aggregator *retval = NULL;	for (; aggregator; aggregator = __get_next_agg(aggregator)) {		if (aggregator->is_active) {			retval = aggregator;			break;		}	}	return retval;}/** * __update_lacpdu_from_port - update a port's lacpdu fields * @port: the port we're looking at * */static inline void __update_lacpdu_from_port(struct port *port){	struct lacpdu *lacpdu = &port->lacpdu;	/* update current actual Actor parameters */	/* lacpdu->subtype                   initialized	 * lacpdu->version_number            initialized	 * lacpdu->tlv_type_actor_info       initialized	 * lacpdu->actor_information_length  initialized	 */	lacpdu->actor_system_priority = port->actor_system_priority;	lacpdu->actor_system = port->actor_system;	lacpdu->actor_key = port->actor_oper_port_key;	lacpdu->actor_port_priority = port->actor_port_priority;	lacpdu->actor_port = port->actor_port_number;	lacpdu->actor_state = port->actor_oper_port_state;	/* lacpdu->reserved_3_1              initialized	 * lacpdu->tlv_type_partner_info     initialized	 * lacpdu->partner_information_length initialized	 */	lacpdu->partner_system_priority = port->partner_oper_system_priority;	lacpdu->partner_system = port->partner_oper_system;	lacpdu->partner_key = port->partner_oper_key;	lacpdu->partner_port_priority = port->partner_oper_port_priority;	lacpdu->partner_port = port->partner_oper_port_number;	lacpdu->partner_state = port->partner_oper_port_state;	/* lacpdu->reserved_3_2              initialized	 * lacpdu->tlv_type_collector_info   initialized	 * lacpdu->collector_information_length initialized	 * collector_max_delay                initialized	 * reserved_12[12]                   initialized	 * tlv_type_terminator               initialized	 * terminator_length                 initialized	 * reserved_50[50]                   initialized	 */	/* Convert all non u8 parameters to Big Endian for transmit */	__ntohs_lacpdu(lacpdu);}//////////////////////////////////////////////////////////////////////////////////////// ================= main 802.3ad protocol code ======================================///////////////////////////////////////////////////////////////////////////////////////** * ad_lacpdu_send - send out a lacpdu packet on a given port * @port: the port we're looking at * * Returns:   0 on success *          < 0 on error */static int ad_lacpdu_send(struct port *port){	struct slave *slave = port->slave;	struct sk_buff *skb;	struct lacpdu_header *lacpdu_header;	int length = sizeof(struct lacpdu_header);	struct mac_addr lacpdu_multicast_address = AD_MULTICAST_LACPDU_ADDR;	skb = dev_alloc_skb(length);	if (!skb) {		return -ENOMEM;	}	skb->dev = slave->dev;	skb->mac.raw = skb->data;	skb->nh.raw = skb->data + ETH_HLEN;	skb->protocol = PKT_TYPE_LACPDU;	skb->priority = TC_PRIO_CONTROL;	lacpdu_header = (struct lacpdu_header *)skb_put(skb, length);	lacpdu_header->ad_header.destination_address = lacpdu_multicast_address;	/* Note: source addres is set to be the member's PERMANENT address, because we use it	   to identify loopback lacpdus in receive. */	lacpdu_header->ad_header.source_address = *((struct mac_addr *)(slave->perm_hwaddr));	lacpdu_header->ad_header.length_type = PKT_TYPE_LACPDU;	lacpdu_header->lacpdu = port->lacpdu; // struct copy	dev_queue_xmit(skb);	return 0;}/** * ad_marker_send - send marker information/response on a given port * @port: the port we're looking at * @marker: marker data to send * * Returns:   0 on success *          < 0 on error */static int ad_marker_send(struct port *port, struct marker *marker){	struct slave *slave = port->slave;	struct sk_buff *skb;	struct marker_header *marker_header;	int length = sizeof(struct marker_header);	struct mac_addr lacpdu_multicast_address = AD_MULTICAST_LACPDU_ADDR;	skb = dev_alloc_skb(length + 16);	if (!skb) {		return -ENOMEM;	}	skb_reserve(skb, 16);	skb->dev = slave->dev;	skb->mac.raw = skb->data;	skb->nh.raw = skb->data + ETH_HLEN;	skb->protocol = PKT_TYPE_LACPDU;	marker_header = (struct marker_header *)skb_put(skb, length);	marker_header->ad_header.destination_address = lacpdu_multicast_address;	/* Note: source addres is set to be the member's PERMANENT address, because we use it	   to identify loopback MARKERs in receive. */	marker_header->ad_header.source_address = *((struct mac_addr *)(slave->perm_hwaddr));	marker_header->ad_header.length_type = PKT_TYPE_LACPDU;	marker_header->marker = *marker; // struct copy	dev_queue_xmit(skb);	return 0;}/** * ad_mux_machine - handle a port's mux state machine * @port: the port we're looking at * */static void ad_mux_machine(struct port *port){	mux_states_t last_state;	// keep current State Machine state to compare later if it was changed	last_state = port->sm_mux_state;	if (port->sm_vars & AD_PORT_BEGIN) {		port->sm_mux_state = AD_MUX_DETACHED;		 // next state	} else {		switch (port->sm_mux_state) {		case AD_MUX_DETACHED:			if ((port->sm_vars & AD_PORT_SELECTED) || (port->sm_vars & AD_PORT_STANDBY)) { // if SELECTED or STANDBY				port->sm_mux_state = AD_MUX_WAITING; // next state			}			break;		case AD_MUX_WAITING:			// if SELECTED == FALSE return to DETACH state			if (!(port->sm_vars & AD_PORT_SELECTED)) { // if UNSELECTED				port->sm_vars &= ~AD_PORT_READY_N;				// in order to withhold the Selection Logic to check all ports READY_N value				// every callback cycle to update ready variable, we check READY_N and update READY here				__set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator));				port->sm_mux_state = AD_MUX_DETACHED;	 // next state				break;			}			// check if the wait_while_timer expired			if (port->sm_mux_timer_counter && !(--port->sm_mux_timer_counter)) {				port->sm_vars |= AD_PORT_READY_N;			}			// in order to withhold the selection logic to check all ports READY_N value			// every callback cycle to update ready variable, we check READY_N and update READY here			__set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator));			// if the wait_while_timer expired, and the port is in READY state, move to ATTACHED state			if ((port->sm_vars & AD_PORT_READY) && !port->sm_mux_timer_counter) {				port->sm_mux_state = AD_MUX_ATTACHED;	 // next state			}			break;		case AD_MUX_ATTACHED:			// check also if agg_select_timer expired(so the edable port will take place only after this timer)			if ((port->sm_vars & AD_PORT_SELECTED) && (port->partner_oper_port_state & AD_STATE_SYNCHRONIZATION) && !__check_agg_selection_timer(port)) {				port->sm_mux_state = AD_MUX_COLLECTING_DISTRIBUTING;// next state			} else if (!(port->sm_vars & AD_PORT_SELECTED) || (port->sm_vars & AD_PORT_STANDBY)) {	  // if UNSELECTED or STANDBY				port->sm_vars &= ~AD_PORT_READY_N;				// in order to withhold the selection logic to check all ports READY_N value				// every callback cycle to update ready variable, we check READY_N and update READY here				__set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator));				port->sm_mux_state = AD_MUX_DETACHED;// next state			}			break;		case AD_MUX_COLLECTING_DISTRIBUTING:			if (!(port->sm_vars & AD_PORT_SELECTED) || (port->sm_vars & AD_PORT_STANDBY) ||			    !(port->partner_oper_port_state & AD_STATE_SYNCHRONIZATION)			   ) {				port->sm_mux_state = AD_MUX_ATTACHED;// next state			} else {				// if port state hasn't changed make				// sure that a collecting distributing				// port in an active aggregator is enabled				if (port->aggregator &&				    port->aggregator->is_active &&				    !__port_is_enabled(port)) {					__enable_port(port);				}			}			break;		default:    //to silence the compiler			break;		}	}	// check if the state machine was changed	if (port->sm_mux_state != last_state) {		dprintk("Mux Machine: Port=%d, Last State=%d, Curr State=%d\n", port->actor_port_number, last_state, port->sm_mux_state);		switch (port->sm_mux_state) {		case AD_MUX_DETACHED:			__detach_bond_from_agg(port);			port->actor_oper_port_state &= ~AD_STATE_SYNCHRONIZATION;			ad_disable_collecting_distributing(port);			port->actor_oper_port_state &= ~AD_STATE_COLLECTING;			port->actor_oper_port_state &= ~AD_STATE_DISTRIBUTING;			port->ntt = 1;			break;		case AD_MUX_WAITING:			port->sm_mux_timer_counter = __ad_timer_to_ticks(AD_WAIT_WHILE_TIMER, 0);			break;		case AD_MUX_ATTACHED:			__attach_bond_to_agg(port);			port->actor_oper_port_state |= AD_STATE_SYNCHRONIZATION;			port->actor_oper_port_state &= ~AD_STATE_COLLECTING;			port->actor_oper_port_state &= ~AD_STATE_DISTRIBUTING;			ad_disable_collecting_distributing(port);			port->ntt = 1;			break;		case AD_MUX_COLLECTING_DISTRIBUTING:			port->actor_oper_port_state |= AD_STATE_COLLECTING;			port->actor_oper_port_state |= AD_STATE_DISTRIBUTING;			ad_enable_collecting_distributing(port);			port->ntt = 1;			break;		default:    //to silence the compiler			break;		}	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -