首页
学习
活动
专区
圈层
工具
发布

26.Linux-网卡驱动介绍以及制作虚拟网卡驱动(详解)

//指向下一个sk_buff结构体 struct sk_buff *prev; //指向前一个sk_buff结构体     ... ......, 在收包函数中: 首先修改发送的sk_buff里数据包的数据,使它变为一个接收的sk_buff,其中数据包结构如下图所示: ?...6)使用skb_reserve(rx_skb, 2);将sk_buff缓冲区里的数据包先后位移2字节,来腾出sk_buff缓冲区里的头部空间 7)使用memcpy()将之前修改好的sk_buff->data...sk_buff结构体里中的数据区,避免溢出 8)设置新的sk_buff 其它成员 9)使用eth_type_trans()来获取上层协议,将返回值赋给sk_buff的protocol成员里 10)然后更新接收统计信息...,最后使用netif_rx( )来将sk_fuffer传递给上层协议中 7.驱动具体代码如下: #include linux/module.h> #include linux/errno.h> #include

12.6K102
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    Linux 是如何收发网络包的?

    如果使用的是 TCP 传输协议发送数据,那么先拷贝一个新的 sk_buff 副本 ,这是因为 sk_buff 后续在调用网络层,最后到达网卡发送完成的时候,这个 sk_buff 会被释放掉。...网络接口层会通过 ARP 协议获得下一跳的 MAC 地址,然后对 sk_buff 填充帧头和帧尾,接着将 sk_buff 放到网卡的发送队列中。...这一些工作准备好后,会触发「软中断」告诉网卡驱动程序,这里有新的网络包需要发送,驱动程序会从发送队列中读取 sk_buff,将这个 sk_buff 挂到 RingBuffer 中,接着将 sk_buff...副本 sk_buff 会被送往网络层,等它发送完的时候就会释放掉,然后原始的 sk_buff 还保留在传输层,目的是为了实现 TCP 的可靠传输,等收到这个数据包的 ACK 时,才会释放原始的 sk_buff...第三次,当 IP 层发现 sk_buff 大于 MTU 时才需要进行。会再申请额外的 sk_buff,并将原来的 sk_buff 拷贝为多个小的 sk_buff。

    1.5K10

    Linux中一个网络包的发送接收流程

    结构体的链表组成,其中一个sk_buff数据结构对应一个网络包;这个结构体后面会详细讲,是Linux实现网络协议栈的核心数据结构。...2. sk_buff数据结构解析 通过对sk_buff数据结构解析,窥见Linux中的一些设计思想; 进行协议头的增添 我们知道,按照网络栈的设定,发送网络包时,每经过一层,都会增加对应协议层的协议首部...,因此Linux采用在sk_buff中的一个Union结构体进行标识: struct sk_buff { union { struct tcphdr *th; // TCP...结构),Linux会尝试将当前包合并到SEND-Q的最后一个sk_buff结构中 (粘包) ; 考虑我们上述的768bytes的结构体为SEND-Q的最后一个sk_buff,当用户进程继续调用write...在真实创建的时候会设置大小2048*2=4096,因为linux除了要考虑用户的应用层数据,还需要考虑linux自身数据结构的开销-协议头部、指针、非线性内存区域结构等... sk_buff结构中通过sk_wmem_queued

    2.4K30

    Linux的以太网驱动(基于Zynq XC7Z020)

    Linux以太网驱动架构 linux以太网架构共包含三个部分 1 linux的网络架构 2 以太网mac数据驱动(收发) 3 以太网phy的驱动 linux的网络驱动架构及流程 申请注册及初始化设备 1...在中断中关闭接收中断并启用napi调度 if (napi_schedule_prep(&bp->napi)) { __napi_schedule(&bp->napi); } 发送 上层协议会将数据保存在sk_buff...中通过 eth_start_xmit(struct sk_buff *skb, struct net_device *dev)函数传下来,eth_start_xmit这个函数包含在之前的注册函数中...ndev->netdev_ops = ðps_netdev_ops; 在这个函数中,我们要做的 1 将sk_buff中传过来的有效数据放入缓冲区 2 将缓冲区的数据通过mac发送出去 以太网mac...发送 发送的数据地址已经保存在sk_buff ,根据其数量,将其分成一块块的数据,每块大小为描述符所指向的缓存大小,再将描述符相应的状态位做上标记(置1或置0)。就可以将数据发送出去了。

    1.6K30
    领券