linux2.6内核网卡数据流过程

来源:互联网 发布:绝对萌域 淘宝 编辑:程序博客网 时间:2024/06/06 08:49
linux 2.6版的内核,网络数据从网线到应用程序需经过3次copy,分别是:
1. 网线上的电信号经过网卡驱DMA到网卡的环形FIFO里;
2. 从网卡的接收环形FIFO里copy到TCP/IP协议栈的sk_buff里;
3. 应用程序的socket调用recv()函数从协议栈的buffer里copy到用户进程的buffer里。

步骤中的2, sk_buff结构体设计得非常精巧:
C/C++ code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/** 
 *    struct sk_buff - socket buffer
 *    @next: Next buffer in list
 *    @prev: Previous buffer in list
 *    @list: List we are on
 *    @sk: Socket we are owned by
 *    @stamp: Time we arrived
 *    @dev: Device we arrived on/are leaving by
 *    @input_dev: Device we arrived on
 *      @real_dev: The real device we are using
 *    @h: Transport layer header
 *    @nh: Network layer header
 *    @mac: Link layer header
 *    @dst: FIXME: Describe this field
 *    @cb: Control buffer. Free for use by every layer. Put private vars here
 *    @len: Length of actual data
 *    @data_len: Data length
 *    @mac_len: Length of link layer header
 *    @csum: Checksum
 *    @__unused: Dead field, may be reused
 *    @cloned: Head may be cloned (check refcnt to be sure)
 *    @pkt_type: Packet class
 *    @ip_summed: Driver fed us an IP checksum
 *    @priority: Packet queueing priority
 *    @users: User count - see {datagram,tcp}.c
 *    @protocol: Packet protocol from driver
 *    @security: Security level of packet
 *    @truesize: Buffer size 
 *    @head: Head of buffer
 *    @data: Data head pointer
 *    @tail: Tail pointer
 *    @end: End pointer
 *    @destructor: Destruct function
 *    @nfmark: Can be used for communication between hooks
 *    @nfcache: Cache info
 *    @nfct: Associated connection, if any
 *    @nfctinfo: Relationship of this skb to the connection
 *    @nf_debug: Netfilter debugging
 *    @nf_bridge: Saved data about a bridged frame - see br_netfilter.c
 *      @private: Data which is private to the HIPPI implementation
 *    @tc_index: Traffic control index
 */
 
struct sk_buff {
    /* These two members must be first. */
    struct sk_buff        *next;
    struct sk_buff        *prev;
 
    struct sk_buff_head    *list;
    struct sock        *sk;
    struct timeval        stamp;
    struct net_device    *dev;
    struct net_device    *input_dev;
    struct net_device    *real_dev;
 
    union {
        struct tcphdr    *th;
        struct udphdr    *uh;
        struct icmphdr    *icmph;
        struct igmphdr    *igmph;
        struct iphdr    *ipiph;
        struct ipv6hdr    *ipv6h;
        unsigned char   *raw;
    } h;
 
    union {
        struct iphdr    *iph;
        struct ipv6hdr    *ipv6h;
        struct arphdr    *arph;
        unsigned char   *raw;
    } nh;
 
    union {
          unsigned char    *raw;
    } mac;
 
    struct  dst_entry    *dst;
    struct   sec_path    *sp;
 
    /*
     * This is the control buffer. It is free to use for every
     * layer. Please put your private variables there. If you
     * want to keep them across layers you have to do a skb_clone()
     * first. This is owned by whoever has the skb queued ATM.
     */
    char           cb[40];
 
    unsigned int       len,
                data_len,
                mac_len,
                csum;
    unsigned char       local_df,
                cloned,
                pkt_type,
                ip_summed;
    __u32            priority;
    unsigned short       protocol,
                security;
 
    void           (*destructor)(struct sk_buff *skb);
#ifdef CONFIG_NETFILTER
        unsigned long       nfmark;
    __u32            nfcache;
    __u32            nfctinfo;
    struct nf_conntrack    *nfct;
#ifdef CONFIG_NETFILTER_DEBUG
        unsigned int       nf_debug;
#endif
#ifdef CONFIG_BRIDGE_NETFILTER
    struct nf_bridge_info    *nf_bridge;
#endif
#endif /* CONFIG_NETFILTER */
#if defined(CONFIG_HIPPI)
    union {
        __u32        ifield;
    private;
#endif
#ifdef CONFIG_NET_SCHED
       __u32            tc_index;        /* traffic control index */
#ifdef CONFIG_NET_CLS_ACT
    __u32           tc_verd;               /* traffic control verdict */
    __u32           tc_classid;            /* traffic control classid */
#endif
 
#endif
 
 
    /* These elements must be at the end, see alloc_skb() for details.  */
    unsigned int       truesize;
    atomic_t        users;
    unsigned char       *head,
                *data,
                *tail,
                *end;
};
0 0
原创粉丝点击