⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stp.c

📁 stp source code used in switch
💻 C
📖 第 1 页 / 共 2 页
字号:
/* stp - spanning tree protocol  * * */#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/if_ether.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/spinlock.h>#include <asm/unaligned.h>#include <linux/netfilter.h>#include <ttype.h>#include <switch.h>#include "ieee802_1d.h"#include "stp.h"#include "wrpmac.h"#include "wrpport.h"#include "wrpstp.h"#include "wrpsys.h"#include "wrptype.h"#include "../mx/via.h"#include "../mx/mx.h"#undef  STP_DEBUG#define STP_PORT_MAX 27extern void (*gvrp_stp_port_forwarding)(int );extern void (*gvrp_stp_port_disabled)(int );extern void (*gmrp_stp_port_forwarding)(int );extern void (*gmrp_stp_port_disabled)(int );extern void (*igmp_stp_port_forwarding)(int );extern void (*igmp_stp_port_disabled)(int );extern int num_tcn;extern unsigned long last_tcn;extern struct nf_sockopt_ops stp_sockopts; struct stp_t stp_info;unsigned char bridge_mac[6];unsigned long ulSpanTreeTickScaling;unsigned long ulMaxNoPorts = 0; /* port threads will increase this */static int periodical_thread_pid;static int port_thread_pid;static int stp_tick_enable;static int restart;//SNMP Bridge MIBint forward_transition[STP_PORT_MAX];static void sleep(unsigned howlong) {  if(in_interrupt())   {    return;   }  current->state = TASK_INTERRUPTIBLE;  schedule_timeout(howlong); }/* this thread will use portdrv to find out any port changes  * and report them to the ieee 802.1d code. */static spinlock_t stp_ieee_sem;static int stp_port_thread(void * vp) {  int i;  int enabled;  Cost c;   UINT8 byAutoAbl, byPortAbl;  BOOL bPortEbl;  BOOL status[STP_PORT_MAX];  UINT8 autoabl[STP_PORT_MAX],portabl[STP_PORT_MAX];  for(i=0;i<STP_PORT_MAX;i++)   {    K_PortGetLink(i, (PBOOL) &(status[i]));    /* // 2007-3-22 Steve changed, need it for module ports?    if(i>=24)     status[i]=BIObIsRegSpecBitOn(PHY_LINK_STATUS, i);         HIbPORTCTL_GetPortAbl((UINT8) i, &(autoabl[i]), &(portabl[i]));    */    portabl[i] = SWPORT_byGetSpdDpx(i);    K_PortGetNego(i, &(autoabl[i]));          enabled = 0;    c=0;//    printk("STP : Port %d PortEbl=%d\n",i+1,status[i]);     {       if (status[i] == FALSE)        {#ifdef STP_DEBUG printk("STP : Port %d disable\n",i);#endif enabled = 0;       }      else if ((portabl[i]== PORTCTL_10M_HALF) || (portabl[i]== PORTCTL_10M_FULL))        {#ifdef STP_DEBUG printk("STP : Port %d 10M\n",i);#endif c= 100; /* (8.8.6) Table 8.5 */        enabled= 1;       }      else if ((portabl[i]== PORTCTL_100M_HALF) || (portabl[i]== PORTCTL_100M_FULL))        {#ifdef STP_DEBUG printk("STP : Port %d 100M\n",i);#endif//many product set to 10// c= 19;  /* (8.8.6) Table 8.5 */ c= 10;  /* (8.8.6) Table 8.5 */        enabled= 1;       }      else if ((portabl[i]== PORTCTL_1000M_HALF) || (portabl[i]== PORTCTL_1000M_FULL))        {#ifdef STP_DEBUG printk("STP : Port %d 1000M\n",i);#endif c= 4;   /* (8.8.6) Table 8.5 */        enabled= 1;       }      else       {           /* warn and disable if bad bitfields */ #ifdef STP_DEBUG        printk("STP:Error Value %d\n", portabl[i]);#endif        enabled= 0;       }     }//    printk("STP : port = %d, enabled = %d, cost = %d\n", i+1, enabled, c);    spin_lock(&stp_ieee_sem); /* protect the ieee802.1d code */    if (enabled)      {//      printk("port %d is enabled cost=%d\n", i, c);      enable_port(i + 1);      set_path_cost(i + 1, c);     }    else      {//      printk("port %d is disabled\n", i);//      set_path_cost(i + 1, DEF_PATH_COST);      disable_port(i + 1);     }        spin_unlock(&stp_ieee_sem);   }  while(1)   {    if(!stp_tick_enable) {sleep(1000); continue;}  for(i=0;i<STP_PORT_MAX;i++)    {   	// 2007-3-22 SteveLin changed //  HIbPORTCTL_GetPortEbl((UINT8) i, &bPortEbl);		bPortEbl = SWPORT_bGetPortEn(i);        /* // 2007-3-22 SteveLin commented, still need for module?      if (i >= 24)    	bPortEbl=BIObIsRegSpecBitOn(PHY_LINK_STATUS, i);         */    	    // 2007-3-22 SteveLin changed    	    // HIbPORTCTL_GetPortAbl((UINT8) i, &byAutoAbl, &byPortAbl);    byPortAbl = SWPORT_byGetSpdDpx(i);    K_PortGetNego(i, &byAutoAbl); #ifdef STP_DEBUG//    printk("STP : Port %d PortEbl=%d\n",i+1,bPortEbl);#endif    if(!restart && (status[i] == bPortEbl)                 && (byAutoAbl == autoabl[i])                 && (byPortAbl == portabl[i])      )     {      sleep(10);      continue;     }    if(restart) restart--;    status[i]=bPortEbl;    autoabl[i]=byAutoAbl;    portabl[i]=byPortAbl;    enabled = 0;    c=0;     {       if (bPortEbl == FALSE)        {#ifdef STP_DEBUG printk("STP : Port %d disable\n",i);#endif enabled = 0;       }      else if ((byPortAbl== PORTCTL_10M_HALF) || (byPortAbl== PORTCTL_10M_FULL))        {#ifdef STP_DEBUG printk("STP : Port %d 10M\n",i);#endif c= 100; /* (8.8.6) Table 8.5 */        enabled= 1;       }      else if ((byPortAbl== PORTCTL_100M_HALF) || (byPortAbl== PORTCTL_100M_FULL))        {#ifdef STP_DEBUG printk("STP : Port %d 100M\n",i);#endif //many product set to 10// c= 19;  /* (8.8.6) Table 8.5 */ c= 10;  /* (8.8.6) Table 8.5 */        enabled= 1;       }      else if ((byPortAbl== PORTCTL_1000M_HALF) || (byPortAbl== PORTCTL_1000M_FULL))        {#ifdef STP_DEBUG printk("STP : Port %d 1000M\n",i);#endif c= 4;   /* (8.8.6) Table 8.5 */        enabled= 1;       }      else       {           /* warn and disable if bad bitfields */ #ifdef STP_DEBUG        printk("STP:Error Value %d\n", byPortAbl);#endif        enabled= 0;       }     }//    printk("STP : port = %d, enabled = %d, cost = %d\n", i+1, enabled, c);    spin_lock(&stp_ieee_sem); /* protect the ieee802.1d code */    if (enabled)      {//      printk("port %d is enabled cost=%d\n", i, c);      enable_port(i + 1);      set_path_cost(i + 1, c);     }    else      {//      printk("port %d is disabled\n", i);      disable_port(i + 1);     }        spin_unlock(&stp_ieee_sem);   }   }  return 0; }/*  periodically run */static int stp_periodical_thread(void * vp) {  while(1)    {    if(!stp_tick_enable) {sleep(1000); continue;}//    printk("STP: Tick\n");    spin_lock(&stp_ieee_sem); /* protect the ieee802.1d code */    STP_tick();//    printk("STP: Tick3\n");    spin_unlock(&stp_ieee_sem);//    printk("STP: Tick4\n");//    sleep(10);//    sleep(23);    sleep(25);   }  return 0;}/* The CallBack function. * This function will get bpdu packets from * the VT6526 and report them to the ieee 802.1d code. *//****************************************************************/static int stp(struct sk_buff *skb) {#ifdef STP_DEBUG  printk("STP: program receives a packet!! %d %d %d %d %d %d\n",VIA_P(skb)->wSize,VIA_P(skb)->wVid,VIA_P(skb)->byPriority,VIA_P(skb)->bySrcPortId,VIA_P(skb)->byFwdReason,VIA_P(skb)->bIfTagged);#endif  /* Process the  BPDU packet */  {   Config_bpdu receivedConfigBpdu;   Tcn_bpdu receivedTcnBpdu;   Bpdu_type bpduMessageType;   Protocol_version protocolVersion;   int port_no;   unsigned int uiProtocolIdentifier;   unsigned char * pucEthernet;   pucEthernet = (unsigned char *)skb->mac.raw;//     printk("len=%d\n",(ntohs(*((unsigned short*)(pucEthernet+12)))) );//   if (VIA_P(skb)->wSize >= 17)   if ((ntohs(*((unsigned short*)(pucEthernet+12)))) >= 17)    {     unsigned char * pucBPDU;     pucEthernet = (unsigned char *)skb->mac.raw;     if(VIA_P(skb)->bIfTagged)      pucBPDU = &pucEthernet[17 + 4 /* ignore the silly VLAN tag */];     else      pucBPDU = &pucEthernet[17];     /* Find BPDU Protocol Identifier.      * First and second byte in configuration message. */       uiProtocolIdentifier = ((unsigned int)pucBPDU[0] << 8) + (unsigned int)pucBPDU[1];      /* Find BPDU Protocol Version.       * Third byte in configuration message. */       protocolVersion = pucBPDU[2];     /* Find BPDU message type.       * Fourth byte in configuration message. */     bpduMessageType = pucBPDU[3];#ifdef DUMP_RECEIVED_BPDU   /* test */   {     int i;     for (i = 0;i < 32;i++) {            if ((i % 16) == 0) {  fprintf(stderr, "\n%02x ",pucEthernet[i]);       }       else {  fprintf(stderr, "%02x ",pucEthernet[i]);       }     }     fprintf(stderr, "\n");   }#endif     if (uiProtocolIdentifier == 0)       {       switch (bpduMessageType)         {         case Config_bpdu_type:#ifdef STP_DEBUG  printk("STP: program receives a BPDU packet!! size:%d vid:%d priority:%d portid:%d reason:%d iftag:%d\n",VIA_P(skb)->wSize,VIA_P(skb)->wVid,VIA_P(skb)->byPriority,VIA_P(skb)->bySrcPortId,VIA_P(skb)->byFwdReason,VIA_P(skb)->bIfTagged);#endif       /* Check BPDU - is it a sane packet ? */       {//        if (!(VIA_P(skb)->wSize >= CONFIG_BPDU_MESSAGE_BYTES)) //by flash, pass ANVL test case 8.2//     printk("len=%d bIfTagged=%d\n",(ntohs(*((unsigned short*)(pucEthernet+12)))),VIA_P(skb)->bIfTagged );     if(VIA_P(skb)->bIfTagged)     {      if ((ntohs(*((unsigned short*)(pucEthernet+12)))) <= 34+3+4)       {        break;       }     }     else     {      if ((ntohs(*((unsigned short*)(pucEthernet+12)))) <= 34+3)       {//        printk("too short \n");        break;       }     }    /* check for invalid flag */        if ( (unsigned long)pucBPDU[4] & 0x7E)          {#ifdef STP_DEBUG      printk("STP Discard Packet! BPDU Flag invalid\n");#endif          break;         }          }       /* Copying data from message bytes to         * config structure in 802.1D code */       {        int i = 4; /* start of Flags */               receivedConfigBpdu.topology_change_acknowledgment = (unsigned long)pucBPDU[i] & 0x80;               receivedConfigBpdu.topology_change = (unsigned long)pucBPDU[i++] & 0x01;                              receivedConfigBpdu.root_id.four_octets[0]  = (unsigned long)pucBPDU[i++] << 24;               receivedConfigBpdu.root_id.four_octets[0] |= (unsigned long)pucBPDU[i++] << 16;               receivedConfigBpdu.root_id.four_octets[0] |= (unsigned long)pucBPDU[i++] << 8;               receivedConfigBpdu.root_id.four_octets[0] |= (unsigned long)pucBPDU[i++] << 0;                              receivedConfigBpdu.root_id.four_octets[1]  = (unsigned long)pucBPDU[i++] << 24;               receivedConfigBpdu.root_id.four_octets[1] |= (unsigned long)pucBPDU[i++] << 16;               receivedConfigBpdu.root_id.four_octets[1] |= (unsigned long)pucBPDU[i++] << 8;               receivedConfigBpdu.root_id.four_octets[1] |= (unsigned long)pucBPDU[i++] << 0;                              receivedConfigBpdu.root_path_cost  = (unsigned long)pucBPDU[i++] << 24;               receivedConfigBpdu.root_path_cost |= (unsigned long)pucBPDU[i++] << 16;               receivedConfigBpdu.root_path_cost |= (unsigned long)pucBPDU[i++] << 8;               receivedConfigBpdu.root_path_cost |= (unsigned long)pucBPDU[i++] << 0;                              receivedConfigBpdu.bridge_id.four_octets[0]  = (unsigned long)pucBPDU[i++] << 24;               receivedConfigBpdu.bridge_id.four_octets[0] |= (unsigned long)pucBPDU[i++] << 16;               receivedConfigBpdu.bridge_id.four_octets[0] |= (unsigned long)pucBPDU[i++] << 8;               receivedConfigBpdu.bridge_id.four_octets[0] |= (unsigned long)pucBPDU[i++] << 0;                              receivedConfigBpdu.bridge_id.four_octets[1]  = (unsigned long)pucBPDU[i++] << 24;               receivedConfigBpdu.bridge_id.four_octets[1] |= (unsigned long)pucBPDU[i++] << 16;               receivedConfigBpdu.bridge_id.four_octets[1] |= (unsigned long)pucBPDU[i++] << 8;               receivedConfigBpdu.bridge_id.four_octets[1] |= (unsigned long)pucBPDU[i++] << 0;                              receivedConfigBpdu.port_id  = (unsigned short)((unsigned short)pucBPDU[i++] << 8);               receivedConfigBpdu.port_id |= (unsigned short)pucBPDU[i++] << 0;                              receivedConfigBpdu.message_age  = (unsigned short)((unsigned short)pucBPDU[i++] << 8);               receivedConfigBpdu.message_age |= (unsigned short)pucBPDU[i++] << 0;                              receivedConfigBpdu.max_age  = (unsigned short)((unsigned short)pucBPDU[i++] << 8);               receivedConfigBpdu.max_age |= (unsigned short)pucBPDU[i++] << 0;                              receivedConfigBpdu.hello_time  = (unsigned short)((unsigned short)pucBPDU[i++] << 8);               receivedConfigBpdu.hello_time |= (unsigned short)pucBPDU[i++] << 0;                              receivedConfigBpdu.forward_delay  = (unsigned short)((unsigned short)pucBPDU[i++] << 8);               receivedConfigBpdu.forward_delay |= (unsigned short)pucBPDU[i++] << 0;                              (void)i;       }        /* Set BPDU message type  */       receivedConfigBpdu.type = bpduMessageType;                         /* Copy the topology change bits in the messages        * 5:th byte to the right fields in the structure */           receivedConfigBpdu.topology_change_acknowledgment = (pucBPDU[4] & 0x80) ? 1 : 0 ;       receivedConfigBpdu.topology_change = (pucBPDU[4] & 0x1) ? 1 : 0 ;          if(receivedConfigBpdu.topology_change)        {         num_tcn++;         last_tcn=jiffies;	 K_MacClrTbl(MAC_CLR_DYNMC);        }       /* Convert VIA port numbering (from 0)         * to port_no numbering from 1 */          port_no = VIA_P(skb)->bySrcPortId + 1; //VIA driver start at 0 but IEEE codes start at 1       /* Call code supplied in 802.1D */       if (receivedConfigBpdu.message_age < receivedConfigBpdu.max_age)        {  spin_lock(&stp_ieee_sem); /* protect the ieee802.1d code *///printk("received_config_bpdu\n");  received_config_bpdu(port_no, &receivedConfigBpdu);  spin_unlock(&stp_ieee_sem);        }       break;     case Tcn_bpdu_type:#ifdef STP_DEBUG  printk("STP: program receives a TCN packet!! size:%d vid:%d priority:%d portid:%d reason:%d iftag:%d\n",VIA_P(skb)->wSize,VIA_P(skb)->wVid,VIA_P(skb)->byPriority,VIA_P(skb)->bySrcPortId,VIA_P(skb)->byFwdReason,VIA_P(skb)->bIfTagged);#endif       num_tcn++;       last_tcn=jiffies;// not need, by flash//       K_MacClrTbl(MAC_CLR_DYNMC);       /* Check BPDU */       {               if (!(VIA_P(skb)->wSize >= 4))                 {                 break;                }       }              /* Fill in Tcn_bpdu from message */              receivedTcnBpdu.type = bpduMessageType;       //VIA driver start at 0 but IEEE codes start at 1       port_no = VIA_P(skb)->bySrcPortId + 1;        /* Call code supplied in 802.1D */       spin_lock(&stp_ieee_sem); /* protect the ieee802.1d code */       received_tcn_bpdu( port_no, &receivedTcnBpdu);       spin_unlock(&stp_ieee_sem);       break;            default:#ifdef STP_DEBUG          printk("- Ignored bpduMessageType 0x%02x.\n",     (unsigned int) bpduMessageType);#endif       break;     } /* switch */   } /* if */        } /* if */          }  return MX_DROP; }void SendConfigBpdu(Int port_no, Config_bpdu *bpdu) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -