【推荐阅读】

浅谈linux 内核网络 sk_buff 之克隆与复制

深入linux内核架构--进程&线程

浅析linux内核网络协议栈--linux bridge

1.

int netif_receive_skb(struct sk_buff *skb),该函数是网络设备驱动到链路层协议栈的接口函数,该函数最后会调用__netif_receive_skb_core函数,下面主要介绍函数流程

1.1

  list_for_each_entry_rcu(ptype, &ptype_all, list) {  //遍历ptype_all,如果有则做相应处理,例如raw socket和tcpdump实现  if (pt_prev)  ret = deliver_skb(skb, pt_prev, orig_dev);  pt_prev = ptype;  } 

主要遍历ptype_all链表的所有成员,然后执行成员里的处理函数,PF_PACKETsocket和tcpdump等实现都在这里了

1.2

rx_handler = rcu_dereference(skb->dev->rx_handler);   if (rx_handler) {  if (pt_prev) {  ret = deliver_skb(skb, pt_prev, orig_dev);  pt_prev = NULL;  }
//根据处理结果,判断接下来对数据包如何进一步处理。  switch (rx_handler(&skb)) {
//数据包已成功接收,不需要再处理  case RX_HANDLER_CONSUMED:  ret = NET_RX_SUCCESS;  goto unlock;
//当rx_handler改变过skb->dev时,在接收回路中再一次处理。  case RX_HANDLER_ANOTHER:  goto another_round;
//不使用匹配的方式,精确传递。  case RX_HANDLER_EXACT:  deliver_exact = true;
//忽略rx_handler的影响。  case RX_HANDLER_PASS:  break;  default:  BUG();  }  }  

可以看到这里首先从设备结构net_device中获取其rx_handler指针,该指针在网卡的混杂模式下指向一个处理函数叫做br_handle_frame,即网桥的处理流程

1.3

    if (likely(!deliver_exact)) {  deliver_ptype_list_skb(skb, &pt_prev, orig_dev, type,   //根据全局定义的协议处理报文  &ptype_base[ntohs(type) &  PTYPE_HASH_MASK]);  }

这里是从链路层进入上层的地方

链路层和上层连接主要通过:ptype_all ptype_base两链表

(1) ptype_all管理的协议主要用于分析目的,它接收所有到达第3层协议的数据包。

(2) ptype_base管理正常的3层协议,仅接收具有正确协议标志符的数据包,例如,Internet的0x0800。

这个目前支持的协议类型:其中ETH_P_IP, ETH_P_ARP, ETH_P_8021Q, 是我们比较关注的

2. 下面介绍桥处理:br_handle_frame

先上一张图

2.

首先根据dev->br_port判断收到报文的接口是否加入某个桥,如果加入则该报文进入桥处理。

桥处理首先判断该报文是否是 stp协议,如果是stp报文,则判断是否stp开启,如果开启,进去stp处理流程,如果,没有则不处理。

如果报文不是stp协议,则判断目的mac是否是网桥下的某个接口的mac,如果是则把in_dev改成网桥自己,然后重新走一遍协议栈,然后这个报文被送进网络层进行路由。如果目的mac不是网桥下的接口的mac,直接进行二层转发。

上面讲到进行三层路由,如果路由的目的ip任然是一个网桥,在调用dev_queue_xmit发送的时候,因为出接口是网桥,则会被br_dev_xmit接管,然后进行二层转发,找到实际出接口,再次调用dev_queue_xmit发送。

一文了解linux 网络协议栈(链路层)相关推荐

  1. linux 虚拟机大量udp请求失败_理解 Linux 网络栈:Linux 网络协议栈简单总结分析...

    1. Linux 网络路径 1.1 发送端 1.1.1 应用层 (1) Socket 应用层的各种网络应用程序基本上都是通过 Linux Socket 编程接口来和内核空间的网络协议栈通信的.Linu ...

  2. Linux网络协议栈:网络包接收过程

    目录 一 Linux网络收包总览 二 Linux启动 2.1 创建ksoftirqd内核线程 2.2 网络子系统初始化 2.3 协议栈注册 2.4 网卡驱动初始化 2.5 启动网卡 三 迎接数据的到来 ...

  3. 监视和调整Linux网络协议栈:发送数据

    目录 有关监视和调整Linux网络堆栈的一般建议 总览 详细外观 协议族注册 通过套接字发送网络数据 sock_sendmsg,__sock_sendmsg和__sock_sendmsg_nosec ...

  4. 理解 Linux 网络栈:Linux 网络协议栈简单总结

    1. Linux 网络路径 1.1 发送端 1.1.1 应用层 (1) Socket 应用层的各种网络应用程序基本上都是通过 Linux Socket 编程接口来和内核空间的网络协议栈通信的.Linu ...

  5. Linux网络协议栈:中断下半部处理

    <Linux中断处理:上半部和下半部> <Linux网络协议栈:中断下半部处理> 目录 数据包上送 网络中断下半部处理 总结 推荐阅读 在<Linux网络协议栈:网络包接 ...

  6. Linux网络协议栈:NAPI机制与处理流程分析(图解)

    Table of Contents NAPI机制 NAPI缺陷 使用 NAPI 先决条件 非NAPI帧的接收 netif_rx - 将网卡中收到的数据包放到系统中的接收队列中 enqueue_to_b ...

  7. 监视和调整Linux网络协议栈:接收数据

    Table of Contents 有关监视和调整Linux网络协议栈的建议 总览 详细外观 网络设备驱动程序 初始化 网络设备初始化 启动网络设备 监控网络设备 调整网络设备 SoftIRQ 什么是 ...

  8. 网络基础链路层--eth协议arp协议mtu

    网络基础链路层--eth协议&arp协议&mtu 一.链路层 二.eth-以太网协议 (一)mac地址 三.arp-地址解析协议 (一)解析流程 (二)arp缓存为什么只有很短的一段时 ...

  9. Linux网络协议栈:用eBPF写TCP拥塞控制算法

    其实不想用这个题目的,只因为TCP相关的东西比较吸引人的眼球,这篇文章的主题还是eBPF,而不是TCP. 用eBPF写TCP拥塞控制算法只是本文所讲内容的一个再平凡不过的例子. 先看两个问题,或者说是 ...

最新文章

  1. assignment makes pointer from integer without a...
  2. mysql function加速_MySQL - 函数(FUNCTION)
  3. group_concat默认长度限制
  4. kitten编程猫里的函数定义,函数实现和函数调用原理
  5. np合并 python_这15个tips,带你领略 Python 的简洁和优雅
  6. Robotium 数据驱动测试框架
  7. ——————————
  8. 基于非特定人语音识别芯片的技术方案
  9. 【服务器】Discuz论坛实现微信小程序(修改接口)
  10. BZOJ 1833 数位DP
  11. Tomcat反射时报错java.lang.ClassNotFoundException
  12. [INet] WebSocket 数据收发的详细过程
  13. docker下修改mysql配置文件
  14. 数值分析课后习题答案(百度网盘)
  15. 电脑上查看自己连接的WIFI密码
  16. 继明当时明月在:万历十五年
  17. harmonyos下载,harmonyos 2.0下载
  18. 迅雷 android下载地址 http,Android HTTP边下边播
  19. 大数据在智慧消防领域的应用
  20. U盘文件删除如何恢复?U盘里的东西删除怎么还原?

热门文章

  1. AndroidStudio的Gradle完全教程
  2. StringTokenizer类的用法
  3. linux运行luminati,Luminati使用从入门到精通-Luminati中国
  4. Fluent多相流之VOF模型操作实例
  5. jQuery中toggle与slideToggle以及fadeToggle之间的不同
  6. 生物信息学: 使用python包GOATOOLS查询GO
  7. 卷积神经网络相比循环神经网络具有哪些特征
  8. List.isEmpty()与CollectionUtils.isEmpty的区别
  9. Golang学习笔记汇总
  10. 《牧羊少年奇幻之旅》读书笔记