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

📄 bond_3ad.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 59 * Temple Place - Suite 330, Boston, MA  02111-1307, USA. * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * * * Changes: * * 2003/05/01 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and *		Amir Noam <amir.noam at intel dot com> *	- Added support for lacp_rate module param. * * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com> *	- Based on discussion on mailing list, changed locking scheme *	  to use lock/unlock or lock_bh/unlock_bh appropriately instead *	  of lock_irqsave/unlock_irqrestore. The new scheme helps exposing *	  hidden bugs and solves system hangs that occurred due to the fact *	  that holding lock_irqsave doesn't prevent softirqs from running. *	  This also increases total throughput since interrupts are not *	  blocked on each transmitted packets or monitor timeout. * * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com> *	- Renamed bond_3ad_link_status_changed() to *	  bond_3ad_handle_link_change() for compatibility with TLB. * * 2003/05/20 - Amir Noam <amir.noam at intel dot com> *	- Fix long fail over time when releasing last slave of an active *	  aggregator - send LACPDU on unbind of slave to tell partner this *	  port is no longer aggregatable. * * 2003/06/25 - Tsippy Mendelson <tsippy.mendelson at intel dot com> *	- Send LACPDU as highest priority packet to further fix the above *	  problem on very high Tx traffic load where packets may get dropped *	  by the slave. * * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com> *	- Code cleanup and style changes *///#define BONDING_DEBUG 1#include <linux/skbuff.h>#include <linux/if_ether.h>#include <linux/netdevice.h>#include <linux/spinlock.h>#include <linux/ethtool.h>#include <linux/if_bonding.h>#include <linux/pkt_sched.h>#include "bonding.h"#include "bond_3ad.h"// General definitions#define AD_SHORT_TIMEOUT           1#define AD_LONG_TIMEOUT            0#define AD_STANDBY                 0x2#define AD_MAX_TX_IN_SECOND        3#define AD_COLLECTOR_MAX_DELAY     0// Timer definitions(43.4.4 in the 802.3ad standard)#define AD_FAST_PERIODIC_TIME      1#define AD_SLOW_PERIODIC_TIME      30#define AD_SHORT_TIMEOUT_TIME      (3*AD_FAST_PERIODIC_TIME)#define AD_LONG_TIMEOUT_TIME       (3*AD_SLOW_PERIODIC_TIME)#define AD_CHURN_DETECTION_TIME    60#define AD_AGGREGATE_WAIT_TIME     2// Port state definitions(43.4.2.2 in the 802.3ad standard)#define AD_STATE_LACP_ACTIVITY   0x1#define AD_STATE_LACP_TIMEOUT    0x2#define AD_STATE_AGGREGATION     0x4#define AD_STATE_SYNCHRONIZATION 0x8#define AD_STATE_COLLECTING      0x10#define AD_STATE_DISTRIBUTING    0x20#define AD_STATE_DEFAULTED       0x40#define AD_STATE_EXPIRED         0x80// Port Variables definitions used by the State Machines(43.4.7 in the 802.3ad standard)#define AD_PORT_BEGIN           0x1#define AD_PORT_LACP_ENABLED    0x2#define AD_PORT_ACTOR_CHURN     0x4#define AD_PORT_PARTNER_CHURN   0x8#define AD_PORT_READY           0x10#define AD_PORT_READY_N         0x20#define AD_PORT_MATCHED         0x40#define AD_PORT_STANDBY         0x80#define AD_PORT_SELECTED        0x100#define AD_PORT_MOVED           0x200// Port Key definitions// key is determined according to the link speed, duplex and// user key(which is yet not supported)//              ------------------------------------------------------------// Port key :   | User key                       |      Speed       |Duplex|//              ------------------------------------------------------------//              16                               6               1 0#define  AD_DUPLEX_KEY_BITS    0x1#define  AD_SPEED_KEY_BITS     0x3E#define  AD_USER_KEY_BITS      0xFFC0//dalloun#define     AD_LINK_SPEED_BITMASK_1MBPS       0x1#define     AD_LINK_SPEED_BITMASK_10MBPS      0x2#define     AD_LINK_SPEED_BITMASK_100MBPS     0x4#define     AD_LINK_SPEED_BITMASK_1000MBPS    0x8//endalloun// compare MAC addresses#define MAC_ADDRESS_COMPARE(A, B) memcmp(A, B, ETH_ALEN)static struct mac_addr null_mac_addr = {{0, 0, 0, 0, 0, 0}};static u16 ad_ticks_per_sec;static const int ad_delta_in_ticks = (AD_TIMER_INTERVAL * HZ) / 1000;// ================= 3AD api to bonding and kernel code ==================static u16 __get_link_speed(struct port *port);static u8 __get_duplex(struct port *port);static inline void __initialize_port_locks(struct port *port);//conversionsstatic void __ntohs_lacpdu(struct lacpdu *lacpdu);static u16 __ad_timer_to_ticks(u16 timer_type, u16 Par);// ================= ad code helper functions ==================//needed by ad_rx_machine(...)static void __record_pdu(struct lacpdu *lacpdu, struct port *port);static void __record_default(struct port *port);static void __update_selected(struct lacpdu *lacpdu, struct port *port);static void __update_default_selected(struct port *port);static void __choose_matched(struct lacpdu *lacpdu, struct port *port);static void __update_ntt(struct lacpdu *lacpdu, struct port *port);//needed for ad_mux_machine(..)static void __attach_bond_to_agg(struct port *port);static void __detach_bond_from_agg(struct port *port);static int __agg_ports_are_ready(struct aggregator *aggregator);static void __set_agg_ports_ready(struct aggregator *aggregator, int val);//needed for ad_agg_selection_logic(...)static u32 __get_agg_bandwidth(struct aggregator *aggregator);static struct aggregator *__get_active_agg(struct aggregator *aggregator);// ================= main 802.3ad protocol functions ==================static int ad_lacpdu_send(struct port *port);static int ad_marker_send(struct port *port, struct marker *marker);static void ad_mux_machine(struct port *port);static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port);static void ad_tx_machine(struct port *port);static void ad_periodic_machine(struct port *port);static void ad_port_selection_logic(struct port *port);static void ad_agg_selection_logic(struct aggregator *aggregator);static void ad_clear_agg(struct aggregator *aggregator);static void ad_initialize_agg(struct aggregator *aggregator);static void ad_initialize_port(struct port *port, int lacp_fast);static void ad_initialize_lacpdu(struct lacpdu *Lacpdu);static void ad_enable_collecting_distributing(struct port *port);static void ad_disable_collecting_distributing(struct port *port);static void ad_marker_info_received(struct marker *marker_info, struct port *port);static void ad_marker_response_received(struct marker *marker, struct port *port);/////////////////////////////////////////////////////////////////////////////////// ================= api to bonding and kernel code ==================//////////////////////////////////////////////////////////////////////////////////** * __get_bond_by_port - get the port's bonding struct * @port: the port we're looking at * * Return @port's bonding struct, or %NULL if it can't be found. */static inline struct bonding *__get_bond_by_port(struct port *port){	if (port->slave == NULL) {		return NULL;	}	return bond_get_bond_by_slave(port->slave);}/** * __get_first_port - get the first port in the bond * @bond: the bond we're looking at * * Return the port of the first slave in @bond, or %NULL if it can't be found. */static inline struct port *__get_first_port(struct bonding *bond){	if (bond->slave_cnt == 0) {		return NULL;	}	return &(SLAVE_AD_INFO(bond->first_slave).port);}/** * __get_next_port - get the next port in the bond * @port: the port we're looking at * * Return the port of the slave that is next in line of @port's slave in the * bond, or %NULL if it can't be found. */static inline struct port *__get_next_port(struct port *port){	struct bonding *bond = __get_bond_by_port(port);	struct slave *slave = port->slave;	// If there's no bond for this port, or this is the last slave	if ((bond == NULL) || (slave->next == bond->first_slave)) {		return NULL;	}	return &(SLAVE_AD_INFO(slave->next).port);}/** * __get_first_agg - get the first aggregator in the bond * @bond: the bond we're looking at * * Return the aggregator of the first slave in @bond, or %NULL if it can't be * found. */static inline struct aggregator *__get_first_agg(struct port *port){	struct bonding *bond = __get_bond_by_port(port);	// If there's no bond for this port, or bond has no slaves	if ((bond == NULL) || (bond->slave_cnt == 0)) {		return NULL;	}	return &(SLAVE_AD_INFO(bond->first_slave).aggregator);}/** * __get_next_agg - get the next aggregator in the bond * @aggregator: the aggregator we're looking at * * Return the aggregator of the slave that is next in line of @aggregator's * slave in the bond, or %NULL if it can't be found. */static inline struct aggregator *__get_next_agg(struct aggregator *aggregator){	struct slave *slave = aggregator->slave;	struct bonding *bond = bond_get_bond_by_slave(slave);	// If there's no bond for this aggregator, or this is the last slave	if ((bond == NULL) || (slave->next == bond->first_slave)) {		return NULL;	}	return &(SLAVE_AD_INFO(slave->next).aggregator);}/** * __disable_port - disable the port's slave * @port: the port we're looking at * */static inline void __disable_port(struct port *port){	bond_set_slave_inactive_flags(port->slave);}/** * __enable_port - enable the port's slave, if it's up * @port: the port we're looking at * */static inline void __enable_port(struct port *port){	struct slave *slave = port->slave;	if ((slave->link == BOND_LINK_UP) && IS_UP(slave->dev)) {		bond_set_slave_active_flags(slave);	}}/** * __port_is_enabled - check if the port's slave is in active state * @port: the port we're looking at * */static inline int __port_is_enabled(struct port *port){	return(port->slave->state == BOND_STATE_ACTIVE);}/** * __get_agg_selection_mode - get the aggregator selection mode * @port: the port we're looking at * * Get the aggregator selection mode. Can be %BANDWIDTH or %COUNT. */static inline u32 __get_agg_selection_mode(struct port *port){	struct bonding *bond = __get_bond_by_port(port);	if (bond == NULL) {		return AD_BANDWIDTH;	}	return BOND_AD_INFO(bond).agg_select_mode;}/** * __check_agg_selection_timer - check if the selection timer has expired * @port: the port we're looking at * */static inline int __check_agg_selection_timer(struct port *port){	struct bonding *bond = __get_bond_by_port(port);	if (bond == NULL) {		return 0;	}	return BOND_AD_INFO(bond).agg_select_timer ? 1 : 0;}/** * __get_rx_machine_lock - lock the port's RX machine * @port: the port we're looking at * */static inline void __get_rx_machine_lock(struct port *port){	spin_lock(&(SLAVE_AD_INFO(port->slave).rx_machine_lock));}/** * __release_rx_machine_lock - unlock the port's RX machine * @port: the port we're looking at * */static inline void __release_rx_machine_lock(struct port *port){	spin_unlock(&(SLAVE_AD_INFO(port->slave).rx_machine_lock));}/** * __get_link_speed - get a port's speed * @port: the port we're looking at * * Return @port's speed in 802.3ad bitmask format. i.e. one of: *     0,

⌨️ 快捷键说明

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