📄 igmp_router.cpp
字号:
}
#if 0
TimerEntity *TimeOut;
if (IgmpGroup->tGroupPortLastMemberQueryTimer[usPort] != 0)
{
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 + -