📄 igmp_router.cpp~
字号:
TimeOut =
(TimerEntity *) StopTimer (IgmpGroup->
tGroupPortLastMemberQueryTimer[usPort]);
}
else
{
TimeOut = (TimerEntity *) CustomMalloc (sizeof (TimerEntity));
if (TimeOut == NULL)
{
if (bIgmpDebug)
{
printf ("Malloc Timer ERROR!\n");
}
return;
}
usCurrentTimer++;
}
TimeOut->TimerType = GroupPortLastMemberQueryTimeOutEvent;
TimeOut->IgmpGroup = IgmpGroup;
TimeOut->usPort = usPort;
IgmpGroup->tGroupPortLastMemberQueryTimer[usPort] =
StartTimer ((UINT) usLastMemberQueryInterval * 1000,
(TIMERFUNC) ProcessIgmpTimerEvent, (ULONG) TimeOut, TIMERONESHOT);
#endif
}
/***************************************************
函数名称:StopGroupPortLastMemberQueryTimer
函数功能:停止GroupPortLastMemberQuery定时器
输入参数:unTimerID 定时器ID号
返回值: 无
***************************************************/
void StopGroupPortLastMemberQueryTimer (GroupEntity * IgmpGroup, USHORT usPort)
{
IgmpGroup->tGroupPortLastMemberQueryTimer[usPort] = 0;
#if 0
TimerEntity *TimeOut;
if (unTimerID != 0)
{
TimeOut = (TimerEntity *) StopTimer (unTimerID);
CustomFree ((void *) TimeOut);
usCurrentTimer--;
}
#endif
}
void RouterSendGroupSpecificQuery (UINT unGroupAddress, UCHAR MaxResponseTime,
USHORT usPort)
{
SendIgmpPkt (IGMPMembershipQuery, unGroupAddress, usPort, MaxResponseTime);
}
void RouterSendGenernalQueryToAllPort (void)
{
SendIgmpPkt(IGMPMembershipQuery, 0, 1, 100);
}
/***************************************************
函数名称:TransformPVCToPort
函数功能:将PVC转换成端口号
输入参数:unPVC PVC的值
返回值: 转换后的端口号
***************************************************/
static USHORT TransformPVCToPort (UINT unPVC)
{
if(unPVC == 0)
{
return 0;
}
return ((USHORT) ((unPVC >> 4) & 0xFFFF) - 31);
}
/***************************************************
函数名称:PPPoENotifyIGMPUserOffline
函数功能:PPPoE用户下线后通知IGMP
输入参数:UINT unPVC 用户PVC
返回值: 无
***************************************************/
void PPPoENotifyIGMPUserOffline(UINT unPVC)
{
GroupEntity *pTemp;
pTemp = pGroupEntityList;
USHORT usPort = TransformPVCToPort(unPVC);
while(pTemp)
{
if(FindPortInSpecificGroup(pTemp, usPort))
{
/*DeletePortFromSpecificGroup(pTemp,usPort);*/
}
pTemp = pTemp->pNext;
}
}
void AddPortToSearchGroup(GroupEntity * IgmpGroup,USHORT usPort)
{
/*SearchGroup * pSearchGroup;*/
SearchNode * pSearchNode;
pSearchNode = (SearchNode *) malloc (sizeof(struct search_node));
if (NULL == pSearchNode)
return;
pSearchNode->pNext = IgmpGroup->pNode;
pSearchNode->usPort = usPort;
IgmpGroup->pNode = pSearchNode;
}
void DelPortFromSearchGroup(GroupEntity * IgmpGroup,USHORT usPort)
{
SearchNode *pSearchNode;
SearchNode *pSearchNodeTemp;
if(IgmpGroup->pNode == NULL)
{
return;
}
if(IgmpGroup->pNode->usPort == usPort)
{
pSearchNode = IgmpGroup->pNode;
IgmpGroup->pNode = pSearchNode->pNext;
free(pSearchNode);
return;
}
pSearchNodeTemp = IgmpGroup->pNode;
pSearchNode = IgmpGroup->pNode->pNext;
while(pSearchNode)
{
if(pSearchNode->usPort == usPort)
{
pSearchNodeTemp->pNext = pSearchNode->pNext;
free(pSearchNode);
return;
}
pSearchNodeTemp = pSearchNodeTemp->pNext;
pSearchNode = pSearchNode->pNext;
}
}
/************************************************************************************
函数名称: IpToMultimac
功能描述: 把组播IP地址映射为组播MAC地址
输入参数: ipaddr
输出参数: ether_addr
返回值: N/A
************************************************************************************/
void IpToMutimac1 (struct in_addr ipaddr, u_char * ether_addr)
{
u_char *p_ip;
p_ip = (u_char *) & (ipaddr.s_addr);
ether_addr[0] = 0x01;
ether_addr[1] = 0x00;
ether_addr[2] = 0x5e;
ether_addr[3] = p_ip[1] & 0x7f; /* modified by zhangxinhui */
ether_addr[4] = p_ip[2];
ether_addr[5] = p_ip[3];
}
/*extern void bcm_mcast_addr_t_init (bcm_mcast_addr_t *mcaddr,mac_addr_t mac, bcm_vlan_t vid);
extern void bcmk_mcast_addr_init(bcm_mcast_addr_t *mcaddr,mac_addr_t mac, bcm_vlan_t vid);
extern int bcmk_mcast_addr_add(bcm_mcast_addr_t mcxaddr);
extern int bcmj_mcast_addr_add(bcm_mcast_addr_t *mcxaddr);
extern void bcm_mcast_addr_init(bcm_mcast_addr_t *mcaddr,mac_addr_t mac, bcm_vlan_t vid);
extern int bcmk_mcast_join(mac_addr_t mcMacAddr, bcm_vlan_t vlanId,int srcPort);
extern int bcmj_mcast_join(int dev, mac_addr_t mcMacAddr, bcm_vlan_t vlanId,int srcPort);
extern int bcmk_mcast_addr_remove(mac_addr_t mac, bcm_vlan_t vid);
extern int bcmj_mcast_addr_remove(mac_addr_t mac, bcm_vlan_t vid);
extern int bcmk_mcast_leave(mac_addr_t mcMacAddr, bcm_vlan_t vlanId,int srcPort);
extern int bcmj_mcast_leave(int dev, mac_addr_t mcMacAddr, bcm_vlan_t vlanId,int srcPort); */
/*函数功能:设置某VLAN中的unknown mcast的转发方式.
输入参数:unit,,设备号,永远为0;vlanid,组播组对应的VLAN ID;mode1,Multicast的转发方式,0表示所有组播组在VLAN中广播,1表示已知组播组在VLAN中按组播方式转发,未知组播组在VLAN中广播,2表示已知组播在组播组中转发,未知组播丢弃.
输出参数:无.
返回值: 0 ,成功;<0,失败.
备注: 注意与bcm5690/bcm5695的区别.一般在组播功能打开时,转发应该设置为模式2,组播功能关闭时转发应该设置为模式0.*/
/*int bcm_vlan_mcast_flood_set(int unit, short vlanid, int mode);*/
/************************************************************************************
函数名称: AddGroup
功能描述: 写硬件组播表
输入参数: unGroupAddress
输出参数: 正确返回OK,失败返回ERROR
返回值: N/A
作者 : aibin 2005-01-24
************************************************************************************/
int AddGroup(UINT unGroupAddress)
{
/*struct IS_GROUP_MAC *p_groupmac = NULL;*/
/*int group_vid = -1, find, i;*/
struct in_addr gip;
gip.s_addr = unGroupAddress;
u_char gmac[6];
int i;
bcm_mcast_addr_t mcaddr[2];
mac_addr_t mac_address;
bcm_vlan_t vlanId;
bcm_pbmp_t pbmp;
bcm_pbmp_t ubmp;
unsigned char dev;
unsigned char portOffSet;
int temp_dev, temp_portOffSet;
IpToMutimac1 (gip, gmac);
/*1.b.1 创建一个组播条目,以router_port[].vid为该组的vid */
memcpy (mac_address,0, 8);
memcpy (mac_address,gmac, 6);
vlanId = GetGroupVlan (unGroupAddress);
if (bIgmpDebug)
{
printf ("\r\ncreate group %s, vid= %d\r\n", inet_ntoa (gip), vlanId);
}
memset(&pbmp,0,sizeof(bcm_pbmp_t));
memset(&ubmp,0,sizeof(bcm_pbmp_t));
#ifdef _AN5116_06A_
bcm_mcast_addr_t_init(&mcaddr[0], mac_address, vlanId);
#else
bcm_mcast_addr_init(&mcaddr[0], mac_address, vlanId);
bcm_mcast_addr_init(&mcaddr[1], mac_address, vlanId);
#endif
mcaddr[0].pbmp=pbmp;
mcaddr[0].ubmp=ubmp;
mcaddr[1].pbmp=pbmp;
mcaddr[1].ubmp=ubmp;
#ifdef _AN5116_06A_
/*if (bcm_vlan_mcast_flood_set(0, vlanId, 2) < 0)
{
return ERROR;
}*/
if (bcmk_mcast_addr_add(mcaddr[0])<0)
{
/* bcm_vlan_mcast_flood_set(0, vlanId, 0);*/
return ERROR;
}
#else
if (bcmj_mcast_addr_add(mcaddr)<0)
{
return ERROR;
}
#endif
return OK;
}
int chip5695 = 0;
/************************************************************************************
函数名称: AddPortToGroup
功能描述: 增加表项到硬件组播表
输入参数: unGroupAddress 组播ip地址
usPort 接收到的包的端口号(槽位号)
输出参数: 正确返回OK,失败返回ERROR
返回值: N/A
作者 : aibin 2005-01-24
************************************************************************************/
int AddPortToGroup (UINT unGroupAddress, USHORT usPort)
{
struct in_addr gip;
gip.s_addr = unGroupAddress;
mac_addr_t mac_address;
unsigned char dev, dev1;
unsigned char portOffSet, portOffSet1;
int vlan;
short vlanid;
if(igmp_get_510port(usPort,&dev,&portOffSet)<0)
return ERROR;
IpToMutimac1 (gip, mac_address);
/*get vlan from online group, aibin 20080320*/
vlanid = GetOnlineGroupVlan(unGroupAddress);
if (-1 == vlanid)
{
printf ("not online group %x\r\n", unGroupAddress);
return -1;
}
/*vlanid = GetGroupVlan (unGroupAddress);*/
/*in cross vlan mode, add slot untag to group vlan, and add uplink port tag to group vlan*/
if(0) /*epon全部以tag流下发到线卡2007-03-11 aibin (gEnableCrossVlan)*/
{
if (usPort >(usMaxPort-8))
{
debug_setslotvlan_no_pvid(usPort, 1, 0x1ffffff, 1, vlanid);
}
else
{
debug_setslotvlan_no_pvid(usPort, 0, 0x1ffffff, 1, vlanid);
}
}
if (bIgmpDebug)
{
printf ("\r\nadd slot %d to %s, vid= %d\r\n", usPort, inet_ntoa (gip), vlanid);
}
#ifdef _AN5116_06A_
if (ERROR == bcmk_mcast_join(mac_address, vlanid, portOffSet))
{
return ERROR;
}
#else
if (ERROR == bcmj_mcast_join(dev, mac_address, vlanid, portOffSet))
{
return ERROR;
}
#endif
return OK;
}
int GetOnlineGroupVlan (UINT groupaddress)
{
GroupEntity *pTemp;
pTemp = FindIgmpGroupByAddress(groupaddress);
if (NULL == pTemp)
return -1;
return pTemp->OutVlanTag;
}
/************************************************************************************
函数名称: DelGroup
功能描述: 在底层删除 相应组的组播转发表
输入参数: unGroupAddress 组播ip地址
输出参数: 正确返回OK,失败返回ERROR
返回值: N/A
作者 : aibin 2005-01-25
************************************************************************************/
int DelGroup (UINT unGroupAddress)
{
struct in_addr gip;
gip.s_addr = unGroupAddress;
mac_addr_t mac_address;
IpToMutimac1 (gip, mac_address);
short vlanid;
/*get vlan from online group, aibin 20080320*/
vlanid = GetOnlineGroupVlan(unGroupAddress);
if (-1 == vlanid)
{
printf ("not online group %x\r\n", unGroupAddress);
return -1;
}
/*vlanid = GetGroupVlan (unGroupAddress);*/
if (bIgmpDebug)
{
printf ("\r\nremoved group %s, vid= %d\r\n", inet_ntoa (gip), vlanid);
printf("mac_address is %x:%x:%x:%x:%x:%x, vlan: %d\r\n", mac_address[0],mac_address[1],mac_address[2],mac_address[3],mac_address[4],mac_address[5], vlanid);
}
#ifdef _AN5116_06A_
if (ERROR == bcmk_mcast_addr_remove(mac_address, vlanid))
{
/*bcm_vlan_mcast_flood_set(0, vlanid, 1);*/
return ERROR;
}
/*bcm_vlan_mcast_flood_set(0, vlanid, 0);*/
return OK;
#else
if (ERROR == bcmj_mcast_addr_remove(mac_address, vlanid))
{
return ERROR;
}
return OK;
#endif
}
/************************************************************************************
函数名称: DelPortFromGroup1
功能描述: 在硬件表中删除端口 (线卡的曹位 )
输入参数: unGroupAddress 组播ip地址
usPort 接收到的包的端口号(槽位号)
输出参数: 正确返回OK,失败返回ERROR
返回值: N/A
作者 : aibin 2005-01-25
************************************************************************************/
int DelPortFromGroup1 (UINT unGroupAddress, USHORT usPort)
{
struct in_addr gip;
gip.s_addr = unGroupAddress;
mac_addr_t mac_address;
unsigned char dev;
short vlanid;
unsigned char portOffSet;
/*get vlan from online group, aibin 20080320*/
vlanid = GetOnlineGroupVlan(unGroupAddress);
if (-1 == vlanid)
{
printf ("not online group %x\r\n", unGroupAddress);
return -1;
}
/*vlanid = GetGroupVlan (unGroupAddress);*/
if(igmp_get_510port(usPort,&dev,&portOffSet)<0)
return ERROR;
IpToMutimac1 (gip, mac_address);
if (bIgmpDebug)
{
printf ("\r\ndel slot %d from %s, vid= %d\r\n", usPort, inet_ntoa (gip), vlanid);
printf("mac_address is %x:%x:%x:%x:%x:%x, vlan: %d, dev = %d, portoff= %d \r\n", mac_address[0],mac_address[1],mac_address[2],mac_address[3],mac_address[4],mac_address[5], vlanid, dev, portOffSet);
}
#ifdef _AN5116_06A_
if (ERROR == bcmk_mcast_leave(mac_address, vlanid, portOffSet))
{
return ERROR;
}
return OK;
#else
if (ERROR == bcmj_mcast_leave(dev, mac_address, vlanid, portOffSet))
{
return ERROR;
}
return OK;
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -