linux 网桥代码分析 一 网桥概念与网桥相关的数据结构

1. 网桥概念

 

中继器:只是简单的把一个端口所接收的数据复制到另一个端口,且是按位复制的。多端口的集线器叫做hub

网桥:网桥了解链路层协议,是按帧复制数据,而非按位复制。网桥还具有地址学习的功能,并不是简单的把数据从一个端口转发到其他端口,其会根据学习到的mac地址来决定是否进行转发,如何转发。

 

2. Linux网桥模型

 

对于linux而言,网桥是虚拟设备。因此,需要将真实的设备绑定到网桥上,网桥才能正常工作。网桥设备的数据传输与接收模型如下:


如上图,对于数据传输:

当上层协议将需要传输的数据发送到网桥设备br0后,br0就会查询转发数据库(FDB),来决定是将数据广播给出去,还是从某个eth口转发出去

对于数据接收:

从eth0或从eth1接收到的报文被提交给网桥的处理代码,在这里会判断报文该转发、丢弃、或提交到协议栈上层

 

 

3、数据结构

下面是bridge代码中比较主要的数据结构,主要包括网桥、网桥端口、转发数据表项

网桥相关的数据结构有

 

Mac地址的数据结构

struct mac_addr

{

unsigned char addr[6];

};

 

转发数据表项

struct net_bridge_fdb_entry

{

struct hlist_node hlist;/*将该表项链接到hash表头的指针,关于hash表结构请看上一篇文档 linux hash表的介绍*/

struct net_bridge_port *dst;/*指向目的网桥端口*/

 

struct rcu_head rcu;/*rcu机制使用*/

unsigned long ageing_timer;/*aging定时器*/

mac_addr addr;/*mac地址*/

unsigned char is_local;/*是否是本地mac地址*/

unsigned char is_static;/*mac地址是否为静态的标志*/

};

 

桥端口

struct net_bridge_port

{

struct net_bridge *br; /*指向该网桥端口所绑定的网桥*/

struct net_device *dev;/*指向该网桥端口所绑定的网络设备*/

struct list_head list;/*用于将该网桥端口链接到网桥的port_list链表的指针*/

 

/* STP */

u8 priority;/*端口优先级*/

u8 state;/*端口状态,在对数据进行转发时会对该state值进行判断*/

u16 port_no;/*端口号*/

unsigned char topology_change_ack;

unsigned char config_pending;

port_id port_id;/*端口ID*/

port_id designated_port;

bridge_id designated_root;

bridge_id designated_bridge;

u32 path_cost;/*端口路径开销*/

u32 designated_cost;

unsigned long designated_age;

/*网桥端口定时器*/

struct timer_list forward_delay_timer;

struct timer_list hold_timer;

struct timer_list message_age_timer;

struct kobject kobj;

 

 

struct rcu_head rcu;

 

unsigned long  flags;

#define BR_HAIRPIN_MODE 0x00000001

};

 

net_bridge

struct net_bridge

{

spinlock_t lock; //自旋锁,在向net_bridge中增加port节点或改变net_bridge结构时使用

struct list_head port_list;//网桥端口列表

struct net_device *dev;//网桥设备

spinlock_t hash_lock;//对hash转发库进行操作时需要使用该自旋锁

struct hlist_head hash[BR_HASH_SIZE];//转发数据库hash表,关于hash表的数据结构的介绍,请看上一篇linux hlist介绍

struct list_head age_list;

unsigned long feature_mask;

#ifdef CONFIG_BRIDGE_NETFILTER

struct rtable  fake_rtable;

#endif

unsigned long flags;

#define BR_SET_MAC_ADDR 0x00000001

 

/* STP */

bridge_id designated_root;

bridge_id bridge_id;

u32 root_path_cost;

/*网桥定时器*/

unsigned long max_age;

unsigned long hello_time;

unsigned long forward_delay;

 

/*本地配置的网桥定时器*/

unsigned long bridge_max_age;

unsigned long bridge_hello_time;

unsigned long bridge_forward_delay;

 

/*转发数据表项未被使用时可以待在转发数据库里的最大时间*/

unsigned long ageing_time;

 

u8 group_addr[ETH_ALEN];

u16 root_port; //根端口的端口号

 

enum {

BR_NO_STP,  /* no spanning tree */

BR_KERNEL_STP, /* old STP in kernel */

BR_USER_STP, /* new RSTP in userspace */

} stp_enabled;

 

unsigned char topology_change;

unsigned char topology_change_detected;

/*网桥定时器*/

struct timer_list hello_timer;

struct timer_list tcn_timer;

struct timer_list topology_change_timer;

struct timer_list gc_timer;

 

 

struct kobject *ifobj;

};

 

 

这些数据结构的关联如下图(该图取自深入理解linu网络一书):



  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值