14 Star 9 Fork 0

zhangruoxu/demo

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
switch_data.c 14.88 KB
一键复制 编辑 原始数据 按行查看 历史
zhangruoxu 提交于 2023-11-23 17:14 . 头文件守卫
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
#include"basetype.h"
#include"common.h"
#include"switch_data.h"
#include"addr_lib.h"
#include"timer_data.h"
#include"debug_lib.h"
#define MAC_NODE_AGING 48
SWITCH_DEVICE_S g_stSwitchDeviceList;
UINT32 g_uiTimeId;
VOID* CheckTimeOut(UINT32 auiPara[4])
{
SWITCH_DEVICE_S* pstSwitch = g_stSwitchDeviceList.pstNextDevice;
SWITCH_MACNODE_S* pstMacNode;
MAC_TABLE_S* pstMacTable;
UINT16 usVlanid;
UINT16 usVlanCount = DEVICE_MAX_VLAN;
UINT32 NowTime;
UINT32 i, j;
for (;; ) // 遍历交换机设备
{
if (NULL == pstSwitch)
{
return;
}
for (i = 0; i < DEVICE_MAX_VLAN; i++)//遍历vlan地址表
{
pstMacTable = &pstSwitch->astMacTable[i];
for (j = 0; j < pstMacTable->usMacCount; j++) //遍历mac表
{
pstMacNode = &pstMacTable->astMacNode[j];
NowTime = TimerData_GetTimeNow();
if (NowTime > pstMacNode->uiAgingTime + MAC_NODE_AGING)// 把该表项删掉
{
usVlanid = pstMacTable[j].usVlanId;
MacData_Delete(pstSwitch->uiDeviceId, pstMacNode->aucMacAddr, pstMacNode->usSwitchPortNum, usVlanid);
}
}
}
pstSwitch = pstSwitch->pstNextDevice;
}
}
INT32 MacData_Init(VOID)
{
UINT32 auiPara[4];
UINT32 NowTime;
memset(&g_stSwitchDeviceList, 0, sizeof(SWITCH_DEVICE_S));
g_uiTimeId = TimerData_Add(2, TIMER_FLAG_ROUTINE, auiPara, CheckTimeOut);
return ERROR_SUCCESS;
}
/*
description: 添加一个交换机设备
input: UINT32 uiDeviceId, 添加的交换机id
output: 添加成功/失败
return: 错误码
tip: IN是空宏,表示该参数是输入。
author:
*/
INT32 MacData_AddDevice(IN UINT32 uiDeviceId)
{
SWITCH_DEVICE_S* pstSwitch;
UINT32 i;
pstSwitch = malloc(sizeof(SWITCH_DEVICE_S));
if (NULL == pstSwitch)
{
return ERROR_NO_MEMORY;
}
memset(pstSwitch, 0, sizeof(SWITCH_DEVICE_S));
pstSwitch->uiDeviceId = uiDeviceId;
pstSwitch->astMacTable[1].usVlanId = 1;
pstSwitch->astMacTable[1].usFlag = 1;
for (i = 0; i < DEVICE_MAX_VLAN_IF; i++)
{
pstSwitch->astIfCfg[i].usPortMode = IF_TYPE_ACCESS;
pstSwitch->astIfCfg[i].usVlanCount = 1;
pstSwitch->astIfCfg[i].astPermitVlanId[0] = 1;
}
pstSwitch->pstNextDevice = g_stSwitchDeviceList.pstNextDevice;
g_stSwitchDeviceList.pstNextDevice = pstSwitch;
return;
}
/*
*
description: 删除交换机设备
input: UINT32 uiDeviceId 删除的交换机id
output: 添加成功/失败
return: 错误码
tip: IN是空宏,表示该参数是输入。
author:
*/
INT32 MacData_DeleteDevice(IN UINT32 uiDeviceId)
{
SWITCH_DEVICE_S* pstSwitchPre = &g_stSwitchDeviceList;
SWITCH_DEVICE_S* pstSwitch = g_stSwitchDeviceList.pstNextDevice;
for (;;)
{
if (NULL == pstSwitch)
{
return;
}
if (uiDeviceId != pstSwitch->uiDeviceId)
{
pstSwitchPre = pstSwitch;
pstSwitch = pstSwitch->pstNextDevice;
}
else
{
/* uiDeviceId == pstSwitch->uiDeviceId */
pstSwitchPre->pstNextDevice = pstSwitch->pstNextDevice;
free(pstSwitch);
return;
}
}
}
/*
description: 根据设备ID查找交换机设备数据结构
input: UINT32 uiDeviceId 交换机设备id
output:
return: 成功,返回找到的交换机数据结构指针 /失败,返回NULL
tip: IN是空宏,表示该参数是输入。
author: 杨洋
*/
SWITCH_DEVICE_S* MacData_FindDevice(IN UINT32 uiDeviceId)
{
SWITCH_DEVICE_S* pstSwitch = g_stSwitchDeviceList.pstNextDevice;
for (;;)
{
if (NULL == pstSwitch)
{
return NULL;
}
if (uiDeviceId == pstSwitch->uiDeviceId)
{
return pstSwitch;
}
pstSwitch = pstSwitch->pstNextDevice;
}
}
INT32 Vlan_Add(IN UINT16 usDeviceId, IN UINT16 usVlanid)
{
SWITCH_DEVICE_S* pstSwitch;
MAC_TABLE_S* pstMacTable;
pstSwitch = MacData_FindDevice(usDeviceId);
if (NULL == pstSwitch)
{
return ERROR_NOT_FOUND;
}
if (usVlanid >= DEVICE_MAX_VLAN)
{
return ERROR_INDEX_EXCEED;
}
pstMacTable = &pstSwitch->astMacTable[usVlanid];
if (1 == pstMacTable->usFlag)
{
return ERROR_ALREADY_EXSISIT;
}
pstMacTable->usFlag = 1;
pstMacTable->usVlanId = usVlanid;
//DebugLib_Printf(MODULE_MACTABLE, "vlan类型:%d\n", IF_TYPE_ACCESS);
return ERROR_SUCCESS;
}
INT32 Vlan_Delete(IN UINT16 usDeviceId, IN UINT16 usVlanid)
{
SWITCH_DEVICE_S* pstSwitch = NULL;
MAC_TABLE_S* pstMacTable;
pstSwitch = MacData_FindDevice(usDeviceId);
if (NULL == pstSwitch)
{
return ERROR_NOT_FOUND;
}
if (usVlanid >= DEVICE_MAX_VLAN)
{
return ERROR_INDEX_EXCEED;
}
pstMacTable = &pstSwitch->astMacTable[usVlanid];
if (0 == pstMacTable->usFlag)
{
return ERROR_NOT_FOUND;
}
pstMacTable->usFlag = 0;
return ERROR_SUCCESS;
}
/*
description: 增加一条mac地址表项
input: UINT32 uiDeviceId 交换机设备id
UINT8* aucMacAddr mac地址
UINT16 usFlag mac地址类型MAC_NODE_XXX
UINT16 usSwitchPortNum, 增加到交换机的哪个接口
output:
return: 成功/失败(错误码)
tip: IN是空宏,表示该参数是输入。
author: 杨洋
*/
INT32 MacData_Add(IN UINT16 usDeviceId, IN UINT8* pucMacAddr, IN UINT32 uiAgingTime,
IN UINT16 usSwitchPortNum, IN UINT16 usVlanid)
{
UINT32 i;
SWITCH_DEVICE_S* pstSwitch;
SWITCH_MACNODE_S* pstMacNode;
MAC_TABLE_S* pstMacTable;
UINT32 uiNowTime;
pstSwitch = MacData_FindDevice(usDeviceId);
if (NULL == pstSwitch)
{
return ERROR_NOT_FOUND;
}
if (usSwitchPortNum >= DEVICE_MAX_VLAN_IF)
{
return ERROR_INDEX_EXCEED;
}
if (usVlanid >= DEVICE_MAX_VLAN)
{
return ERROR_INDEX_EXCEED;
}
pstMacTable = &pstSwitch->astMacTable[usVlanid];
if (1 != usVlanid && 0 == pstMacTable->usFlag)
{
return ERROR_SWITCH_VLAN_NOT_EXSIT;
}
//查找mac地址是否已经添加过
for (i = 0; i < pstMacTable->usMacCount; i++)
{
pstMacNode = &pstMacTable->astMacNode[i];
if (0 == memcmp(pstMacNode->aucMacAddr, pucMacAddr, MAC_BYTE))
{
//要添加的mac地址已经存在,更新端口编号
pstMacNode->usSwitchPortNum = usSwitchPortNum;
uiNowTime = TimerData_GetTimeNow();
if (MAC_NODE_STATIC == uiAgingTime)//静态表项
{
pstMacNode->uiAgingTime = uiAgingTime;
}
else//动态表项
{
pstMacNode->uiAgingTime = uiNowTime;
}
return ERROR_ALREADY_EXSISIT;
}
}
pstMacNode = &pstMacTable->astMacNode[pstMacTable->usMacCount];
//构造添加的新节点
memcpy(&pstMacNode->aucMacAddr, pucMacAddr, MAC_BYTE);
pstMacNode->usSwitchPortNum = usSwitchPortNum;
uiNowTime = TimerData_GetTimeNow();
if (MAC_NODE_STATIC == uiAgingTime) //静态表项
{
pstMacNode->uiAgingTime = uiAgingTime;
}
else//动态表项
{
pstMacNode->uiAgingTime = uiNowTime;
}
//DebugLib_Printf(MODULE_MACTABLE, "mac Type:%d\n", pstMacNode->uiAgingTime);
pstMacTable->usMacCount++;
return ERROR_SUCCESS;
}
/*
description: 删除一条mac地址表项
input: UINT32 uiDeviceID 交换机设备id
UINT8* aucMacAddr, 目的mac地址
IN UINT16 usFlag, mac地址类型
UINT16 usSwitchPortNum, 删除的交换机接口号
output: 成功/失败
return: 错误码
tip: IN是空宏,表示该参数是输入。
author:
*/
INT32 MacData_Delete(IN UINT32 uiDeviceId, IN UINT8* aucMacAddr, IN UINT16 usSwitchPortNum, IN UINT16 usVlanid)
{
SWITCH_DEVICE_S* pstSwitch;
SWITCH_MACNODE_S* pstMacNode;
MAC_TABLE_S* pstMacTable;
UINT32 i;
pstSwitch = MacData_FindDevice(uiDeviceId);
if (NULL == pstSwitch)
{
return ERROR_NOT_FOUND;
}
if (usSwitchPortNum >= DEVICE_MAX_VLAN_IF)
{
return ERROR_INDEX_EXCEED;
}
if (usVlanid >= DEVICE_MAX_VLAN)
{
return ERROR_INDEX_EXCEED;
}
pstMacTable = &pstSwitch->astMacTable[usVlanid];
//判断flag是不是1
if (1 != usVlanid && 0 == pstMacTable->usFlag)
{
return ERROR_SWITCH_VLAN_NOT_EXSIT;
}
//查找删除的mac地址是否存在
for (i = 0; i < pstMacTable->usMacCount; i++)
{
pstMacNode = &pstMacTable->astMacNode[i];
if (0 == memcmp(pstMacNode->aucMacAddr, aucMacAddr, MAC_BYTE))
{
//将count - 1位置上的结点拷贝到该位置上
memcpy(pstMacNode, &pstMacTable->astMacNode[pstMacTable->usMacCount - 1], sizeof(SWITCH_MACNODE_S));
ASSERT(pstMacTable->usMacCount > 0);
pstMacTable->usMacCount--;
return ERROR_SUCCESS;
}
}
return ERROR_NOT_EXIST;
}
/*
description: 将交换机的数据提封装成字符串提供给process层使用
input: UINT32 uiDeviceId, 交换机的id
INT8* pcString, 打印的字符串信息
UINT32 uiStringLength, 缓冲区的最大长度
output: 成功/失败
return: 错误码
tip: IN表示该参数是输入,OUT表示该参数是输出。
author: 杨洋
*/
INT32 MacData_Print(IN SWITCH_DEVICE_S* pstSwitchDevice, IN UINT16 usVlanid)
{
SWITCH_MACNODE_S* pstMacNode;
UINT32 uiTimeNow;
UINT8 aucMacAddrString[MAC_STRING_MAXLEN] = { 0 };
UINT8 aucMacAging[UINT_STRING_MAXLEN] = { 0 };
UINT32 i;
if (0 == pstSwitchDevice->astMacTable[usVlanid].usFlag)
{
return ERROR_INVALID_INPUT;
}
if (usVlanid >= DEVICE_MAX_VLAN)
{
return ERROR_INDEX_EXCEED;
}
printf("MAC Address\t\t Port\t\tType\t\tAge\n");
for (i = 0; i < pstSwitchDevice->astMacTable[usVlanid].usMacCount; i++)
{
pstMacNode = &pstSwitchDevice->astMacTable[usVlanid].astMacNode[i];
AddrLib_HextoMacString(pstMacNode->aucMacAddr, aucMacAddrString);
if (MAC_NODE_STATIC != pstMacNode->uiAgingTime)
{
uiTimeNow = TimerData_GetTimeNow();
sprintf(aucMacAging, "%d", MAC_NODE_AGING + pstMacNode->uiAgingTime - uiTimeNow);
printf("%s\t\t%d\t\t%s\t\t%s\n", aucMacAddrString, pstMacNode->usSwitchPortNum,
"dynamic", aucMacAging);
}
else
{
printf("%s\t\t%d\t\t%s\t\t%s\n", aucMacAddrString, pstMacNode->usSwitchPortNum,
"static", "forever");
}
}
return ERROR_SUCCESS;
}
/*
description: 允许指定的 VLAN 通过当前类型端口
input: UINT32 uiDeviceId 交换机设备id
UINT16 usVlanid Vlan号
UINT16 usSwitchPortNum 接口号
UINT16 usInterfaceType 接口类型
output: 成功/失败
return: (错误码)
tip: IN是空宏,表示该参数是输入。
author: 刘星雨
*/
INT32 Port_AddPermitVlan(IN UINT16 usDeviceId, IN UINT16 usVlanid, IN UINT16 usSwitchPortNum, IN UINT16 usPortMode)
{
SWITCH_DEVICE_S* pstSwitch;
SWITCH_IFCFG_S* pstIfCfg;
MAC_TABLE_S* pstMacTable;
UINT32 i;
pstSwitch = MacData_FindDevice(usDeviceId);
if (NULL == pstSwitch)
{
return ERROR_NOT_FOUND;
}
if (usSwitchPortNum >= DEVICE_MAX_VLAN_IF)
{
return ERROR_INDEX_EXCEED;
}
if (usVlanid >= DEVICE_MAX_VLAN)
{
return ERROR_INDEX_EXCEED;
}
pstMacTable = &pstSwitch->astMacTable[usVlanid];
//todo 检查vlan是否已经启用
if (0 == pstMacTable->usFlag)
{
return ERROR_SWITCH_VLAN_NOT_EXSIT;
}
pstIfCfg = &pstSwitch->astIfCfg[usSwitchPortNum];
if (usPortMode != pstIfCfg->usPortMode)
{
return ERROR_INVALID_INPUT;
}
for (i = 0; i < pstIfCfg->usVlanCount; i++)
{
if (usVlanid == pstIfCfg->astPermitVlanId)
{
return ERROR_ALREADY_EXSISIT;
}
}
if (IF_TYPE_ACCESS == pstIfCfg->usPortMode)
{
pstIfCfg->astPermitVlanId[0] = usVlanid;
}
else
{
pstIfCfg->astPermitVlanId[pstIfCfg->usVlanCount] = usVlanid;
pstIfCfg->usVlanCount++;
}
return ERROR_SUCCESS;
}
/*
description: 禁止指定的 VLAN 通过当前类型端口
input: UINT32 uiDeviceId 交换机设备id
UINT16 usVlanid Vlan号
UINT16 usSwitchPortNum 接口号
UINT16 usInterfaceType 接口类型
output: 成功/失败
return: (错误码)
tip: IN是空宏,表示该参数是输入。
author: 刘星雨
*/
INT32 Port_DeletePermitVlan(IN UINT16 usDeviceId, IN UINT16 usVlanid, IN UINT16 usSwitchPortNum, IN UINT16 usPortMode)
{
SWITCH_DEVICE_S* pstSwitch;
SWITCH_IFCFG_S* pstIfCfg;
MAC_TABLE_S* pstMacTable;
UINT16 usVlanIndex = DEVICE_MAX_VLAN;
pstSwitch = MacData_FindDevice(usDeviceId);
if (NULL == pstSwitch)
{
return ERROR_NOT_FOUND;
}
if (usSwitchPortNum >= DEVICE_MAX_VLAN_IF)
{
return ERROR_INDEX_EXCEED;
}
if (usVlanid >= DEVICE_MAX_VLAN)
{
return ERROR_INDEX_EXCEED;
}
pstMacTable = &pstSwitch->astMacTable[usVlanid];
if (0 == pstMacTable->usFlag)
{
return ERROR_NOT_EXIST;
}
pstIfCfg = &pstSwitch->astIfCfg[usSwitchPortNum];
for (int i = 0; i < pstIfCfg->usVlanCount; i++)
{
if (usVlanid == pstIfCfg->astPermitVlanId[i])
{
pstIfCfg->astPermitVlanId[i] = pstIfCfg->astPermitVlanId[pstIfCfg->usVlanCount - 1];
pstIfCfg->usVlanCount--;
return ERROR_SUCCESS;
}
}
return ERROR_FAIL;
}
/*
description: 配置端口类型
input: UINT32 uiDeviceId 交换机设备id
UINT16 usSwitchPortNum 接口号
UINT16 usInterfaceType 增加的接口类型
output: 成功/失败
return: (错误码)
tip: IN是空宏,表示该参数是输入。
author: 刘星雨
*/
//set
INT32 Port_SetMode(IN UINT16 usDeviceId, IN UINT16 usPortMode, IN UINT16 usSwitchPortNum, IN UINT16 usVlanid)
{
SWITCH_DEVICE_S* pstSwitch;
SWITCH_IFCFG_S* pstIfCfg;
UINT32 i;
pstSwitch = MacData_FindDevice(usDeviceId);
if (NULL == pstSwitch)
{
return ERROR_NOT_FOUND;
}
if (usSwitchPortNum >= DEVICE_MAX_VLAN_IF)
{
return ERROR_INDEX_EXCEED;
}
if (usVlanid >= DEVICE_MAX_VLAN)
{
return ERROR_INDEX_EXCEED;
}
pstIfCfg = &pstSwitch->astIfCfg[usSwitchPortNum];
//DebugLib_Printf(MODULE_MACTABLE, "设备类型:%d\t 传参类型:%d\n", pstIfCfg->usInterfaceType, usInterfaceType);
//do 的逻辑
if (usPortMode != IF_TYPE_NULL)
{
//IF_TYPE_ACCESS 改为IF_TYPE_TRUNK 直接改
if (IF_TYPE_ACCESS == pstIfCfg->usPortMode && usPortMode == IF_TYPE_TRUNK)
{
pstIfCfg->usPortMode = usPortMode;
}
else
{
//配置成跟原来一样的接口类型
if (pstIfCfg->usPortMode == usPortMode)
{
//IF_TYPE_ACCESS 改为 IF_TYPE_ACCESS,有两种情况
if (IF_TYPE_ACCESS == usPortMode)
{
//1。初始化的接口类型默认为IF_TYPE_ACCESS,第一次配置时需要更改允许的vlan
if (1 == pstIfCfg->astPermitVlanId[0])
{
pstIfCfg->astPermitVlanId[0] = usVlanid;
}
//2。配置其它的,需要先undo之后才能配置
else
{
return ERROR_ALREADY_EXSIT;
}
}
else
{
return ERROR_ALREADY_EXSIT;
}
}
else
{
//IF_TYPE_TRUNK改为IF_TYPE_ACCESS,不允许
return ERROR_INVALID_INPUT;
}
}
}
//undo
else
{
for (i = 0; i < pstIfCfg->usVlanCount; i++)
{
Port_DeletePermitVlan(usDeviceId, usVlanid, usSwitchPortNum, IF_TYPE_ACCESS);
}
pstIfCfg->usVlanCount = 1;
pstIfCfg->astPermitVlanId[0] = 1;
}
return ERROR_SUCCESS;
}
SWITCH_MACNODE_S* MacData_BestMatch(UINT8* aucMacaddr, UINT16 uiDeviceId, IN UINT16 usVlanid, IN UINT16 usifIndex)
{
SWITCH_DEVICE_S* pstSwitch = MacData_FindDevice(uiDeviceId);
SWITCH_MACNODE_S* pstMacNodes = NULL;
SWITCH_MACNODE_S* pstMacNode;
MAC_TABLE_S* pstMacTable;
UINT32 i;
UINT16 usMacCount;
if (NULL == pstSwitch)
{
return ERROR_NOT_FOUND;
}
if (usVlanid >= DEVICE_MAX_VLAN)
{
return ERROR_INDEX_EXCEED;
}
pstMacTable = &pstSwitch->astMacTable[usVlanid];
usMacCount = pstMacTable->usMacCount;
pstMacNodes = &pstMacTable->astMacNode;
for (i = 0; i < usMacCount; i++)
{
pstMacNode = &pstMacNodes[i];
if (0 == memcmp(aucMacaddr, pstMacNode->aucMacAddr, MAC_BYTE))
{
return pstMacNode;
}
}
return NULL;
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/zhangruoxudada/demo.git
git@gitee.com:zhangruoxudada/demo.git
zhangruoxudada
demo
demo
master

搜索帮助