📄 igmp_snoop.c
字号:
/*and only if this query is an igmp v1 query can we del the igmpv1 timer*/
if ((igmp_snoop_router_entry_to_find->router_v1flag == TRUE) && (timer == 0))
{
/*the router has been a router v1 type*/
del_timer_return = hos_deltimer(igmp_snoop_router_entry_to_find->igmpv1_timer_id);
if(ERROR != del_timer_return)
{
/*hos_deltimer(igmp_snoop_router_entry_to_find->igmpv1_timer_id); */ /*igmpv1_timer_id may be 0*/
igmp_snoop_router_entry_to_find->igmpv1_timer_id = 0;
kfree(igmp_snoop_router_entry_to_find->rec_igmpv1_pkt_msg);
igmp_snoop_router_entry_to_find->rec_igmpv1_pkt_msg = NULL;
}
else
timer = 1; /*declare the query is not v1*/
}
}
else
{ /*on the port there is no router,so we should first add a port in the router list*/
igmp_snoop_router_entry_to_find = igmp_snoop_router_add(port_no, ROUTER_TIME_OUT_TIMER,VID);
}
igmp_snoop_router_entry_to_find->rec_pkt_msg = igmp_snoop_pkt_msg;
igmp_snoop_router_entry_to_find->router_timer = ROUTER_TIME_OUT_TIMER;
igmp_snoop_router_entry_to_find->timer_id = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, ROUTER_TIME_OUT_TIMER, NULL, (char *) igmp_snoop_pkt_msg);
/*check if the timer' value,zero presents that it is an igmpv1 router,we should create a
*igmp_snoop_pktv1_msg for its igmp v1 timer
*/
if (timer == 0)
{
igmp_snoop_pktv1_msg = (struct igmp_snoop_pkt_msg *)kmalloc(sizeof (struct igmp_snoop_pkt_msg) , IGMP_SNOOPING_MOD_ID);
if(NULL == igmp_snoop_pktv1_msg)
return NULL;
bzero ((char *)igmp_snoop_pktv1_msg, sizeof (struct igmp_snoop_pkt_msg));
if(igmp_snoop_pktv1_msg == NULL)
{
syslog(LOG_INFO,"No free momory for new igmp_snoop_pktv1_msg");
return ERROR;
}
igmp_snoop_pktv1_msg->port_no = port_no;
igmp_snoop_pktv1_msg->time_out_type = ROUTER_V1_TIME_OUT;
igmp_snoop_router_entry_to_find->rec_igmpv1_pkt_msg = igmp_snoop_pktv1_msg;
igmp_snoop_router_entry_to_find->igmpv1_timer_id = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, ROUTER_V1_TIME_OUT_TIMER, NULL, (char *) igmp_snoop_pktv1_msg);
/*version 1 router present timeout is 400s*/
igmp_snoop_router_entry_to_find->router_v1flag = TRUE;
}
}
/***************************************************************************************************
* Func: igmp_memebership_report_process
*This function processes the received igmp_memebership_report packet.
*Input: port_no - the port_no from which received this packet
* ih_type - the type of the msg
* VID - the VID to which the port_no belongs
* enaddr - the mac address of the packet
* group_addr - the ip address of the group
*Output:OK -the packet is normally disposed
* ERROR - meets error when processing the packet
****************************************************************************************************/
/*int igmp_memebership_report_process(int port_no,char *pkt, int len, int VID, unsigned char enaddr[6], unsigned int group_addr )*/
int igmp_memebership_report_process(int port_no,short ih_type, int VID, unsigned char enaddr[6], unsigned int group_addr )
{
long timer = GROUP_MEMEBER_SHIP_INTERVAL; /*260s*/
int del_timer_return;
struct igmp_snoop_pkt_msg *igmp_snoop_pkt_msg , *igmp_snoop_pktv1_msg;
struct igmp_snoop_mac_group *igmp_snoop_mac_to_join;
struct igmp_snoop_group *igmp_snoop_group_to_join;
struct igmphdr *ih;
vlanentry *v;
/*now we create a igmp_snoop_pkt_msg*/
igmp_snoop_pkt_msg = (struct igmp_snoop_pkt_msg *)kmalloc(sizeof (struct igmp_snoop_pkt_msg) , IGMP_SNOOPING_MOD_ID);
if(NULL == igmp_snoop_pkt_msg)
return NULL;
bzero ((char *)igmp_snoop_pkt_msg, sizeof (struct igmp_snoop_pkt_msg));
if(igmp_snoop_pkt_msg == NULL)
{
syslog(LOG_INFO,"No free momory for new igmp_snoop_pkt_msg");
return ERROR;
}
igmp_snoop_pkt_msg->port_no = port_no;
igmp_snoop_pkt_msg->time_out_type = GROUP_TIME_OUT;
igmp_snoop_pkt_msg->VID = VID;
igmp_snoop_pkt_msg->group_addr = group_addr;
if(ih_type == IGMP_V1_MEMBERSHIP_REPORT)
{
igmp_snoop_pktv1_msg = (struct igmp_snoop_pkt_msg *)kmalloc(sizeof (struct igmp_snoop_pkt_msg) , IGMP_SNOOPING_MOD_ID);
if(NULL == igmp_snoop_pktv1_msg)
return NULL;
bzero ((char *)igmp_snoop_pktv1_msg, sizeof (struct igmp_snoop_pkt_msg));
if(igmp_snoop_pktv1_msg == NULL)
{
syslog(LOG_INFO,"No free momory for new igmp_snoop_pktv1_msg");
return ERROR;
}
igmp_snoop_pktv1_msg->port_no = port_no;
igmp_snoop_pktv1_msg->time_out_type = GROUP_V1_TIME_OUT;
igmp_snoop_pktv1_msg->VID = VID;
igmp_snoop_pktv1_msg->group_addr = group_addr;
}
igmp_snoop_mac_to_join = igmp_snoop_mac_find(VID,enaddr);
igmp_snoop_group_to_join = NULL;
if (igmp_snoop_mac_to_join == NULL)
{
/*there is no the igmp_snoop_mac_group*/
igmp_snoop_mac_to_join = igmp_snoop_mac_add(VID, enaddr);
igmp_snoop_mac_to_join->port_no_list[0] = port_no;
#ifdef _FLEX_HAMMER_
v = vlan_get_by_VID(igmp_snoop_mac_to_join->VIDX);
vlan_pseduo_add_port(v,igmp_snoop_mac_to_join->VIDX,port_no);
#endif
#ifdef _U_24_IGMPSNOOPING_
u24_driver_add_igmp_snooping_port(igmp_snoop_mac_to_join->VID ,igmp_snoop_mac_to_join->macaddr.addr, port_no);
#endif
igmp_snoop_group_to_join = igmp_snoop_group_add(igmp_snoop_mac_to_join, group_addr);
add_each_router_port_to_group(igmp_snoop_mac_to_join, igmp_snoop_group_to_join ,port_no);
igmp_snoop_group_to_join->port_no_list[0] = port_no;
igmp_snoop_group_to_join->rec_pkt_msg[port_no] = igmp_snoop_pkt_msg;
/*add timer for group and port*/
igmp_snoop_group_to_join->timer_id[port_no] = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, timer, NULL, (char *) igmp_snoop_pkt_msg);
if(ih_type == IGMP_V1_MEMBERSHIP_REPORT)
{
igmp_snoop_group_to_join->rec_igmpv1_pkt_msg[port_no] = igmp_snoop_pktv1_msg;
igmp_snoop_group_to_join->igmpv1_timer_id[port_no] = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, GROUP_V1_MEMEBER_SHIP_INTERVAL, NULL, (char *) igmp_snoop_pktv1_msg);
igmp_snoop_group_to_join->host_v1flag[port_no] = TRUE;
}
}
else
{
/* the igmp_snoop_mac_group has existed*/
int i = 0;
while((igmp_snoop_mac_to_join->port_no_list[i] != port_no) && (i<MAXPortNum))
{
i++;
}
if (igmp_snoop_mac_to_join->port_no_list[i] == port_no)
{
/*the mac group has existed , also as the port no */
igmp_snoop_group_to_join = igmp_snoop_group_find(igmp_snoop_mac_to_join, group_addr);
if (igmp_snoop_group_to_join == NULL)
{
/*the igmp_snoop_group doesn't exist*/
igmp_snoop_group_to_join = igmp_snoop_group_add(igmp_snoop_mac_to_join, group_addr);
add_each_router_port_to_group(igmp_snoop_mac_to_join, igmp_snoop_group_to_join ,port_no);
igmp_snoop_group_to_join->port_no_list[0] = port_no;
igmp_snoop_group_to_join->host_v1flag[port_no] = FALSE;
/*add timer for group and port*/
igmp_snoop_group_to_join->rec_pkt_msg[port_no] = igmp_snoop_pkt_msg;
igmp_snoop_group_to_join->timer_id[port_no] = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, timer, NULL, (char *) igmp_snoop_pkt_msg);
if(ih_type == IGMP_V1_MEMBERSHIP_REPORT)
{
igmp_snoop_group_to_join->rec_igmpv1_pkt_msg[port_no] = igmp_snoop_pktv1_msg;
igmp_snoop_group_to_join->igmpv1_timer_id[port_no] = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, GROUP_V1_MEMEBER_SHIP_INTERVAL, NULL, (char *) igmp_snoop_pktv1_msg);
igmp_snoop_group_to_join->host_v1flag[port_no] = TRUE;
}
}
else
{
/*check if the port has existed in the group,if yes then refresh the timer
*else add the port and timer
*/
int i = 0;
while((igmp_snoop_group_to_join->port_no_list[i] != port_no) && (i<MAXPortNum))
{
i++;
}
if (igmp_snoop_group_to_join->port_no_list[i] == port_no)
{ /* the port_no has existed,refresh the timer*/
del_timer_return = hos_deltimer(igmp_snoop_group_to_join->timer_id[port_no]);
if(ERROR == del_timer_return)
{
kfree(igmp_snoop_pkt_msg);
if(ih_type == IGMP_V1_MEMBERSHIP_REPORT)
kfree(igmp_snoop_pktv1_msg);
return ERROR;
}
kfree(igmp_snoop_group_to_join->rec_pkt_msg[port_no]);
igmp_snoop_group_to_join->rec_pkt_msg[port_no] = NULL;
/* hos_deltimer(igmp_snoop_group_to_join->timer_id[port_no]);*/
igmp_snoop_group_to_join->timer_id[port_no] = 0;
igmp_snoop_group_to_join->rec_pkt_msg[port_no] = igmp_snoop_pkt_msg;
igmp_snoop_group_to_join->timer_id[port_no] = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, timer, NULL, (char *) igmp_snoop_pkt_msg);
if(ih_type == IGMP_V1_MEMBERSHIP_REPORT)
{
if (igmp_snoop_group_to_join->host_v1flag[port_no] == TRUE)
{
del_timer_return = hos_deltimer(igmp_snoop_group_to_join->igmpv1_timer_id[port_no]);
if(ERROR == del_timer_return)
{
kfree(igmp_snoop_pktv1_msg);
return ERROR;
}
kfree(igmp_snoop_group_to_join->rec_igmpv1_pkt_msg[port_no]);
igmp_snoop_group_to_join->rec_igmpv1_pkt_msg[port_no] = NULL;
/* hos_deltimer(igmp_snoop_group_to_join->igmpv1_timer_id[port_no]);*/
igmp_snoop_group_to_join->igmpv1_timer_id[port_no] = 0;
}
igmp_snoop_group_to_join->rec_igmpv1_pkt_msg[port_no] = igmp_snoop_pktv1_msg;
igmp_snoop_group_to_join->igmpv1_timer_id[port_no] = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, GROUP_V1_MEMEBER_SHIP_INTERVAL, NULL, (char *) igmp_snoop_pktv1_msg);
igmp_snoop_group_to_join->host_v1flag[port_no] = TRUE;
}
}
else
{ /*the port no does'nt exist*/
int j = 0, i = 0;
for(j = 0; j<MAXPortNum; j++)
{
if (igmp_snoop_group_to_join->port_no_list[j] == 0)
{
i = j;
j = MAXPortNum;
}
}
igmp_snoop_group_to_join->port_no_list[i] = port_no;
igmp_snoop_group_to_join->host_v1flag[port_no] = FALSE;
/*add the timer*/
igmp_snoop_group_to_join->rec_pkt_msg[port_no] = igmp_snoop_pkt_msg;
igmp_snoop_group_to_join->timer_id[port_no] = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, timer, GROUP_TIME_OUT, (char *) igmp_snoop_pkt_msg);
if(ih_type == IGMP_V1_MEMBERSHIP_REPORT)
{
igmp_snoop_group_to_join->rec_igmpv1_pkt_msg[port_no] = igmp_snoop_pktv1_msg;
igmp_snoop_group_to_join->igmpv1_timer_id[port_no] = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, GROUP_V1_MEMEBER_SHIP_INTERVAL, GROUP_TIME_OUT, (char *) igmp_snoop_pktv1_msg);
igmp_snoop_group_to_join->host_v1flag[port_no] = TRUE;
}
}
}
}
else
{
/*the mac group has existed , but the port no doesn't exist */
int j = 0 , i = 0;
for(j = 0; j<MAXPortNum; j++)
{
if (igmp_snoop_mac_to_join->port_no_list[j] == 0)
{
i = j;
j = MAXPortNum;
}
}
igmp_snoop_mac_to_join->port_no_list[i] = port_no;
#ifdef _FLEX_HAMMER_
v = vlan_get_by_VID(igmp_snoop_mac_to_join->VIDX);
vlan_pseduo_add_port(v,igmp_snoop_mac_to_join->VIDX,port_no);
#endif
#ifdef _U_24_IGMPSNOOPING_
u24_driver_add_igmp_snooping_port(igmp_snoop_mac_to_join->VID ,igmp_snoop_mac_to_join->macaddr.addr, port_no);
#endif
igmp_snoop_group_to_join = igmp_snoop_group_find(igmp_snoop_mac_to_join, group_addr);
if (igmp_snoop_group_to_join == NULL)
{
/*the igmp_snoop_group doesn't exist*/
igmp_snoop_group_to_join = igmp_snoop_group_add(igmp_snoop_mac_to_join, group_addr);
add_each_router_port_to_group(igmp_snoop_mac_to_join, igmp_snoop_group_to_join ,port_no);
igmp_snoop_group_to_join->port_no_list[0] = port_no;
igmp_snoop_group_to_join->host_v1flag[port_no] = FALSE;
/*add timer for group and port*/
igmp_snoop_group_to_join->rec_pkt_msg[port_no] = igmp_snoop_pkt_msg;
igmp_snoop_group_to_join->timer_id[port_no] = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, timer, NULL, (char *) igmp_snoop_pkt_msg);
if(ih_type == IGMP_V1_MEMBERSHIP_REPORT)
{
igmp_snoop_group_to_join->rec_igmpv1_pkt_msg[port_no] = igmp_snoop_pktv1_msg;
igmp_snoop_group_to_join->igmpv1_timer_id[port_no] = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, GROUP_V1_MEMEBER_SHIP_INTERVAL, GROUP_TIME_OUT, (char *) igmp_snoop_pktv1_msg);
igmp_snoop_group_to_join->host_v1flag[port_no] = TRUE;
}
}
else
{
/*the igmp_snoop_group exists, but the port no doesn't exist*/
int j = 0, i = 0;
for(j = 0; j<MAXPortNum; j++)
{
if (igmp_snoop_group_to_join->port_no_list[j] == 0)
{
i = j;
j = MAXPortNum;
}
}
igmp_snoop_group_to_join->port_no_list[i] = port_no;
/*add the timer*/
igmp_snoop_group_to_join->rec_pkt_msg[port_no] = igmp_snoop_pkt_msg;
igmp_snoop_group_to_join->timer_id[port_no] = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, timer, GROUP_TIME_OUT, (char *) igmp_snoop_pkt_msg);
igmp_snoop_group_to_join->host_v1flag[port_no] = FALSE;
igmp_snoop_group_to_join->igmpv1_timer_id[port_no] = 0;
if(ih_type == IGMP_V1_MEMBERSHIP_REPORT)
{
igmp_snoop_group_to_join->rec_igmpv1_pkt_msg[port_no] = igmp_snoop_pktv1_msg;
igmp_snoop_group_to_join->igmpv1_timer_id[port_no] = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, GROUP_V1_MEMEBER_SHIP_INTERVAL, GROUP_TIME_OUT, (char *) igmp_snoop_pktv1_msg);
igmp_snoop_group_to_join->host_v1flag[port_no] = TRUE;
}
}
}
}
}
/***************************************************************************************************
* Func: other_router_port_timeout_process
*This function processes the other router port timeout msg .
*Input: msg - the msg received from msg queue
*Output:OK -the msg is normally processed
* ERROR - meets error when processing the msg
****************************************************************************************************/
int other_router_port_timeout_process(TIMERMSG_S *msg)
{
short port_no_to_del ,VID;
struct igmp_snoop_pkt_msg *igmp_snoop_pkt_msg;
struct igmp_snoop_router_entry *p;
igmp_snoop_pkt_msg = (struct igmp_snoop_pkt_msg *)msg->parg;
port_no_to_del = igmp_snoop_pkt_msg->port_no;
VID = igmp_snoop_pkt_msg->VID;
p = igmp_snoop_router_find(port_no_to_del,VID);
if (p == NULL)
return ERROR;
kfree(igmp_snoop_pkt_msg);
igmp_snoop_pkt_msg = NULL;
igmp_snoop_router_del(port_no_to_del ,VID);
}
/***************************************************************************************************
* Func: router_port_timeout_process
*This function processes the router port timeout msg .
*Input: msg - the msg received from msg queue
*Output:OK -the msg is normally processed
* ERROR - meets error when processing the msg
****************************************************************************************************/
int router_port_timeout_process(TIMERMSG_S *msg)
{
short port_no_to_del,VID;
struct igmp_snoop_pkt_msg *igmp_snoop_pkt_msg;
struct igmp_snoop_router_entry *p;
igmp_snoop_pkt_msg = (struct igmp_snoop_pkt_msg *)msg->parg;
port_no_to_del = igmp_snoop_pkt_msg->port_no;
VID = igmp_snoop_pkt_msg->VID;
p = igmp_snoop_router_find(port_no_to_del,VID);
if (p == NULL)
return ERROR;
kfree(igmp_snoop_pkt_msg);
igmp_snoop_pkt_msg = NULL;
igmp_snoop_router_del(port_no_to_del ,VID);
}
/***************************************************************************************************
* Func: group_port_timeout_process
*This function processes the group port timeout msg .
*Input: msg - the msg received from msg queue
*Output:OK -the msg is normally processed
* ERROR - meets error when processing the msg
****************************************************************************************************/
int group_port_timeout_process(TIMERMSG_S *msg)
{
int VID,VIDX;
short port_no;
char *pkt;
int len, i, port_index_return;
unsigned int group_addr;
unsigned char enaddr[6];
vlanentry * v;
struct igmp_snoop_router_entry *p_router;
int port_exist_flag = FALSE;
long timer = GROUP_MEMEBER_SHIP_INTERVAL; /*260s*/
struct igmp_snoop_mac_group *igmp_snoop_mac_group_to_find, *p_mac;
struct igmp_snoop_group *igmp_snoop_group_to_find, *p_group, *q_group;
struct igmp_snoop_pkt_msg *igmp_snoop_pkt_msg, *igmp_snoop_pkt_new_msg;
igmp_snoop_pkt_msg = (struct igmp_snoop_pkt_msg *)msg->parg;
VID = igmp_snoop_pkt_msg->VID;
port_no = igmp_snoop_pkt_msg->port_no;
group_addr = igmp_snoop_pkt_msg->group_addr;
IGMP_ETHER_MAP_IP_MULTICAST(&group_addr, enaddr);
igmp_snoop_mac_group_to_find = igmp_snoop_mac_find(VID, enaddr);
if (NULL == igmp_snoop_mac_group_to_find)
return;
igmp_snoop_group_to_find = igmp_snoop_group_find(igmp_snoop_mac_group_to_find, group_addr);
if (NULL == igmp_snoop_group_to_find)
return;
port_index_return = igmp_snoop_group_port_find(igmp_snoop_group_to_find,port_no);
if (port_index_return == ERROR)
return;
/*we should first check whether there is router on this port*/
p_router = igmp_snoop_router_find(port_no,VID);
if (p_router != NULL)
{
/*if there is router on this port ,so we should not delete this port
* but we should add a new timer
*/
igmp_snoop_pkt_new_msg = (struct igmp_snoop_pkt_msg *)kmalloc(sizeof (struct igmp_snoop_pkt_msg) , IGMP_SNOOPING_MOD_ID);
if(NULL == igmp_snoop_pkt_new_msg)
return NULL;
bzero ((char *)igmp_snoop_pkt_new_msg, sizeof (struct igmp_snoop_pkt_msg));
if(igmp_snoop_pkt_new_msg == NULL)
{
syslog(LOG_INFO,"No free momory for
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -