📄 swprvtb.c
字号:
/*
* Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
* All rights reserved.
*
* This software is copyrighted by and is the sole property of
* VIA Networking Technologies, Inc. This software may only be used
* in accordance with the corresponding license agreement. Any unauthorized
* use, duplication, transmission, distribution, or disclosure of this
* software is expressly forbidden.
*
* This software is provided by VIA Networking Technologies, Inc. "as is"
* and any express or implied warranties, including, but not limited to, the
* implied warranties of merchantability and fitness for a particular purpose
* are disclaimed. In no event shall VIA Networking Technologies, Inc.
* be liable for any direct, indirect, incidental, special, exemplary, or
* consequential damages.
*
*
* File: swprvtb.c
*
* Purpose: Protocol based vlan operation functions
*
* Author: Henry Lin
*
* Date: May 20, 2005
*
* Functions:
*
* Revision History:
*
*/
#if !defined(__STR_H__)
#include "str.h"
#endif
#if !defined(__SWITCH_H__)
#include "switch.h"
#endif
#if !defined(__SWSRAM_H__)
#include "swsram.h"
#endif
#if !defined(__SWPRVTB_H__)
#include "swprvtb.h"
#endif
#if !defined(__SWL2PTB_H__)
#include "swl2ptb.h"
#endif
/*--------------------- Static Definitions -------------------------*/
#define IP_ETHER_TYPE 0x0800
/*--------------------- Static Types ------------------------------*/
/*--------------------- Static Macros -----------------------------*/
/*--------------------- Static Classes ----------------------------*/
/*--------------------- Static Variables --------------------------*/
UINT8 au8RFC1042Ptn[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
UINT8 au8SNAP8021HPtn[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
UINT8 au8SNAPOtherPtn[] = {0xAA, 0xAA, 0x03};
/*--------------------- Static Functions --------------------------*/
/*--------------------- Export Variables --------------------------*/
BOOL SWPRVTB_bGetEntry(UINT8 u8EntryIdx, SProVlanEntry *pSEntry)
{
SL2pACEntry SEntryAC;
STcamEntry SEntryTcam;
BOOL bMaskTbl = FALSE;
UINT16 u16TmpType;
// Get vid
SWL2PAC_bGetEntry (u8EntryIdx, &SEntryAC);
pSEntry->u16Vid = SEntryAC.u16L2pVid;
// Get type, frame formate and TagPkt
SWTCAM_bGetEntry (u8EntryIdx, &SEntryTcam, bMaskTbl);
pSEntry->bTagPkt = SEntryTcam.bVlanTag;
#if defined(__LITTLE_ENDIAN)
// convert SIP,DIP,IpOpt to byte array
SWSRAM_vEndianConvert(&SEntryTcam.UCfg13B.au8AftSV[1], 4);
SWSRAM_vEndianConvert(&SEntryTcam.UCfg13B.au8AftSV[5], 4);
SWSRAM_vEndianConvert(&SEntryTcam.UCfg13B.au8AftSV[9], 4);
#endif
u16TmpType = (SEntryTcam.UCfg13B.au8AftSV[0] << 8) | SEntryTcam.UCfg13B.au8AftSV[1];
if (u16TmpType != 0){
pSEntry->byFrameFormat = FRAME_FRMT_ETHER2;
pSEntry->u16Type = SEntryTcam.UCfg13B.au8AftSV[OFFSET_ETHER2_TYPE] << 8 |
SEntryTcam.UCfg13B.au8AftSV[OFFSET_ETHER2_TYPE + 1];
}
else{
if (STR_iMemcmp( &SEntryTcam.UCfg13B.au8AftSV[OFFSET_DSAP], au8RFC1042Ptn, sizeof(au8RFC1042Ptn)) == 0){
pSEntry->byFrameFormat = FRAME_FRMT_RFC1042;
pSEntry->u16Type = SEntryTcam.UCfg13B.au8AftSV[OFFSET_RFC1042_TYPE] << 8 |
SEntryTcam.UCfg13B.au8AftSV[OFFSET_RFC1042_TYPE + 1];
}
else if (STR_iMemcmp( &SEntryTcam.UCfg13B.au8AftSV[OFFSET_DSAP], au8SNAP8021HPtn, sizeof(au8SNAP8021HPtn)) == 0){
pSEntry->byFrameFormat = FRAME_FRMT_802_1H;
pSEntry->u16Type = SEntryTcam.UCfg13B.au8AftSV[OFFSET_802_1H_TYPE] << 8 |
SEntryTcam.UCfg13B.au8AftSV[OFFSET_802_1H_TYPE + 1];
}
else if (STR_iMemcmp( &SEntryTcam.UCfg13B.au8AftSV[OFFSET_DSAP], au8SNAPOtherPtn, sizeof(au8SNAPOtherPtn)) == 0){
pSEntry->byFrameFormat = FRAME_FRMT_SANP_OTHERS;
pSEntry->u16Type = SEntryTcam.UCfg13B.au8AftSV[OFFSET_SANP_OTHERS_TYPE] << 8 |
SEntryTcam.UCfg13B.au8AftSV[OFFSET_SANP_OTHERS_TYPE + 1];
}
else{
//Ipv4 or LLC
u16TmpType = (SEntryTcam.UCfg13B.au8AftSV[OFFSET_DSAP] << 8) | SEntryTcam.UCfg13B.au8AftSV[OFFSET_DSAP + 1];
if (u16TmpType != 0){
pSEntry->byFrameFormat = FRAME_FRMT_LLC;
pSEntry->u16Type = SEntryTcam.UCfg13B.au8AftSV[OFFSET_DSAP] << 8 |
SEntryTcam.UCfg13B.au8AftSV[OFFSET_DSAP + 1];
}
else{
pSEntry->byFrameFormat = FRAME_FRMT_ETHER2_IPV4;
pSEntry->u16Type = IP_ETHER_TYPE;
}
}
}
return TRUE;
}
UINT16 SWPRVTB_u16SearchEntry(UINT16 u16Type, UINT16 u16Vid, UINT8 byFrameFormat)
{
UINT16 u16Idx, u16TmpType;
UINT8 u8Off;
BOOL bMaskTbl = FALSE;
SL2pACEntry SEntryAC;
STcamEntry SEntryTcam;
for (u16Idx = 0 ; u16Idx < TCAM_ENTRY_NUM; u16Idx++)
{
// Get vid, and compare
if (!SWL2PAC_bGetEntry (u16Idx, &SEntryAC) )
continue;
if (SEntryAC.u16L2pVid != u16Vid)
continue;
// Compare Type
SWTCAM_bGetEntry (u16Idx, &SEntryTcam, bMaskTbl);
#if defined(__LITTLE_ENDIAN)
// convert SIP,DIP,IpOpt to byte array
SWSRAM_vEndianConvert(&SEntryTcam.UCfg13B.au8AftSV[1], 4);
SWSRAM_vEndianConvert(&SEntryTcam.UCfg13B.au8AftSV[5], 4);
SWSRAM_vEndianConvert(&SEntryTcam.UCfg13B.au8AftSV[9], 4);
#endif
switch(byFrameFormat)
{
case FRAME_FRMT_ETHER2_IPV4:
// if ipv4, ether type not compare.
// compare is IPv4
if (SEntryTcam.bIpv4 == TRUE)
return u16Idx;
continue;
case FRAME_FRMT_ETHER2:
u8Off = OFFSET_ETHER2_TYPE;
break;
case FRAME_FRMT_RFC1042:
case FRAME_FRMT_802_1H:
case FRAME_FRMT_SANP_OTHERS:
u8Off = OFFSET_RFC1042_TYPE;
break;
case FRAME_FRMT_LLC:
u8Off = OFFSET_DSAP;
break;
default:
continue; // unknow frame format
}
u16TmpType = (SEntryTcam.UCfg13B.au8AftSV[u8Off] << 8) | SEntryTcam.UCfg13B.au8AftSV[u8Off+1];
if (u16TmpType == u16Type)
return u16Idx;
}
return UINT16_MAX;
}
BOOL SWPRVTB_bInsEntry(SProVlanEntry *pSInsEntry, BOOL bIsOverWrite)
{
UINT16 u16EntryIdx, u16ByteMsk, u16MskType;
UINT8 u8Off;
BOOL bIsIpv4;
UINT8 byTmpType[2];
STcamEntry SEntryTcam;
SL2pACEntry SEntryAC;
u16EntryIdx = SWPRVTB_u16SearchEntry(pSInsEntry->u16Type, pSInsEntry->u16Vid, pSInsEntry->byFrameFormat);
// If entry already exist and can't be overwrote, then return operate fail.
if ((u16EntryIdx != UINT16_MAX) && (!bIsOverWrite) )
return FALSE;
if (u16EntryIdx == UINT16_MAX){
u16EntryIdx = SWL2PTB_u16FindEmptyEntry();
if (u16EntryIdx == UINT16_MAX)
return FALSE; //TCAM table is full
}
//
// 1.Insert L2+ value array
//
STR_pvMemset(&SEntryTcam, 0, sizeof(STcamEntry));
// Incoming packet is VLAN-tagged packet
SEntryTcam.bVlanTag = pSInsEntry->bTagPkt;
*((PUINT16)byTmpType) = pSInsEntry->u16Type;
#if defined(__LITTLE_ENDIAN)
// convert u16Type to byte array
SWSRAM_vEndianConvert(byTmpType, 2);
#endif
SEntryTcam.bIpv4 = FALSE;
bIsIpv4 = FALSE;
u16MskType = MSK_IPV4 | MSK_VLAN_TYPE;
u16ByteMsk = 0; //13bytes mask after SMAC or VLAN-tag
// Check frame format
switch(pSInsEntry->byFrameFormat){
case FRAME_FRMT_ETHER2_IPV4:
SEntryTcam.bIpv4 = TRUE;
bIsIpv4 = TRUE;
break;
case FRAME_FRMT_ETHER2:
u8Off = OFFSET_ETHER2_TYPE;
SEntryTcam.UCfg13B.au8AftSV[u8Off++] = byTmpType[0];
SEntryTcam.UCfg13B.au8AftSV[u8Off++] = byTmpType[1];
u16ByteMsk = 0x003; //unmaked 1st,2nd octet after SMAC or VLAN-tag (0000 0000 0000 0011 b)
break;
case FRAME_FRMT_RFC1042:
STR_pvMemcpy(&SEntryTcam.UCfg13B.au8AftSV[2], au8RFC1042Ptn, sizeof(au8RFC1042Ptn));
u8Off = OFFSET_RFC1042_TYPE;
SEntryTcam.UCfg13B.au8AftSV[u8Off++] = byTmpType[0];
SEntryTcam.UCfg13B.au8AftSV[u8Off++] = byTmpType[1];
u16ByteMsk = 0x03FC; //unmaked 3rd,4th,5,6,7,8,9,10 octet after SMAC or VLAN-tag (0000 0011 1111 1100 b)
break;
case FRAME_FRMT_802_1H:
STR_pvMemcpy(&SEntryTcam.UCfg13B.au8AftSV[2], au8SNAP8021HPtn, sizeof(au8SNAP8021HPtn));
u8Off = OFFSET_802_1H_TYPE;
SEntryTcam.UCfg13B.au8AftSV[u8Off++] = byTmpType[0];
SEntryTcam.UCfg13B.au8AftSV[u8Off++] = byTmpType[1];
u16ByteMsk = 0x03FC;
break;
case FRAME_FRMT_SANP_OTHERS:
STR_pvMemcpy(&SEntryTcam.UCfg13B.au8AftSV[2], au8SNAPOtherPtn, sizeof(au8SNAPOtherPtn));
u8Off = OFFSET_SANP_OTHERS_OUI;
SEntryTcam.UCfg13B.au8AftSV[u8Off++] = pSInsEntry->abyOUI[0];
SEntryTcam.UCfg13B.au8AftSV[u8Off++] = pSInsEntry->abyOUI[1];
SEntryTcam.UCfg13B.au8AftSV[u8Off++] = pSInsEntry->abyOUI[2];
SEntryTcam.UCfg13B.au8AftSV[u8Off++] = byTmpType[0];
SEntryTcam.UCfg13B.au8AftSV[u8Off++] = byTmpType[1];
u16ByteMsk = 0x03FC;
break;
case FRAME_FRMT_LLC:
u8Off = OFFSET_DSAP;
SEntryTcam.UCfg13B.au8AftSV[u8Off++] = byTmpType[0];
SEntryTcam.UCfg13B.au8AftSV[u8Off++] = byTmpType[1];
u16ByteMsk = 0x000C; //unmaked 3rd,4th octet after SMAC or VLAN-tag (0000 0000 0000 1100 b)
break;
default:
return FALSE; // unknow frame format
}
#if defined(__LITTLE_ENDIAN)
// convert byte array to SIP,DIP,IpOpt
SWSRAM_vEndianConvert(&SEntryTcam.UCfg13B.au8AftSV[1],4);
SWSRAM_vEndianConvert(&SEntryTcam.UCfg13B.au8AftSV[5],4);
SWSRAM_vEndianConvert(&SEntryTcam.UCfg13B.au8AftSV[9],4);
#endif
SWTCAM_bInsEntry((UINT8)u16EntryIdx, &SEntryTcam, FALSE);
//
// 2.Insert L2+ masks array
//
STR_pvMemset(&SEntryTcam, 0, sizeof(STcamEntry));
SWTCAM_vUnMskEntry(&SEntryTcam, bIsIpv4, u16MskType, u16ByteMsk);
#if defined(__LITTLE_ENDIAN)
// convert byte array to SIP,DIP,IpOpt
SWSRAM_vEndianConvert(&SEntryTcam.UCfg13B.au8AftSV[1],4);
SWSRAM_vEndianConvert(&SEntryTcam.UCfg13B.au8AftSV[5],4);
SWSRAM_vEndianConvert(&SEntryTcam.UCfg13B.au8AftSV[9],4);
#endif
SWTCAM_bInsEntry((UINT8)u16EntryIdx, &SEntryTcam, TRUE);
//
// 3.Insert L2+ action array
//
STR_pvMemset(&SEntryAC, 0, sizeof(SL2pACEntry));
SEntryAC.bL2pVidValid = TRUE;
SEntryAC.u16L2pVid = pSInsEntry->u16Vid;
SWL2PAC_bInsEntry((UINT8)u16EntryIdx, &SEntryAC);
return TRUE;
}
BOOL SWPRVTB_bDelEntry(UINT16 u16Type, UINT16 u16Vid, UINT8 byFrameFormat)
{
UINT16 u16EntryIdx;
u16EntryIdx = SWPRVTB_u16SearchEntry(u16Type, u16Vid, byFrameFormat);
if (u16EntryIdx == UINT16_MAX )
return FALSE; // Entry not exist , then return operate fail.
SWL2PTB_vSetEntryInValidByIndex(u16EntryIdx);
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -