LInux下桥接模式详解二

上篇文章导入博客园的比较早,而这篇自己在写的时候才发现内部复杂的很,以至于没能按时完成,造成两篇文章的间隔时间有点长!

话不多说,言归正传!

前面的文章介绍了桥接模式下的基础理论知识,其实本节想结合LInux源代码分析下桥接模式下的数据包的转发流程,但是看了源码才发现,这部分内容太多,非一篇文章可以描述的清楚的,所以决定本篇文章主要介绍下linux网络相关的主要结构体,以及各个结构之间的关当一个网络数据包来到host的物理网卡,由于此时网卡已经是混杂模式,所以此数据包的目的地不一定就是host本身。那么此时网卡的   设备控制器就会向host的APIC发送中断信号。CPU收到中断信号后,会自动进入处理该中断的流程,调用IDT中网卡驱动注册的中断处理函数进行处理。

而最终数据包会__netif_receive_skb_core函数进行处理,在进入此函数之前,我们有必要了解下相关的数据结构。

struct net_device 网络设备结构,这里只列举了和我们要分析的相关的信息

 1 struct net_device{
 2   ……
 3   unsigned long    state;
 4
 5   ……
 6   unsigned int    flags;    /* interface flags (a la BSD)    */
 7   unsigned int    priv_flags; /* Like ‘flags‘ but invisible to userspace.
 8
 9   ……
10   
11   #if IS_ENABLED(CONFIG_VLAN_8021Q)
12   struct vlan_info __rcu    *vlan_info;    /* VLAN info */
13   #endif
14
15   ……
16   unsigned char *dev_addr
17   rx_handler_func_t __rcu *rx_handler;
18   void __rcu    *rx_handler_data;
19
20   …… 
21
22 }
23

net_device结构代表一个网络设备,每一个物理网卡还有linux内部都有一个独立的net_device结构与之对应。

state表示设备的状态

flag表示设备的特性,而priv_flag则表示设备的私有特性,对用户空间是不可见的。

dev_addr表示设备的mac地址

rx_handler代表一个钩子函数,在网卡混杂模式开启时,此函数会被初始化成一个转发数据包的函数

rx_hander_data 代表前面函数的参数

struct sk_buff  应用层的数据包结构

 1 struct sk_buffer{
 2   struct sk_buff *next;
 3   struct sk_buff    *prev;
 4
 5   ……
 6
 7   struct net_device *dev;
 8
 9   ……
1115   __u16    transport_header;//传输层头部偏移
16   __u16    network_header; //IP头部偏移
17   __u16    mac_header;//MAC地址偏移
18   /* These elements must be at the end, see alloc_skb() for details. */
19   sk_buff_data_t    tail;
20   sk_buff_data_t    end;
21   unsigned char    *head,//buffer header指针
22                    *data; //数据指针
23   unsigned int    truesize;
24   atomic_t    users;
25
26 }

该结构是数据包逐层交付所必须的结构,其中Next和prev分别指向下一个和上一个buffer,dev表示这个buffer从哪个设备进入,data指向buffer的数据区,head指向buffer的最开始的头部,

mac_header是以太网头部到head指针的偏移,network_header是Ip数据包头部到head指针的偏移,transport_header是传送层头部到head指针的偏移,tail指向数据部分的结束,end指向buffer的结束。truesize是buffer实际的大小,user记录用户数,主要表明是否共享。

struct net_bridge 网桥结构

1 struct net_bridge{
2 struct list_head port_list;//所有端口组成的链表头
3 struct net_device    *dev; //对应的物理设备
4
5 ……
6
7 struct net_bridge_mdb_htable __rcu *mdb;
8 ……
9 }

这是linux内部的网桥对应的结构,port_list连接网桥所有的端口,dev指向网桥的设备结构体,mdb指向网桥的组播数据库转发表

struct net_bridge_port 网桥端口结构

 1 struct net_bridge_port
 2 {
 3     struct net_bridge    *br; //对应的网桥
 4     struct net_device    *dev; //端口对应的设备
 5     struct list_head    list;
 6     ……
 7     u8 state;
 8     ……
 9     unsigned long flags;
10     ……
11     struct hlist_head mglist;
12     ……
13 }

net_bridge_port结构对应于网桥的一个端口,state表明端口的状态,flags表明端口本身的特性,dev指向它关联的设备,br指向它attach的网桥,mglist连接所有port加入的组,flag记录了端口的某些特性,state表明了端口的某一个状态,如转发、学习等。

struct net_bridge_fdb_entry  网桥内部转发表表项

 1 struct net_bridge_fdb_entry
 2 {
 3     struct hlist_node        hlist;
 4     struct net_bridge_port        *dst;
 5
 6     struct rcu_head            rcu;
 7     unsigned long            updated;
 8     unsigned long            used;
 9     mac_addr            addr;
10     unsigned char            is_local;
11     unsigned char            is_static;
12     __u16                vlan_id;
13 };

这是网桥内部转发表的表项,hlist表明表项作为一个节点存在于某张表中,这张表就是转发表。dst指向目的端口,addr是表项的mac地址,isLocal表明是否是本地端口,本地端口我猜想是网桥的数据流入端口,即当目的mac是本地端口表明这是发往本地的数据包;isstatic表明是否是静态地址,静态地址不能自动更新。

struct net_bridge_mdb_htable   /*组播组数据库转发表,该结构体将所有的组播组数据库转发项通过hash数组连接到一起*/

 1 struct net_bridge_mdb_htable
 2 {
 3   struct hlist_head    *mhash;
 4   struct rcu_head    rcu;
 5   struct net_bridge_mdb_htable    *old;
 6   u32    size;
 7   u32    max;
 8   u32    secret;
 9   u32    ver;
10 };

该结构表示一个组播数据库转发表,连接了所有的组播数据库转发项.size表示表的大小,max表示最大容量。

struct net_port_vlans 

 1 struct net_port_vlans {
 2     u16                port_idx;
 3     u16                pvid;
 4     union {
 5         struct net_bridge_port        *port;
 6         struct net_bridge        *br;
 7     }                parent;
 8     struct rcu_head            rcu;
 9     unsigned long            vlan_bitmap[BR_VLAN_BITMAP_LEN];
10     unsigned long            untagged_bitmap[BR_VLAN_BITMAP_LEN];
11     u16                num_vlans;
12 };

struct net_bridge_mdb_entry 

struct net_bridge_mdb_entry

{
       struct hlist_node            hlist[2];
       struct hlist_node            mglist;
       struct net_bridge           *br;//桥
       struct net_bridge_port_group *ports;//
       struct rcu_head                     rcu;
       struct timer_list             timer;//组播组数据库项失效定时器,若超时,则会将该组播端口从组播组数据库项的组播端口列表中删除
       struct timer_list             query_timer;//查询定时
       __be32                         addr;//组播组地址
       u32                       queries_sent;

};

struct net_bridge_port_group 

1 struct net_bridge_port_group {
2     struct net_bridge_port        *port;
3     struct net_bridge_port_group __rcu *next;
4     struct hlist_node        mglist;
5     struct rcu_head            rcu;
6     struct timer_list        timer;
7     struct br_ip            addr;
8     unsigned char            state;
9 };

这是用于组播的组结构,一个组绑定一个组播地址addr,next指向下一个组播组,port指向组的端口,timer是定时器,mgList用于连接一个端口加入的所有的group,表头保存在port结构里

struct mac_addr  MAC地址结构

1 struct mac_addr
2 {
3     unsigned char    addr[6];
4 };

可以看到内核中MAC地址用6个字节表示

牵扯到的几个结构基本都在这里了,里面好多变量我也不是很清楚,有说错的地方还请老师们多多指正!!下一篇就结合源代码分析具体的数据包处理流程了

时间: 2024-11-05 18:50:45

LInux下桥接模式详解二的相关文章

linux下tar命令详解

 linux下tar命令详解  tar是Linux环境下最常用的备份工具之一.tar(tap archive)原意为操作磁带文件,但基于Linux的文件操作机制,同样也可适用于普通的磁盘文件.tar可用于建立.还原.查看.管理文件,也可方 便的追加新文件到备份文件中,或仅更新部分的备份文件,以及解压.删除指定的文件.熟悉其常用参数,能方便日常的系统管理工作. 一.版本 还是那句,不同的操作系统,tar的命令参数是有点区别的: 引用 # tar --version tar (GNU tar) 1.

(转)Linux下PS命令详解

(转)Linux下PS命令详解 整理自:http://blog.chinaunix.net/space.php?uid=20564848&do=blog&id=74654 要对系统中进程进行监测控制,查看状态,内存,CPU的使用情况,使用命令:/bin/ps (1) ps :是显示瞬间进程的状态,并不动态连续: (2) top:如果想对进程运行时间监控,应该用 top 命令: (3) kill 用于杀死进程或者给进程发送信号: (4) 查看文章最后的man手册,可以查看ps的每项输出的含义

Linux下chkconfig命令详解

Linux下chkconfig命令详解 chkconfig命令主要用来更新(启动或停止)和查询系统服务的运行级信息.谨记chkconfig不是立即自动禁止或激活一个服务,它只是简单的改变了符号连接. 使用语法:chkconfig [--add][--del][--list][系统服务] 或 chkconfig [--level <等级代号>][系统服务][on/off/reset] chkconfig在没有参数运行时,显示用法.如果加上服务名,那么就检查这个服务是否在当前运行级启动.如果是,返

转载的 Linux下chkconfig命令详解

Linux下chkconfig命令详解 chkconfig命令主要用来更新(启动或停止)和查询系统服务的运行级信息.谨记chkconfig不是立即自动禁止或激活一个服务,它只是简单的改变了符号连接. 使用语法: chkconfig [--add][--del][--list][系统服务] 或 chkconfig [--level <等级代号>][系统服务][on/off/reset] chkconfig 在没有参数运行时,显示用法.如果加上服务名,那么就检查这个服务是否在当前运行级启动.如果是

linux下scp命令详解

scp是 secure copy的缩写, scp是linux系统下基于ssh登陆进行安全的远程文件拷贝命令.linux的scp命令可以在linux服务器之间复制文件和目录. scp命令的用处: scp在网络上不同的主机之间复制文件,它使用ssh安全协议传输数据,具有和ssh一样的验证机制,从而安全的远程拷贝文件. scp命令基本格式: scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file] [-l limit] [-o s

linux下IPTABLES配置详解 (防火墙命令)

linux下IPTABLES配置详解 -A RH-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 24000 -j ACCEPT-A RH-Firewall-1-INPUT -s 121.10.120.24 -p tcp -m tcp --dport 18612 -j ACCEPT 如果你的IPTABLES基础知识还不了解,建议先去看看. 开始配置 我们来配置一个filter表的防火墙. (1)查看本机关于IPTABLES的

linux下任务计划详解

一次性任务计划 用at(指定时间执行任务,需开启atd服务)   batch(不指定执行时间,在系统空闲时/系统负载较低时自动执行任务)等命令来实现 周期性任务计划 cron(需启动crond服务) at介绍 at now+3min|11:30|noon,midnight,teatime(更多时间指定格式见man at页)  回车  在>提示符下可输入多行命令,用ctrl+d提交任务 atq 查看当前等待执行的atd的命令队列,或  at  -l at会将执行结果(即执行输出)以邮件方式发给任务

Linux下chkconfig命令详解(转)

Linux下chkconfig命令详解 chkconfig命令主要用来更新(启动或停止)和查询系统服务的运行级信息.谨记chkconfig不是立即自动禁止或激活一个服务,它只是简单的改变了符号连接. 使用语法:chkconfig [--add][--del][--list][系统服务] 或 chkconfig [--level <等级代号>][系统服务][on/off/reset] chkconfig在没有参数运行时,显示用法.如果加上服务名,那么就检查这个服务是否在当前运行级启动.如果是,返

&lt;linux下sysctl指令详解&gt;

Sysctl指令是对系统核心参数的设置: 用法: -a 参数列出系统中所有核心设置 当然了这些核心的设置都是文件,存放于/proc/sys/net目录下. 举个有代表性的例子: net.ipv4.icmp_echo_ignore_all = 0      把所有的点改为 / 就可以了.   [[email protected] net]# net.ipv4.icmp_echo_ignore_all = 0 [[email protected] net]# cd ipv4/ [[email pro