°æ±¾£ºLinux 2.4.18
Ò»¡¢µ÷ÓÃ
ÔÚsrc/net/core/dev.cµÄÈíÖжϺ¯Êýstatic void net_rx_action(struct softirq_action *h)ÖУº
ÒýÓÃ:line 1479
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
if (skb->dev->br_port != NULL &&
br_handle_frame_hook != NULL) {
handle_bridge(skb, pt_prev);
dev_put(rx_dev);
continue;
}
#endif
Èç¹û¶¨ÒåÁËÍøÇÅ»òÍøÇÅÄ£¿é£¬ÔòÓÉhandle_bridgeº¯Êý´¦Àískb->dev->br_port £º½ÓÊÕ¸ÃÊý¾Ý°üµÄ¶Ë¿ÚÊÇÍøÇŶ˿Ú×éµÄÒ»Ô±br_handle_frame_hook £º¶¨ÒåÁËÍøÇÅ´¦Àíº¯Êý¡£
¶þ¡¢³õʼ»¯
ÒýÓÃ:src/net/bridge/br.c£º
static int __init br_init(void)
{
printk(KERN_INFO "NET4: Ethernet Bridge 008 for NET4.0\n";
br_handle_frame_hook = br_handle_frame;
br_ioctl_hook = br_ioctl_deviceless_stub;
#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
br_fdb_get_hook = br_fdb_get;
br_fdb_put_hook = br_fdb_put;
#endif
register_netdevice_notifier(&br_device_notifier);
return 0;
}
³õʼ»¯º¯ÊýÖ¸Ã÷ÁËÍøÇŵĴ¦Àíº¯ÊýÊÇbr_handle_frameioctl´¦Àíº¯ÊýÊÇ£ºbr_ioctl_deviceless_stub¡£
Èý¡¢br_handle_frame(br_input.c)
ÍøÇÅ´¦Àíº¯Êý
ÒýÓÃ:void br_handle_frame(struct sk_buff *skb)
{
struct net_bridge *br;
unsigned char *dest;
struct net_bridge_port *p;
/*»ñÈ¡Ä¿µÄMACµØÖ·*/
dest = skb->mac.ethernet->h_dest;
/*skb->dev->br_portÓÃÓÚÖ¸¶¨½ÓÊÕ¸ÃÊý¾Ý°üµÄ¶Ë¿Ú£¬
Èô²»ÊÇÊôÓÚÍøÇŵĶ˿ڣ¬ÔòΪNULL*/
p = skb->dev->br_port;
if (p == NULL) /*¶Ë¿Ú²»ÊÇÍøÇÅ×é¶Ë¿ÚÖÐ*/
goto err_nolock;
/*±¾¶Ë¿ÚËùÊôµÄÍøÇÅ×é*/
br = p->br;
/*¼ÓËø£¬ÒòΪÔÚת·¢ÖÐÐèÒª¶ÁCAM±í£¬ËùÒÔ±ØÐë¼Ó¶ÁËø£¬
±ÜÃâÔÚÕâ¸ö¹ý³ÌÖÐÁíÍâµÄÄں˿ØÖÆ·¾¶(Èç¶à´¦Àí»úÉÏÁíÍâÒ»¸öCPUÉϵÄϵͳµ÷ÓÃ)ÐÞ¸ÄCAM±í*/
read_lock(&br->lock);
if (skb->dev->br_port == NULL) /*Ç°ÃæÅжϹýµÄ*/
goto err;
/*br->devÊÇÍøÇŵÄÐéÄâÍø¿¨£¬Èç¹ûËüδUP£¬
»òÍøÇÅDISABLED,p->stateʵ¼ÊÉÏÊÇÇŵĵ±Ç°¶Ë¿ÚµÄSTP¼ÆËãÅжϺóµÄ״̬*/
if (!(br->dev.flags & IFF_UP) ||
p->state == BR_STATE_DISABLED)
goto err;
/*Ô´MACµØַΪ255.X.X.X£¬¼´Ô´MACÊǶಥ»ò¹ã²¥£¬¶ªÆúÖ®*/
if (skb->mac.ethernet->h_source[0] & 1)
goto err;
Emperor ÓÚ 2006-11-29 09:58:19·¢±í:
»ù±¾¿ò¼Ü¾ÍÊÇÕâÑùÁË£¬ÓëÄÇЩ½²ÍøÇÅÔÀíµÄÊéÉϽ²µÄ»ù±¾²î²»¶à¡¡
ÍøÇÅÖ®ËùÒÔÊÇÍøÇÅ£¬Ö÷Òª¿¿ÕâÁ½¸öº¯Êý£º
Ò»¸öѧϰ£¬Ò»¸ö²é±í£»ÁíÍ⣬֧³ÖSTP£¬´¦ÀíBPDU£¬ÐèÒªÓõ½º¯Êýbr_stp_handle_bpdu.ÄÄλÓÐÕâÈý¸öº¯ÊýµÄϸ½Ú·ÖÎö£¬¿É·ñË;żúÒ»·Ý£¬ÃâµÃÏÂÎçÄÇôÐÁ¿àÔÙÈ¥¿Ð´úÂë¡¡
ɨÁËһϠbr_fdb_insert£¬½á¹¹»¹ÊǺÜÇåÎö£¬Èç¹ûµ±Ç°ÏîÒÑ´æÔÚÓÚhash±íÏîÖУ¬Ôò¸üÐÂËü£¨__fdb_possibly_replace£©£¬Èç¹ûÊÇÐÂÏÔò²åÈ룬ʵ¼ÊÊÇÒ»¸öË«ÏòÁ´±íµÄά»¤¹ý³Ì£¨__hash_link£©£º
ͬÑù£¬²é±íÒ²ÊÇÒ»¸ö±éÀúÁ´±í£¬½øÐеØÖ·Æ¥ÅäµÄ¹ý³Ì£º
Emperor ÓÚ 2006-11-29 09:57:32·¢±í:
ÖÚËùÖÜÖ®£¬ÍøÇÅÖ®ËùÒÔÊÇÍøÇÅ£¬±ÈHUB¸üÖÇÄÜ£¬ÊÇÒòΪËüÓÐÒ»¸öMAC-PORTµÄ±í£¬ÕâÑùת·¢Êý¾Ý¾Í²»Óù㲥£¬¶ø²é±í¶¨¶Ë¿Ú¾Í¿ÉÒÔÁË
ÿ´ÎÊÕµ½Ò»¸ö°ü£¬ÍøÇŶ¼»áѧϰÆäÀ´Ô´MAC£¬Ìí¼Ó½øÕâ¸ö±í¡£LinuxÖÐÕâ¸ö±í½ÐCAM±í(Õâ¸öÃû×ÖÊÇÆäËü×ÊÁÏÉÏ¿´µÄ)¡£Èç¹ûÇŵÄ״̬ÊÇLEARNING»òFORWARDING(ѧϰ»òת·¢)£¬Ôòѧϰ¸Ã°üµÄÔ´µØÖ·skb->mac.ethernet->h_source£¬½«ÆäÌí¼Óµ½CAM±íÖУ¬Èç¹ûÒѾ´æÔÚÓÚ±íÖÐÁË£¬Ôò¸üж¨Ê±Æ÷£¬br_fdb_insertÍê³ÉÁËÕâÒ»¹ý³Ì
STPÐÒéµÄBPDU°üµÄÄ¿µÄMAC²ÉÓõÄÊǶಥĿ±êMACµØÖ·£º´Ó01-80-c2-00-00-00£¨Bridge_group_addr£ºÍøÇÅ×é¶à²¥µØÖ·£©¿ªÊ¼.ËùÒÔÕâÀïÊÇÈç¹û¿ªÆôÁËSTP£¬¶øµ±Ç°Êý¾Ý°üÓÖÊÇÒ»¸öBPDU(!memcmp(dest, bridge_ula, 5)£¬ unsigned char bridge_ula[6] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }£¬Ôò½»ÓÉÏàÓ¦º¯Êý´¦Àí¡£if (br->stp_enabled &&£¬ÕâÀïÖ»±È½ÏÇ°5¸ö×Ö½Ú£¬Ã»ÓÐ×ÐϸÑо¿¹ýSTPÊÇʹÓÃÁËÈ«²¿¶à²¥µØÖ·£¨´Ó0 1 : 0 0 : 5 e : 0 0 : 0 0 : 0 0µ½0 1 : 0 0 : 5 e : 7 f : ff : ff¡££©£¬»¹ÊÇֻʹÓÃÁËÒ»²¿·Ý£¬ÕâÀï¿´À´ËƺõÖ»ÊÇÒ»²¿·Ý£¬Ã»È¥ÉÁË
ËÄ¡¢br_handle_frame_finish