首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

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

()来构造一个新的sk_buff 2)使用skb_reserve(rx_skb, 2); 将sk_buff缓冲区里的数据包先后位移2字节,来腾出sk_buff缓冲区里的头部空间 3)读取网络设备硬件上接收到的数据...()来构造一个新的sk_buff 6)使用skb_reserve(rx_skb, 2);将sk_buff缓冲区里的数据包先后位移2字节,来腾出sk_buff缓冲区里的头部空间 7)使用memcpy()将之前修改好的...sk_buff->data复制到新的sk_buff里的data成员指向的地址处: memcpy(skb_put(rx_skb, skb->len), skb->data, skb->len); // skb_put... #include #include #include #include...(skb_put(rx_skb, skb->len), skb->data, skb->len); // skb_put():来动态扩大sk_buff结构体里中的数据区,避免溢出 /*8)设置新的

10.2K101
您找到你想要的搜索结果了吗?
是的
没有找到

Linux内核网络UDP数据包发送(三)——IP协议层分析

前言 Linux内核网络 UDP 协议层通过调用 ip_send_skbskb 交给 IP 协议层,本文通过分析内核 IP 协议层的关键函数来分享内核数据包发送在 IP 协议层的处理,并分享了监控...它只是调用ip_local_out,如果调用失败,就更新相应的错误计数: int ip_send_skb(struct net *net, struct sk_buff *skb) {.... */ static inline int dst_output(struct sk_buff *skb) { return skb_dst(skb)->output(skb); }...以上两种情况,最后都会到 dev_queue_xmit,它将 skb 发送给 Linux 网络设备子系统,在它 进入设备驱动程序层之前将对其进行更多处理。...将头数据复制到 skb 后,skb_push 将更新 skb 内指向数据缓冲区的指针。最后调用 dev_queue_xmit 将 skb 传递给 Linux 网络设备子系统。

2.9K21

Linux内核UDP收包为什么效率低?性能怎么优化(超详细讲解)

现在很多人都在诟病Linux内核协议栈收包效率低,不管他们是真的懂还是一点都不懂只是听别人说的,反正就是在一味地怼Linux内核协议栈,他们的武器貌似只有DPDK。...) // 进程上下文 { skb = dequeue(sk); // 见上面的伪代码 if (skb) { copy_skb_to_buff(skb, buff); low_lock_lock..., skb); update_statis(sk); spin_unlock(sk->sk_receive_queue->lock); } sk_buff dequeue(sk) { spin_lock...udp_recv(sk, buff) // 进程上下文 { skb = dequeue(sk); // 见上面的伪代码 if (skb) { copy_skb_to_buff(skb, buff...= recv_dequeue(sk); // 仅仅从接收队列里拉取 if (skb) { copy_skb_to_buff(skb, buff); } } 如此一来,双队列解除了中断上下文和进程上下文之间的锁竞争

1.5K20

Linux内核UDP收包为什么效率低?能做什么优化?

现在很多人都在诟病Linux内核协议栈收包效率低,不管他们是真的懂还是一点都不懂只是听别人说的,反正就是在一味地怼Linux内核协议栈,他们的武器貌似只有DPDK。...) // 进程上下文 { skb = dequeue(sk); // 见上面的伪代码 if (skb) { copy_skb_to_buff(skb, buff); low_lock_lock..., skb); update_statis(sk); spin_unlock(sk->sk_receive_queue->lock); } sk_buff dequeue(sk) { spin_lock...(sk, buff) // 进程上下文 { skb = dequeue(sk); // 见上面的伪代码 if (skb) { copy_skb_to_buff(skb, buff); } }...= recv_dequeue(sk); // 仅仅从接收队列里拉取 if (skb) { copy_skb_to_buff(skb, buff); } } 如此一来,双队列解除了中断上下文和进程上下文之间的锁竞争

3.2K61

Linux 网卡数据收发过程分析

所以,当网卡接收到数据包后,要通知 Linux 内核有数据需要处理。另外,网卡驱动应该提供让 Linux 内核把数据把发送出去的接口。...net_device 结构是 Linux 为了适配不同类型的网卡设备而抽象出来的对象,不同的网卡驱动只需要按 Linux 的规范来填充 net_device 结构的各个成员变量,Linux 内核就能够识别出网卡...if ((pkt_stat & 0x0F) == ENRSR_RXOK) { // 如果数据包状态是合法的 struct sk_buff *skb; skb...return; } ei_receive 函数主要完成以下几个工作: 申请一个 sk_buff 数据包对象,并且设置其 dev 字段为接收数据包的设备。...我们来看看 ei_start_xmit 函数的实现: static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev) {

2.3K30

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

结构体的链表组成,其中一个sk_buff数据结构对应一个网络包;这个结构体后面会详细讲,是Linux实现网络协议栈的核心数据结构。...,因此Linux采用在sk_buff中的一个Union结构体进行标识: struct sk_buff { union { struct tcphdr *th; // TCP...) 的内存空间; 因此当发送这个网络包时: Case1:不存在缓冲区积压,则新建一个sk_buff进行网络包的发送; skb->truesize = 768 skb->datalen = 0 skb_shared_info...的已经发送的网络包-即SEND-Q中存在sk_buff结构),Linux会尝试将当前包合并到SEND-Q的最后一个sk_buff结构中 (粘包) ; 考虑我们上述的768bytes的结构体为SEND-Q...2048*2=4096,因为linux除了要考虑用户的应用层数据,还需要考虑linux自身数据结构的开销-协议头部、指针、非线性内存区域结构等... sk_buff结构中通过sk_wmem_queued

1.9K30

25 张图,一万字,拆解 Linux 网络包发送过程

一、Linux 网络发送过程总览 我觉得看 Linux 源码最重要的是得有整体上的把握,而不是一开始就陷入各种细节。...如上所示,这个函数是在获取 socket 发送队列中的最后一个 skbskb 是 struct sk_buff 对象的简称,用户的发送队列就是该对象组成的一个链表。...//file: include/linux/skbuff.h struct sk_buff { //保存了一些路由相关信息 unsigned long _skb_refdst; } 接下来就是定位到...最后调用 dev_queue_xmit 将 skb 传递给 Linux 网络设备子系统。 4.5 网络设备子系统 邻居子系统通过 dev_queue_xmit 进入到网络设备子系统中来。...//file: include/linux/netdevice.h struct net_device_ops { netdev_tx_t (*ndo_start_xmit) (struct sk_buff

1.9K21

25 张图,一万字,拆解 Linux 网络包发送过程

一、Linux 网络发送过程总览 我觉得看 Linux 源码最重要的是得有整体上的把握,而不是一开始就陷入各种细节。...如上所示,这个函数是在获取 socket 发送队列中的最后一个 skbskb 是 struct sk_buff 对象的简称,用户的发送队列就是该对象组成的一个链表。 ?...//file: include/linux/skbuff.h struct sk_buff { //保存了一些路由相关信息 unsigned long _skb_refdst; } 接下来就是定位到...最后调用 dev_queue_xmit 将 skb 传递给 Linux 网络设备子系统。 4.5 网络设备子系统 ? 邻居子系统通过 dev_queue_xmit 进入到网络设备子系统中来。...//file: include/linux/netdevice.h struct net_device_ops { netdev_tx_t (*ndo_start_xmit) (struct sk_buff

2.4K52
领券