📄 igmp_snoop.c
字号:
/*#include <net/ip.h>*/
#include "vxworks.h"
#include "igmp_snoop.h"
#include <linux/ip.h>
#include "msgQLib.h"
#include "semLib.h"
#include <hos_time.h>
#include <route/thread.h>
#include <cli.h>
#include "Mod_flag.h"
#include <syslog.h>
#ifdef _FLEX_HAMMER_
#include "../vlan/vlan_aux.h"
#include "../switch/br_fdb.h"
#include "../../product/flex_hammer/Driver/Galileo/Gt_txrx.h"
#include "../../include/linux/if_vlan.h"
#endif
#ifdef _U_24_IGMPSNOOPING_
#include <linux/if_vlan.h>
/*#include "../../Driver/Galileo/galnetConfig.h" */
#include "M_vlan.h"
/*because the definition of vlanhdr is off when _KERNEL is off in the file if_vlan.h*/
#ifndef __KERNEL__
struct vlanhdr
{
unsigned char v_dest[ETH_ALEN];
unsigned char v_source[ETH_ALEN];
unsigned short v_prio;
unsigned short v_vid;
unsigned short v_proto;
};
#endif
#endif
#ifndef NULL
#define NULL 0
#endif
#define DEBUG
extern struct st_timer * generic_head_timer;
int igmp_ignore_leave_report = 0;
int igmp_snoop_tid = 0;
/*struct igmp_snoop_router_entry *igmp_snoop_router_list = (struct igmp_snoop_router_entry *)NULL;*/
struct igmp_snoop_router_entry *igmp_snoop_router_list = NULL;
/*struct igmp_snoop_mac_group *igmp_snoop_mac_list = (struct igmp_snoop_mac_group *)NULL;*/
struct igmp_snoop_mac_group *igmp_snoop_mac_list = NULL;
/*the main routine*/
struct thread_master *igmp_snoop_master;
SEM_ID semIgmpSnoopSyncCLI;
MSG_Q_ID IgmpSnoopMsgQId;
unsigned int IgmpSnoopMsgNum ;
long ROUTER_V1_TIME_OUT_TIMER ;
long GROUP_MEMEBER_SHIP_INTERVAL ;
long GROUP_V1_MEMEBER_SHIP_INTERVAL ;
int host_time_milli_flag;
int router_time_milli_flag;
long ROUTER_TIME_OUT_TIMER ;
long ROUTER_GENERAL_QUERY_INTERVAL ;
#ifdef _U_24_IGMPSNOOPING_
/*should be deleted after the real function is worked out*/
typedef struct igmp_list {
unsigned long timer_id;
char type;
long timeout;
long timenow;
MSG_Q_ID queue_id;
char *parg;
struct igmp_list *next,*prev;
} igmp_list_t;
#define log2phy_port_igmp(i) log_phy_tbl_igmp[i]
#define phy2log_port_igmp(i) log_phy_tbl_igmp[i]
/* local variables */
const u_int16 log_phy_tbl_igmp[27] = { 0, /* cpu */
1, 2, 3, 4, 5, 6, /* unchanged */
13, 14, 15, 16, 17, 18, /* change */
7, 8, 9, 10, 11, 12, /* changed */
19, 20, 21, 22, 23, 24, /* unchanged */
25, 26};
static igmp_list_t *plis_global;
static unsigned long timer_id_igmp_global;
SEM_ID sem_igmp_list;
int igmp_snoop_timer_tid = 0;
void timer_igmp();
int igmp_timer_list_init();
igmp_list_t* malloc_igmp_list_node();
void free_igmp_list_node(igmp_list_t *plis_tmp);
/*
u24_driver_add_igmp_snooping_port(int VID, mac_addr macaddr, short port_no)
{
addr_entry_t msg;
driver_SearchAddrEntry((mac_addr_t*)macaddr,VID,&msg);
}
u24_driver_delete_igmp_snooping_entry(int VID, mac_addr macaddr)
{
}
u24_driver_delete_igmp_snooping_port(int VID, mac_addr macaddr, short port_no)
{
}
*/
long hos_deltimer(unsigned long timerid)
{
igmp_list_t* plis_tmp;
plis_tmp = plis_global;
while(plis_tmp->timer_id != timerid && plis_tmp != NULL)
plis_tmp = plis_tmp->next;
if(plis_tmp->timer_id == timerid)
{
free_igmp_list_node(plis_tmp);
return OK;
}
return ERROR;
}
long hos_timerout_every_byqueue(unsigned long que_id,long millsec,long larg, char * parg)
{
igmp_list_t* plis_tmp;
if(0 >= millsec/1000)
return ERROR;
semTake(sem_igmp_list,WAIT_FOREVER);
plis_tmp = (igmp_list_t*)malloc_igmp_list_node();
if(NULL == plis_tmp)
return ERROR;
plis_tmp->type = 1;
plis_tmp->queue_id = (MSG_Q_ID)que_id;
plis_tmp->timeout = plis_tmp->timenow = millsec/1000;
plis_tmp->parg = parg;
semGive(sem_igmp_list);
return plis_tmp->timer_id;
}
int igmp_timer_list_init()
{
plis_global = NULL;
timer_id_igmp_global = 1;
if( (sem_igmp_list = semBCreate (SEM_Q_FIFO,SEM_FULL)) == NULL)
{
return ERROR;
}
semTake(sem_igmp_list,WAIT_FOREVER);
semGive(sem_igmp_list);
if((igmp_snoop_timer_tid = taskSpawn ("igmptimer", 4, 0, 2000, (FUNCPTR)timer_igmp, 0,0,0,0,0,0,0,0,0,0) )== ERROR)
return ERROR;
return OK;
}
igmp_list_t* malloc_igmp_list_node()
{
igmp_list_t* plis_tmp;
plis_tmp = (struct igmp_list*) malloc(sizeof(igmp_list_t));
if(NULL == plis_tmp)
return NULL;
bzero((char*)plis_tmp,sizeof(igmp_list_t));
plis_tmp->timer_id = timer_id_igmp_global++;
plis_tmp->next = plis_global;
/*
if(plis_global != NULL)
plis_global->prev = plis_tmp;
*/
plis_global = plis_tmp;
return plis_tmp;
}
void free_igmp_list_node(igmp_list_t *plis_tmp)
{
igmp_list_t *p;
igmp_list_t *q;
if(plis_tmp == NULL)
return;
semTake(sem_igmp_list,WAIT_FOREVER);
p = plis_global;
if (NULL == p)
{
syslog(LOG_INFO, "there is no timer to delete");
semGive(sem_igmp_list);
return;
}
if (p ->timer_id == plis_tmp->timer_id)
{
plis_global = p->next;
free(p);
p = NULL;
semGive(sem_igmp_list);
return;
}
while(p->next)
{
q = p->next;
if(q->timer_id == plis_tmp->timer_id)
{
p->next = q->next;
free(q);
q = NULL;
semGive(sem_igmp_list);
return;
}
p = p->next;
}
/* if(plis_tmp->prev != NULL)
plis_tmp->prev->next = plis_tmp->next;
if(plis_tmp->next != NULL)
plis_tmp->next->prev = plis_tmp->prev;
if(plis_tmp == plis_global)
plis_global = plis_tmp->next;
semGive(sem_igmp_list);
*/
/* free(plis_tmp);*/
semGive(sem_igmp_list);
return;
}
void timer_igmp()
{
igmp_list_t *pil_tmp,*pil_tmp2;
TIMERMSG_S * msg;
int rnet;
while(1)
{
pil_tmp = plis_global;
while(pil_tmp != NULL)
{
pil_tmp->timenow --;
if(0 >= pil_tmp->timenow)
{
msg = (TIMERMSG_S *)kmalloc(sizeof(TIMERMSG_S) , IGMP_SNOOPING_MOD_ID);
if(NULL == msg)
return;
bzero ((char *)msg, sizeof (TIMERMSG_S));
msg->source_id = TASK_TIMER_NOTIFY;
msg->timer_id = 0; /*should choose an impossible value temporarily 0*/
msg->func = 0;
msg->parg = (char *)pil_tmp->parg;
rnet = (int)msgQSend(pil_tmp->queue_id, (char *)msg, sizeof(TIMERMSG_S), NO_WAIT, MSG_PRI_NORMAL);
kfree(msg);
msg = NULL;
if (rnet !=0 )
{
/* kfree(pil_tmp->parg);*/
pil_tmp->timenow = pil_tmp->timeout;
syslog(LOG_INFO, "return error");
}
/*msgQSend(pil_tmp->queue_id, (char *)pil_tmp->parg, sizeof(TIMERMSG_S), NO_WAIT, MSG_PRI_NORMAL);*/
if(1 == pil_tmp->type)
{
pil_tmp->timenow = pil_tmp->timeout;
}
}
/*the pil_tmp->timenow of type 1 has been changed to the timeout*/
if(0 >= pil_tmp->timenow)
{
pil_tmp2 = pil_tmp;
pil_tmp = pil_tmp->next;
free_igmp_list_node(pil_tmp2);
}
else
pil_tmp = pil_tmp->next;
}
taskDelay(120);
}
return;
}
long hos_timerout_byqueue(unsigned long que_id,long millsec,long larg, char * parg)
{
igmp_list_t* plis_tmp;
if(0 >= millsec/1000)
return ERROR;
semTake(sem_igmp_list,WAIT_FOREVER);
plis_tmp = malloc_igmp_list_node();
if(NULL == plis_tmp)
return ERROR;
plis_tmp->type = 0;
plis_tmp->queue_id = (MSG_Q_ID)que_id;
plis_tmp->timeout = plis_tmp->timenow = millsec/1000;
plis_tmp->parg = parg;
semGive(sem_igmp_list);
return plis_tmp->timer_id;
}
#endif
/*struct igmphdr *IgmpSnoopPkt;*/
/*
int igmp_snoop_start()
{
semIgmpSnoopSyncCLI = semBCreate (SEM_Q_FIFO, SEM_EMPTY);
if ((IgmpSnoopMsgQId = msgQCreate (IGMP_SNOOP_MAX_MSGS, sizeof(TIMERMSG_S *), MSG_Q_FIFO))== NULL)
{
syslog(LOG_INFO,"Create the message queue failure\n\r");
return ;
}
}
*/
/***************************************************************************************************
* Func: igmp_snoop_instance_start
*This function is the entry of the igmp snooping task.
****************************************************************************************************/
void igmp_snoop_instance_start()
{
if (igmp_snoop_tid !=0 )
return;
if ((IgmpSnoopMsgQId = msgQCreate (IGMP_SNOOP_MAX_MSGS, sizeof(TIMERMSG_S), MSG_Q_FIFO))== NULL)
{
syslog(LOG_INFO,"Create the message queue failure\n\r");
return ;
}
#ifdef _FLEX_HAMMER_
driver_igmpenable();
#endif
#ifdef _U_24_IGMPSNOOPING_
u24_driver_igmpenable();
#endif
igmp_snoop_tid = taskSpawn ("tIgmpSnoop", 80, 0, 0x4096,
(FUNCPTR)igmp_snoop_main, 0,0,0,0,0,0,0,0,0,0);
#ifdef _U_24_IGMPSNOOPING_
igmp_timer_list_init();
#endif
/*return (ERROR);*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -