加入收藏 | 设为首页 | 会员中心 | 我要投稿 温州站长网 (https://www.0577zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

Linux内核分析 - 网络[六]:网桥

发布时间:2016-09-28 06:27:19 所属栏目:Linux 来源:站长网
导读:副标题#e# 看完了路由表,重新回到netif_receive_skb ()函数,在提交给上层协议处理前,会执行下面一句,这就是网桥的相关操作 ,也是这篇要讲解的内容。 skb = handle_bridge(skb, pt_prev, ret, orig_dev); 网桥可以简单理 解为交换机,以下图为例,一台l

如果端口state= BR_STATE_LEARNING,如果是发往本机的报文,则设置pkt_type为PACKET_HOST,然后执行 br_handle_frame_finish来完成报文的进一步处理。要注意的是,这里将报文发往本机的报文设为PACKET_HOST,实现了经过网 桥处理后,再次进入netif_receive_skb()时,不会再被网桥处理(结果进入网桥的条件理解):

if (!

compare_ether_addr(p->br->dev->dev_addr, dest))     
  skb->pkt_type = PACKET_HOST;     
NF_HOOK(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,     
  br_handle_frame_finish);

除此之外,端口处于不可用状态,此时丢弃掉报文:

kfree_skb(skb);

下 面来详细看下br_handle_frame_finish()函数。

首先还是会根据收到报文的源mac和端口更新CAM表,这是交换机区别于hub的 重要特征:

br_fdb_update(br, p, eth_hdr(skb)->h_source);

然后如果端口处于LEARNING状态,则只是学习 到CAM表中,而不对报文作任何处理,所以丢弃掉报文:

if (p->state == BR_STATE_LEARNING)     
  goto drop;

否则端口已处于FORWARDING状态,此时分情况:

1. 如果报文是多播的,则br_flood_forward(br, skb, skb2);

2. 如果报文是单播的,但不在网桥的CAM表中,则br_flood_forward(br, skb, skb2);

3. 如果报文是单播的 ,在网桥的CAM表中,但不是发往本机,则br_forward(dst->dst, skb, skb2);

4. 如果报文是单播的,在网桥的CAM表中 ,且是发往本机,则br_pass_frame_upbr_pass_frame_up(skb2);

br_handle_frame_finish()处理完后,顺着最后一种情 况继续往下走,br_pass_frame_up()。

该函数比较简单,我们知道,在底层报文的向上传递就是通过设备的更换来进行的(参 考802.1q),这里将skb的设备换成网桥设备,使上层协议不知道报文来自网卡,而是认为报文来自于网桥;然后调用 netif_receive_skb()再次进入接收栈:

skb->dev = brdev;     
return NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL,     
         netif_receive_skb);

经过网桥处理后,再次进入netif_receive_skb()->handle_bridge(),此时skb- >dev已经不是网卡设备了,而是网桥设备,注意到在向网桥添加端口时,是相应网卡dev->br_port赋值为创建的端口,网 桥设备是没有的,因此其br_port为空,在这一句会直接返回,进入正常的协议栈流程:

if (skb->pkt_type == 

PACKET_LOOPBACK ||     
     (port = rcu_dereference(skb->dev->br_port)) == NULL)     
  return skb;

当发送数据报文时,会调用br_dev_xmit()[netbridgebr_device.c],大致会根据目的地址调用 br_multicast_deliver()或br_flood_deliver()或br_deliver(),在其过程中会将skb->dev由原来的网桥设备brdev换面网卡 设备dev,然后通过网卡变更向下传递报文;

内核协议栈中,发送与接收是分离的,接收像是报文脱壳的过程,发送则是函数的嵌套调用。有关发送的流程,稍 后专门详述。

(编辑:温州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读