Linux从用户层到内核层系列 – TCP/IP协议栈部分系列3: bridge(网桥)FDB表中MAC地址的更新

释放双眼,带上耳机,听听看~!

bridge(网桥)FDB表中MAC地址的更新

网桥工作在L2,对于网桥而言,最重要的就是网络拓扑中MAC地址的学习和基于MAC地址转发表(FDB- Forwarding database)对数据包的转发。

在br_handle_frame函数处理接到的数据包之后,网桥会根据接受的数据包的包头信息和接受数据包的接口进行FDB更新。对于已经存在的FDB表项,仅更新该表项的时间标记,对于不存在与FDB的表项,调用fdb_create来创建新的表项。

1.对于FDB的创建和更新过程如下图:

Linux从用户层到内核层系列 - TCP/IP协议栈部分系列3: bridge(网桥)FDB表中MAC地址的更新

2.Linux3.0.34
版本的
br_fdb_update
函数的源代码如下:

void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,

  const unsigned char *addr)
{

struct hlist_head *head = &br->hash[br_mac_hash(addr)];

struct net_bridge_fdb_entry *fdb;

/* some users want to always flood. */

if (hold_time(br) == 0)

return;

/* ignore packets unless we are using this port */

if (!(source->state == BR_STATE_LEARNING ||

     source->state == BR_STATE_FORWARDING))

return;

fdb = fdb_find_rcu(head, addr);

if (likely(fdb)) {

/* attempt to update an entry for a local interface */

if (unlikely(fdb->is_local)) {

if (net_ratelimit())

br_warn(br, "received packet on %s with "

"own address as source address.  MAC address is %s \n",

source->dev->name, addr);

} else {

/* fastpath: update of existing entry */  
//如果FDB中已经存在了该MAC表项,则仅更新最新的时间,用于下次老化查询

fdb->dst = source;

fdb->updated = jiffies;

}

} else {

spin_lock(&br->hash_lock);

if (likely(!fdb_find(head, addr)))

fdb_create(head, source, addr);      
//如果FDB中没有该MAC表项,则调用fdb_create来创建新的表项 /* else  we lose race and someone else inserts * it first, don't bother updating */ spin_unlock(&br->hash_lock); } }

给TA打赏
共{{data.count}}人
人已打赏
安全运维

WordPress网站专用docker容器环境带Waf

2020-7-18 20:04:44

安全运维

运维安全-Gitlab管理员权限安全思考

2021-9-19 9:16:14

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索