免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: 独孤九贱
打印 上一主题 下一主题

Linux网桥源码框架分析初步 [复制链接]

论坛徽章:
0
21 [报告]
发表于 2006-01-13 10:09 |只看该作者

论坛徽章:
0
22 [报告]
发表于 2006-01-13 10:19 |只看该作者
原帖由 zhangjiakouzf 于 2006-1-13 10:05 发表
俺贴两个网址,也许对楼主又帮助,我在看桥代码时用过的
http://www.ee.unimelb.edu.au/sta ... ck_walkthrough.html
http://www.ecsl.cs.sunysb.edu/elibrary/linux/netwo ...


谢谢大家!!
前面忘了贴桥的数据结构的分析了,补上来:
数据结构:

对Linux上所有接口进行网桥划分,可以把一组端口划分到一个网桥之中,同时一个系统上
允许有多个网桥。内核描述一个网桥,使用了struct net_bridge结构:

struct net_bridge
{
        struct net_bridge                *next;                        //下一个网桥
        rwlock_t                        lock;                        //读写锁
        struct net_bridge_port                *port_list;                //桥组中的端口列表
       
        /*网桥都会有一个虚拟设备用来进行管理,就是它了。说到这里,我想到了以前一个没有解决的问题:对网桥管理IP配置后,发现其虚拟的MAC地址是动态生成的,取的是桥组中某一个物理端口的MAC地址(好像是第一个网卡的MAC吧,记不清了),这样,如果远程管理时就有麻烦:如果你动态调整网桥中的端口,如删除某个网卡出去,用于管理的虚拟网卡的MAC地址就有可以改        变,导致不能远程管理,盼指点如何解决此问题呢?也许看完整个代码就会也答案……*/
        struct net_device                dev;                       
        struct net_device_stats                statistics;                //网桥虚拟网卡的统计数据
        rwlock_t                        hash_lock;                //hash表的读写锁,这个表就是用于存放桥的MAC-PORT对应表
        struct net_bridge_fdb_entry        *hash[BR_HASH_SIZE];        //就是这张表了,也叫CAM表
        struct timer_list                tick;

        /*以下定义了STP协议所使用的信息,参见STP协议的相关定义,我的小站上
        [url]http://www.skynet.org.cn/viewthread.php?tid=90&fpage=1
也有对协议的相关分析 */
        bridge_id                        designated_root;
        int                                root_path_cost;
        int                                root_port;
        int                                max_age;
        int                                hello_time;
        int                                forward_delay;
        bridge_id                        bridge_id;
        int                                bridge_max_age;
        int                                bridge_hello_time;
        int                                bridge_forward_delay;
        unsigned                        stp_enabled:1;
        unsigned                        topology_change:1;
        unsigned                        topology_change_detected:1;

        struct br_timer                        hello_timer;
        struct br_timer                        tcn_timer;
        struct br_timer                        topology_change_timer;
        struct br_timer                        gc_timer;

        int                                ageing_time;
        int                                gc_interval;
};

可以看出,桥中有几个重要的地方:
1、桥的端口成员:struct net_bridge_port                *port_list;
2、桥的CAM表:struct net_bridge_fdb_entry        *hash[BR_HASH_SIZE];
3、桥的虚拟网卡
4、STP

桥的虚拟网卡是一个struct net_device设备,它在2.4中是如此庞大,要对它在这里进行分析无疑是非常困难的,改天大家一起讨论吧。
STP的相关成员的定义与STP包的结构是紧密相关的,看了其包结构,可以分析出这些成员了,不再一一列举了。

网桥中的端口,用struct net_bridge结构表示,它实际上表示的是接收该数据包的网桥的端口的相关信息:
struct net_bridge_port
{
        struct net_bridge_port                *next;                //网桥端口组中的下一个端口
        struct net_bridge                *br;                //当前端口(接收数据包这个)所在的桥组
        struct net_device                *dev;                //本端口所指向的物理网卡
        int                                port_no;        //本端口在网桥中的编号


        port_id                                port_id;       
        int                                state;
        int                                path_cost;
        bridge_id                        designated_root;
        int                                designated_cost;
        bridge_id                        designated_bridge;
        port_id                                designated_port;
        unsigned                        topology_change_ack:1;
        unsigned                        config_pending:1;
        int                                priority;

        struct br_timer                        forward_delay_timer;
        struct br_timer                        hold_timer;
        struct br_timer                        message_age_timer;
};
这个结构对应了内核缓存中的skb->dev->br_port;

桥的CAM表是一个struct net_bridge_fdb_entry类型的数组,数组最大为:
#define BR_HASH_BITS 8
#define BR_HASH_SIZE (1 << BR_HASH_BITS)
256个项。
网桥根据目的地址来查表,以确定由哪个接口把包转发出去:
        struct net_bridge_fdb_entry
        {
                struct net_bridge_fdb_entry        *next_hash;                //用于CAM表连接的链表指针
                struct net_bridge_fdb_entry        **pprev_hash;                //为什么是pprev不是prev呢?还没有仔细去研究
                atomic_t                        use_count;                //此项当前的引用计数器
                mac_addr                        addr;                        //MAC地址
                struct net_bridge_port                *dst;                        //此项所对应的物理端口
                unsigned long                        ageing_timer;                //处理MAC超时
                unsigned                        is_local:1;                //是否是本机的MAC地址
                unsigned                        is_static:1;                //是否是静态MAC地址
        };

事实上,整个桥的处理,就是一个根据源地址学习(写表),根据目的地址确定发送端口(查表)的过程。当然,还有一个插曲,如处理发给本机的数据,需要交到上层,如果开启了STP,还要处理STP协议

[ 本帖最后由 独孤九贱 于 2006-1-13 10:23 编辑 ]

论坛徽章:
0
23 [报告]
发表于 2006-01-13 22:05 |只看该作者
顶,哥们,继续!

论坛徽章:
0
24 [报告]
发表于 2006-01-16 09:49 |只看该作者
呵呵,谢谢分享知识

论坛徽章:
0
25 [报告]
发表于 2006-01-16 10:33 |只看该作者
强人,不断向您学习~~~

论坛徽章:
0
26 [报告]
发表于 2006-01-16 11:06 |只看该作者
大侠,在STP的处理函数br_stp_handle_bpdu(struct sk_buff *skb)里的
        buf = skb->mac.raw + 14;
是什么意思啊,raw是指的什么东西呢

论坛徽章:
0
27 [报告]
发表于 2006-01-16 11:30 |只看该作者
原帖由 Pagliuca 于 2006-1-16 11:06 发表
大侠,在STP的处理函数br_stp_handle_bpdu(struct sk_buff *skb)里的
        buf = skb->mac.raw + 14;
是什么意思啊,raw是指的什么东西呢


原始的二层数据

这样skb->mac.raw + 14就表示跳过DLC包头:
如果是IEEE802的话,则就802.3包头,即:dst(6)+src(6)+len(2)=14;
如果是以太的话,则就是以太包头:dst(6)+src(6)+type(2)=14;

以STP协议的BPDU包来说,用的IEEE802封装,加14后,就指向了802.2LLC头部了,这样,用
buf[6]就可以指向BPDU的类型字段,前面五个分别是:
DSAP(1)+SSAP(1)+cntl(1)————802.2LLC部份三个字节
BPDU protocol ID(2)+BPDU version(1)——BPDU的开头部份,二个字节

tcp/ip详解卷一第二章第二页的最上边那幅图有很清楚的描述,记得是……

[ 本帖最后由 独孤九贱 于 2006-1-16 11:31 编辑 ]

论坛徽章:
0
28 [报告]
发表于 2006-01-16 16:28 |只看该作者
kfree_skb(skb);
是用来清空buf中的数据skb吗?

论坛徽章:
0
29 [报告]
发表于 2006-01-16 16:55 |只看该作者
原帖由 Pagliuca 于 2006-1-16 16:28 发表
kfree_skb(skb);
是用来清空buf中的数据skb吗?


建议你还是找专门分析Linux skb buffer的资料吧,我在这里一时半会说不清楚,或者等我把STP拿下来后,专门贴篇分析skb的贴子吧

论坛徽章:
0
30 [报告]
发表于 2006-01-16 19:27 |只看该作者
希望LZ先写好STP的文档.... 赞一个!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP