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

📄 skrlmt.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
				SK_DBGCAT_TX,				("SkRlmtSend: BPDU Packet on Port %u.\n",					PortIdx))		}	}	return;}	/* SkRlmtSend *//****************************************************************************** * *	SkRlmtPortReceives - check if port is (going) down and bring it up * * Description: *	This routine checks if a port who received a non-BPDU packet *	needs to go up or needs to be stopped going down. ** Context: *	runtime, pageable? * * Returns: *	Nothing. */RLMT_STATIC void	SkRlmtPortReceives(SK_AC	*pAC,		/* adapter context */SK_IOC	IoC,		/* I/O context */SK_U32	PortIdx)	/* port to check */{	SK_RLMT_PORT	*pRPort;	SK_EVPARA	Para;	pRPort = &pAC->Rlmt.Port[PortIdx];	pRPort->PortNoRx = SK_FALSE;	if ((pRPort->PortState == SK_RLMT_PS_DOWN) &&		!(pRPort->CheckingState & SK_RLMT_PCS_TX)) {		/*		 * Port is marked down (rx), but received a non-BPDU packet.		 * Bring it up.		 */		SK_DBG_MSG(			pAC,			SK_DBGMOD_RLMT,			SK_DBGCAT_RX,			("SkRlmtPacketReceive: Received on PortDown.\n"))		pRPort->PortState = SK_RLMT_PS_GOING_UP;		pRPort->GuTimeStamp = SkOsGetTime(pAC);		Para.Para32[0] = PortIdx;		SkTimerStart(			pAC,			IoC,			&pRPort->UpTimer,			SK_RLMT_PORTUP_TIM_VAL,			SKGE_RLMT,			SK_RLMT_PORTUP_TIM,			Para);		SkRlmtCheckSwitch(pAC, IoC);	}	else if (pRPort->CheckingState & SK_RLMT_PCS_RX) {		SK_DBG_MSG(			pAC,			SK_DBGMOD_RLMT,			SK_DBGCAT_RX,			("SkRlmtPacketReceive: Stop bringing port down.\n"))		SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);		SkRlmtCheckSwitch(pAC, IoC);	}	pRPort->CheckingState &= ~SK_RLMT_PCS_RX;	return;}	/* SkRlmtPortReceives *//****************************************************************************** * *	SkRlmtPacketReceive - receive a packet for closer examination * * Description: *	This routine examines a packet more closely than SkRlmtLookahead*(). * * Context: *	runtime, pageable? * * Returns: *	Nothing. */RLMT_STATIC void	SkRlmtPacketReceive(SK_AC	*pAC,	/* adapter context */SK_IOC	IoC,	/* I/O context */SK_MBUF	*pMb)	/* received packet */{#ifdef xDEBUG	extern	void DumpData(char *p, int size);#endif	/* DEBUG */	int			i;	unsigned		j;	SK_U16			PacketType;	SK_U32			PortIdx;	SK_ADDR_PORT		*pAPort;	SK_RLMT_PORT		*pRPort;	SK_RLMT_PACKET		*pRPacket;	SK_SPTREE_PACKET	*pSPacket;	SK_EVPARA		Para;	PortIdx	= pMb->PortIdx;	pAPort = &pAC->Addr.Port[PortIdx];	pRPort = &pAC->Rlmt.Port[PortIdx];	SK_DBG_MSG(		pAC,		SK_DBGMOD_RLMT,		SK_DBGCAT_RX,		("SkRlmtPacketReceive: PortIdx == %d.\n", PortIdx))	pRPacket = (SK_RLMT_PACKET*)pMb->pData;	pSPacket = (SK_SPTREE_PACKET*)pRPacket;#ifdef xDEBUG	DumpData((char *)pRPacket, 32);#endif	/* DEBUG */	if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) != 0) {		SkRlmtPortReceives(pAC, IoC, PortIdx);	}		/* Check destination address. */	if (!SK_ADDR_EQUAL(pAPort->CurrentMacAddress.a, pRPacket->DstAddr) &&		!SK_ADDR_EQUAL(SkRlmtMcAddr.a, pRPacket->DstAddr) &&		!SK_ADDR_EQUAL(BridgeMcAddr.a, pRPacket->DstAddr)) {		/*		 * Not sent to current MAC or registered MC address		 * => Trash it.		 */		SK_DBG_MSG(			pAC,			SK_DBGMOD_RLMT,			SK_DBGCAT_RX,			("SkRlmtPacketReceive: Not for me.\n"))		SkDrvFreeRlmtMbuf(pAC, IoC, pMb);		return;	}	else if (SK_ADDR_EQUAL(pAPort->CurrentMacAddress.a, pRPacket->SrcAddr)) {		/*		 * Was sent by same port (may happen during port switching		 * or in case of duplicate MAC addresses).		 */		/*		 * Check for duplicate address here:		 * If Packet.Random != My.Random => DupAddr.		 */		for (i = 3; i >= 0; i--) {			if (pRPort->Random[i] !=				pRPacket->Random[i]) {				break;			}		}		/*		 * CAUTION: Do not check for duplicate MAC		 * address in RLMT Alive Reply packets.		 */		if (i >= 0 && pRPacket->DSap == SK_RLMT_DSAP &&			pRPacket->Ctrl == SK_RLMT_CTRL &&			pRPacket->SSap == SK_RLMT_SSAP &&			pRPacket->Indicator[0] == SK_RLMT_INDICATOR0 &&			pRPacket->Indicator[1] == SK_RLMT_INDICATOR1 &&			pRPacket->Indicator[2] == SK_RLMT_INDICATOR2 &&			pRPacket->Indicator[3] == SK_RLMT_INDICATOR3 &&			pRPacket->Indicator[4] == SK_RLMT_INDICATOR4 &&			pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 &&			pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) {			SK_DBG_MSG(				pAC,				SK_DBGMOD_RLMT,				SK_DBGCAT_RX,				("SkRlmtPacketReceive: Duplicate MAC Address.\n"))			/* Error Log entry. */			SK_ERR_LOG(				pAC,				SK_ERRCL_COMM,				SKERR_RLMT_E006,				SKERR_RLMT_E006_MSG);		}		else {			/* Simply trash it. */			SK_DBG_MSG(				pAC,				SK_DBGMOD_RLMT,				SK_DBGCAT_RX,				("SkRlmtPacketReceive: Sent by me.\n"))		}		SkDrvFreeRlmtMbuf(pAC, IoC, pMb);		return;	}	/* Check SuspectTx entries. */	if (pRPort->PortsSuspect > 0) {		for (j = 0; j < pRPort->PortsChecked; j++) {			if (pRPort->PortCheck[j].SuspectTx &&				SK_ADDR_EQUAL(					pRPacket->SrcAddr,					pRPort->PortCheck[j].CheckAddr.a)) {				pRPort->PortCheck[j].SuspectTx = SK_FALSE;				pRPort->PortsSuspect--;				break;			}		}	}	/* Determine type of packet. */	if (pRPacket->DSap == SK_RLMT_DSAP &&		pRPacket->Ctrl == SK_RLMT_CTRL &&		(pRPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SSAP &&		pRPacket->Indicator[0] == SK_RLMT_INDICATOR0 &&		pRPacket->Indicator[1] == SK_RLMT_INDICATOR1 &&		pRPacket->Indicator[2] == SK_RLMT_INDICATOR2 &&		pRPacket->Indicator[3] == SK_RLMT_INDICATOR3 &&		pRPacket->Indicator[4] == SK_RLMT_INDICATOR4 &&		pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 &&		pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) {		/* It's an RLMT packet. */		PacketType = (SK_U16)((pRPacket->RlmtPacketType[0] << 8) |			pRPacket->RlmtPacketType[1]);		switch (PacketType) {		case SK_PACKET_ANNOUNCE:	/* Not yet used. */#if 0			/* Build the check chain. */			SkRlmtBuildCheckChain(pAC);#endif	/* 0 */			SK_DBG_MSG(				pAC,				SK_DBGMOD_RLMT,				SK_DBGCAT_RX,				("SkRlmtPacketReceive: Announce.\n"))			SkDrvFreeRlmtMbuf(pAC, IoC, pMb);			break;		case SK_PACKET_ALIVE:			if (pRPacket->SSap & LLC_COMMAND_RESPONSE_BIT) {				SK_DBG_MSG(					pAC,					SK_DBGMOD_RLMT,					SK_DBGCAT_RX,					("SkRlmtPacketReceive: Alive Reply.\n"))				/* Alive Reply Packet. */#if 0				pRPort->RlmtAcksPerTimeSlot++;#endif	/* 0 */				if (!(pAC->Addr.Port[PortIdx].PromMode &					SK_PROM_MODE_LLC) ||					SK_ADDR_EQUAL(						pRPacket->DstAddr,						pAPort->CurrentMacAddress.a)) {					/* Obviously we could send something. */					if (pRPort->CheckingState &						SK_RLMT_PCS_TX) {						pRPort->CheckingState &=							~SK_RLMT_PCS_TX;						SkTimerStop(							pAC,							IoC,							&pRPort->DownTxTimer);					}					if ((pRPort->PortState ==						SK_RLMT_PS_DOWN) &&						!(pRPort->CheckingState &						SK_RLMT_PCS_RX)) {						pRPort->PortState =							SK_RLMT_PS_GOING_UP;						pRPort->GuTimeStamp =							SkOsGetTime(pAC);						SkTimerStop(							pAC,							IoC,							&pRPort->DownTxTimer);						Para.Para32[0] = PortIdx;						SkTimerStart(							pAC,							IoC,							&pRPort->UpTimer,							SK_RLMT_PORTUP_TIM_VAL,							SKGE_RLMT,							SK_RLMT_PORTUP_TIM,							Para);					}				}				/* Mark sending port as alive? */				SkDrvFreeRlmtMbuf(pAC, IoC, pMb);			}			else {	/* Alive Request Packet. */				SK_DBG_MSG(					pAC,					SK_DBGMOD_RLMT,					SK_DBGCAT_RX,					("SkRlmtPacketReceive: Alive Request.\n"))				pRPort->RxHelloCts++;#if 0				pRPort->RlmtChksPerTimeSlot++;#endif	/* 0 */				/* Answer. */				for (i = 0; i < SK_MAC_ADDR_LEN; i++) {					pRPacket->DstAddr[i] =						pRPacket->SrcAddr[i];					pRPacket->SrcAddr[i] = pAC->Addr.Port[						PortIdx].CurrentMacAddress.a[i];				}				pRPacket->SSap |= LLC_COMMAND_RESPONSE_BIT;				Para.pParaPtr = pMb;				SkEventQueue(					pAC,					SKGE_DRV,					SK_DRV_RLMT_SEND,					Para);			}			break;		case SK_PACKET_CHECK_TX:			SK_DBG_MSG(				pAC,				SK_DBGMOD_RLMT,				SK_DBGCAT_RX,				("SkRlmtPacketReceive: Check your tx line.\n"))			/*			 * A port checking us requests us to check our tx line.			 */			pRPort->CheckingState |= SK_RLMT_PCS_TX;			/* Start PortDownTx timer. */			Para.Para32[0] = PortIdx;			SkTimerStart(				pAC,				IoC,				&pRPort->DownTxTimer,				SK_RLMT_PORTDOWN_TIM_VAL,				SKGE_RLMT,				SK_RLMT_PORTDOWN_TX_TIM,				Para);			SkDrvFreeRlmtMbuf(pAC, IoC, pMb);			if ((Para.pParaPtr = SkRlmtBuildPacket(				pAC,				IoC,				PortIdx,				SK_PACKET_ALIVE,				&pAC->Addr.Port[PortIdx].CurrentMacAddress,				&SkRlmtMcAddr)) != NULL) {				SkEventQueue(					pAC,					SKGE_DRV,					SK_DRV_RLMT_SEND,					Para);			}			break;		case SK_PACKET_ADDR_CHANGED:			SK_DBG_MSG(				pAC,				SK_DBGMOD_RLMT,				SK_DBGCAT_RX,				("SkRlmtPacketReceive: Address Change.\n"))			/* Build the check chain. */			SkRlmtBuildCheckChain(pAC);			SkDrvFreeRlmtMbuf(pAC, IoC, pMb);			break;		default:			SK_DBG_MSG(				pAC,				SK_DBGMOD_RLMT,				SK_DBGCAT_RX,				("SkRlmtPacketReceive: Unknown RLMT packet.\n"))			/* RA;:;: ??? */			SkDrvFreeRlmtMbuf(pAC, IoC, pMb);		}	}	else if (pSPacket->DSap == SK_RLMT_SPT_DSAP &&		pSPacket->Ctrl == SK_RLMT_SPT_CTRL &&		(pSPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) ==		SK_RLMT_SPT_SSAP) {		SK_DBG_MSG(			pAC,			SK_DBGMOD_RLMT,			SK_DBGCAT_RX,			("SkRlmtPacketReceive: BPDU Packet.\n"))		/* Spanning Tree packet. */		pRPort->RxSpHelloCts++;		if (!SK_ADDR_EQUAL(			&pSPacket->RootId[2],			&pAC->Addr.CurrentMacAddress.a[0])) {			/*			 * Check segmentation if a new root bridge is set and			 * the segmentation check is not currently running.			 */			if (!SK_ADDR_EQUAL(					&pSPacket->RootId[2],					&pRPort->Root.Id[2]) &&				(pAC->Rlmt.LinksUp > 1) &&				(pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_SEG) &&				!(pAC->Rlmt.CheckingState & SK_RLMT_RCS_SEG)) {				pAC->Rlmt.CheckingState |=					SK_RLMT_RCS_START_SEG |					SK_RLMT_RCS_SEND_SEG;			}			/* Store tree view of this port. */			for (i = 0; i < 8; i++) {				pRPort->Root.Id[i] = pSPacket->RootId[i];			}			pRPort->RootIdSet = SK_TRUE;		}		SkDrvFreeRlmtMbuf(pAC, IoC, pMb);		if (pAC->Rlmt.CheckingState & SK_RLMT_RCS_REPORT_SEG) {			SkRlmtCheckSeg(pAC, IoC);		}	}	else {		SK_DBG_MSG(			pAC,			SK_DBGMOD_RLMT,			SK_DBGCAT_RX,			("SkRlmtPacketReceive: Unknown Packet Type.\n"))		/* Unknown packet. */		SkDrvFreeRlmtMbuf(pAC, IoC, pMb);	}	return;}	/* SkRlmtPacketReceive *//****************************************************************************** * *	SkRlmtCheckPort - check if a port works * * Description: *	This routine checks if a port whose link is up received something *	and if it seems to transmit successfully. * *	# PortState: PsInit, PsLinkDown, PsDown, PsGoingUp, PsUp *	# PortCheckingState (Bitfield): ChkTx, ChkRx, ChkSeg *	# RlmtCheckingState (Bitfield): ChkSeg, StartChkSeg, ReportSeg * *	if (Rx - RxBpdu == 0) {	# No rx. *		if (state == PsUp) { *			PortCheckingState |= ChkRx *		} *		if (ModeCheckSeg && (Timeout == *			TO_SHORTEN(RLMT_DEFAULT_TIMEOUT))) { *			RlmtCheckingState |= ChkSeg) *			PortCheckingState |= ChkSeg *		} *		NewTimeout = TO_SHORTEN(Timeout) *		if (NewTimeout < RLMT_MIN_TIMEOUT) { *			NewTimeout = RLMT_MIN_TIMEOUT *			PortState = PsDown *			... *		} *	} *	else {	# something was received *		# Set counter to 0 at LinkDown? *		#   No - rx may be reported after LinkDown ??? *		PortCheckingState &= ~ChkRx *		NewTimeout = RLMT_DEFAULT_TIMEOUT *		if (RxAck == 0) { *			possible reasons: *			is my tx line bad? -- *				send RLMT multicast and report *				back internally? (only possible *				between ports on same adapter) *		} *		if (RxChk == 0) { *			possible reasons: *			- tx line of port set to check me *			  maybe bad *			- no other port/adapter available or set *			  to check me *			- adapter checking me has a longer *			  timeout *			??? anything that can be done here? *		} *	} * * Context: *	runtime, pageable? *

⌨️ 快捷键说明

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