Linux网络协议栈(五) -- 数据包的发送(based in 2.6.32)

本文详细介绍了Linux 2.6.32版本中网络协议栈数据包发送的过程,从关键数据结构如net_device和Qdisc开始,涵盖输出队列的初始化、重置,网络层与链路层的接口,流量控制模块的实现,以及封包发送的具体步骤。通过dev_queue_xmit和dev_hard_start_xmit等函数,揭示了数据包如何经过流量控制和驱动程序发送出去。
摘要由CSDN通过智能技术生成

一、关键数据结构

对于输出封包,设备的数据结构主要包括两个:输出队列(queue)和输出队列规则(queue discipline)。我们首先来看输出队列(2.6.18内核中无该结构体):

struct netdev_queue {

structnet_device  *dev;

structQdisc          *qdisc;

unsigned long             state;

structQdisc          *qdisc_sleeping;

spinlock_t             _xmit_lock____cacheline_aligned_in_smp;


int                 xmit_lock_owner;

unsignedlong             trans_start;

unsignedlong             tx_bytes;

unsignedlong             tx_packets;

       unsigned long             tx_dropped;

} ____cacheline_aligned_in_smp;

该结构描述了一个输出队列,输出队列其实就是输出封包的缓存队列。每个设备(net_device)有一个或多个输出队列,从设备的定义中我们就可以看出:

struct net_device

{

    ...

    struct netdev_queue *_tx ____cacheline_aligned_in_smp;

   // struct list_head   qdisc_list; in 2.6.18在发包时获取发送队列方式有修改

    unsignedint        num_tx_queues;                                                                                              

    unsignedint        real_num_tx_queues;

    structQdisc        *qdisc; 

    unsignedlong       tx_queue_len;  

    spinlock_t      tx_global_lock;

    ....

}

该网络设备结构中,_tx表示了发送队列,num_tx_queues表示发送队列的个数,均在创建网络设备时进行初始化。real_num_tx_queues表示当前活动的发送队列个数,tx_queue_len表示发送队列的最大长度,也即发送队列中正在排队的最大帧个数。qdisc表示了队列规则,该规则用于输出流量控制。其定义如下:

struct Qdisc {

    int             (*enqueue)(structsk_buff *skb, struct Qdisc *dev);

    structsk_buff *    (*dequeue)(struct Qdisc *dev);

    unsigned        flags;


#defineTCQ_F_BUILTIN       1

#defineTCQ_F_INGRESS       2

#defineTCQ_F_CAN_BYPASS    4

#defineTCQ_F_MQROOT        8

#define TCQ_F_WARN_NONWC    (1<< 16)


    int         padded;

    structQdisc_ops    *ops;

    structqdisc_size_table __rcu *stab;

    structlist_head    list;

    u32         handle;

    u32         parent;

    atomic_t        refcnt;

    structgnet_stats_rate_est  rate_est;


    int         (*reshape_fail)(structsk_buff *skb,

                    structQdisc *q);

    void            *u32_node;

    structQdisc        *__parent;

    struct netdev_queue *dev_queue;

    structQdisc        *next_sched;

    structsk_buff      *gso_skb;

    unsigned long       state;

    struct sk_buff_head q;   

   //sk_buff_head结构体中声明了锁,可直接获得队列的锁(qdisc->q.lock),2.6.18中获得锁方式略有不同(qdisc->dev->queue_lock)

    structgnet_stats_basic_packed bstats;

    structgnet_stats_queue qstats;

};

该结构体中有enqueue、dequeue及ops函数集,用于操作队列。gso_skb表示分片帧,q表示输出封包。//2.6.18中qdisc结构体无state字段,用net_device结构体的state字段表征状态。


二、初始化输出队列

输出队列的初始化在注册网络设备时完成。用于向内核注册

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值