1. ISO参考模型与TCP/IP参考模型

2. 在kernel中如何管理网络包(Network Packets)

2.1 定义Socket Buffers

Socket Buffers 由以下两部分组成:

1) Packet data: 它是在网络上传输的数据,其存储位置对应的PDU (Protocol Data Unit)

2) Management data: 当包在kernel中进行处理时,kernel需要另外一些数据,如pointer, timers等,它们是协议实体间交换信息的ICI(Interface Control Information)

Socket Buffer构成如下图所示:

在Kernel处理过程中,网络数据以Socket Buffer的形式存在。

当app通过socket发送数据时,socket将创建一个对应的socket buffer,并把需要发送的数据(payload)放于其中。当它通过各个协议层时,每一层的包头将被插入到payload的前面,在创建socket buffer时,为包头预留了足够空间。按此方案,payload被copy两次:

1) 从用户空间copy到kernel空间

2) 发送数据到network adapter

在协议层间传递时,其数据变化如下图所示:

Socket Buffer数据结构如下所示:

[cpp] view plaincopy
  1. struct sk_buff {
  2. /* These two members must be first. */
  3. struct sk_buff      *next;
  4. struct sk_buff      *prev;
  5. ktime_t         tstamp;
  6. struct sock     *sk;
  7. struct net_device   *dev;
  8. /*
  9. * This is the control buffer. It is free to use for every
  10. * layer. Please put your private variables there. If you
  11. * want to keep them across layers you have to do a skb_clone()
  12. * first. This is owned by whoever has the skb queued ATM.
  13. */
  14. char            cb[48] __aligned(8);
  15. unsigned long       _skb_refdst;
  16. #ifdef CONFIG_XFRM
  17. struct  sec_path    *sp;
  18. #endif
  19. unsigned int        len,
  20. data_len;
  21. __u16           mac_len,
  22. hdr_len;
  23. union {
  24. __wsum      csum;
  25. struct {
  26. __u16   csum_start;
  27. __u16   csum_offset;
  28. };
  29. };
  30. __u32           priority;
  31. kmemcheck_bitfield_begin(flags1);
  32. __u8            local_df:1,
  33. cloned:1,
  34. ip_summed:2,
  35. nohdr:1,
  36. nfctinfo:3;
  37. __u8            pkt_type:3,
  38. fclone:2,
  39. ipvs_property:1,
  40. peeked:1,
  41. nf_trace:1;
  42. kmemcheck_bitfield_end(flags1);
  43. __be16          protocol;
  44. void            (*destructor)(struct sk_buff *skb);
  45. #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
  46. struct nf_conntrack *nfct;
  47. #endif
  48. #ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
  49. struct sk_buff      *nfct_reasm;
  50. #endif
  51. #ifdef CONFIG_BRIDGE_NETFILTER
  52. struct nf_bridge_info   *nf_bridge;
  53. #endif
  54. int         skb_iif;
  55. #ifdef CONFIG_NET_SCHED
  56. __u16           tc_index;   /* traffic control index */
  57. #ifdef CONFIG_NET_CLS_ACT
  58. __u16           tc_verd;    /* traffic control verdict */
  59. #endif
  60. #endif
  61. __u32           rxhash;
  62. __u16           queue_mapping;
  63. kmemcheck_bitfield_begin(flags2);
  64. #ifdef CONFIG_IPV6_NDISC_NODETYPE
  65. __u8            ndisc_nodetype:2;
  66. #endif
  67. __u8            ooo_okay:1;
  68. kmemcheck_bitfield_end(flags2);
  69. /* 0/13 bit hole */
  70. #ifdef CONFIG_NET_DMA
  71. dma_cookie_t        dma_cookie;
  72. #endif
  73. #ifdef CONFIG_NETWORK_SECMARK
  74. __u32           secmark;
  75. #endif
  76. union {
  77. __u32       mark;
  78. __u32       dropcount;
  79. };
  80. __u16           vlan_tci;
  81. sk_buff_data_t      transport_header; //传输层头
  82. sk_buff_data_t      network_header;   //网络层头
  83. sk_buff_data_t      mac_header;       //链路层头
  84. /* These elements must be at the end, see alloc_skb() for details.  */
  85. sk_buff_data_t      tail;
  86. sk_buff_data_t      end;
  87. unsigned char       *head,
  88. *data;
  89. unsigned int        truesize;
  90. atomic_t        users;
  91. }

对Socket Buffers的操作分为以下三类:

1) 创建、释放和复制sokcet buffers

2) 操作sk_buff结构中的参数和指针,主要是改变包数据空间的操作

3) 管理socket buffer队列

2.1.1 创建、释放和复制sokcet buffers

其相关函数如下所示:

alloc_skb()                include/linux/skbuff.h 
dev_alloc_skb()        net/core/skbuff.c 
skb_copy()                net/core/skbuff.c  
skb_copy_expand()  net/core/skbuff.c 
skb_clone()               net/core/skbuff.c 
kfree_skb()               net/core/skbuff.c 
dev_kfree_skb()       include/linux/skbuff.h 
kfree_skbmem()       net/core/skbuff.c

2.1.2 操作包数据空间

include/linux/skbuff.h 
skb_get()
skb_unshare()
skb_put()
skb_push()
skb_pull()
skb_tailroom()
skb_headroom()
skb_realloc_headroom()
skb_reserve()
skb_trim()
skb_cow()

2.2 定义Socket-Buffer Queues

如果Socket Buffer不是正在被处理,则它被sk_buff_head管理,它通过双向链表进行管理,如下图所示:

[cpp] view plaincopy
  1. struct sk_buff_head {
  2. /* These two members must be first. */
  3. struct sk_buff  *next;
  4. struct sk_buff  *prev;
  5. __u32       qlen;
  6. spinlock_t  lock;
  7. };

2.2.1 队列操作

include/linux/skbuff.h
skb_queue_head_init()
skb_queue_empty()
skb_queue_len()

2.2.2 队列中socket Buffer操作

include/linux/skbuff.h
skb_queue_head()
skb_queue_tail()
skb_dequeue()
skb_dequeue_tail()
skb_queue_purge()
skb_insert()
skb_append()
skb_unlink()
skb_peek()
skb_peek_tail()

3. Network Devices

在Linux系统中的网络架构,基于软件的协议(software-based protocol)与网络适配器(network adapters)间的接口通过network devices来实现。一个network-device接口需要满足以下要求:
     1) 是network adapter的技术抽象
     2) 提供统一的接口供协议实体访问

3.1 net_device定义

【网络设备】不同于【字符设备】和【块设备】,其主要区别如下:

1) 网络设备在/dev下不存在对应的设备名,即不可通过read和write进行读写操作

2) 网络设备基于包进行处理,且必须经过复杂协议的处理(如TCP和UDP)

net_device定义如下:

[cpp] view plaincopy
  1. struct net_device {
  2. /*
  3. * This is the first field of the "visible" part of this structure
  4. * (i.e. as seen by users in the "Space.c" file).  It is the name
  5. * of the interface.
  6. */
  7. char            name[IFNAMSIZ];
  8. struct pm_qos_request_list pm_qos_req;
  9. /* device name hash chain */
  10. struct hlist_node   name_hlist;
  11. /* snmp alias */
  12. char            *ifalias;
  13. // 硬件相关的信息
  14. /*
  15. *  I/O specific fields
  16. *  FIXME: Merge these and struct ifmap into one
  17. */
  18. unsigned long       mem_end;    /* shared mem end   */
  19. unsigned long       mem_start;  /* shared mem start */
  20. unsigned long       base_addr;  /* device I/O address   */
  21. unsigned int        irq;        /* device IRQ number    */
  22. /*
  23. *  Some hardware also needs these fields, but they are not
  24. *  part of the usual set specified in Space.c.
  25. */
  26. unsigned long       state;
  27. struct list_head    dev_list;
  28. struct list_head    napi_list;
  29. struct list_head    unreg_list;
  30. /* currently active device features */
  31. u32         features;
  32. /* user-changeable features */
  33. u32         hw_features;
  34. /* user-requested features */
  35. u32         wanted_features;
  36. /* mask of features inheritable by VLAN devices */
  37. u32         vlan_features;
  38. /* Interface index. Unique device identifier    */
  39. int         ifindex;
  40. int         iflink;
  41. struct net_device_stats stats;
  42. atomic_long_t       rx_dropped; /* dropped packets by core network
  43. * Do not use this in drivers.
  44. */
  45. // 管理操作
  46. /* Management operations */
  47. const struct net_device_ops *netdev_ops; // 最终调用网络设备驱动方法
  48. const struct ethtool_ops *ethtool_ops;
  49. // 硬件头描述
  50. /* Hardware header description */
  51. const struct header_ops *header_ops;
  52. unsigned int        flags;  /* interface flags (a la BSD)   */
  53. unsigned int        priv_flags; /* Like 'flags' but invisible to userspace. */
  54. unsigned short      gflags;
  55. unsigned short      padded; /* How much padding added by alloc_netdev() */
  56. unsigned char       operstate; /* RFC2863 operstate */
  57. unsigned char       link_mode; /* mapping policy to operstate */
  58. unsigned char       if_port;    /* Selectable AUI, TP,..*/
  59. unsigned char       dma;        /* DMA channel      */
  60. unsigned int        mtu;    /* interface MTU value      */
  61. unsigned short      type;   /* interface hardware type  */
  62. unsigned short      hard_header_len;    /* hardware hdr length  */
  63. /* extra head- and tailroom the hardware may need, but not in all cases
  64. * can this be guaranteed, especially tailroom. Some cases also use
  65. * LL_MAX_HEADER instead to allocate the skb.
  66. */
  67. unsigned short      needed_headroom;
  68. unsigned short      needed_tailroom;
  69. // 接口地址信息
  70. /* Interface address info. */
  71. unsigned char       perm_addr[MAX_ADDR_LEN]; /* permanent hw address */
  72. unsigned char       addr_assign_type; /* hw address assignment type */
  73. unsigned char       addr_len;   /* hardware address length  */
  74. unsigned short          dev_id;     /* for shared network cards */
  75. spinlock_t      addr_list_lock;
  76. struct netdev_hw_addr_list  uc; /* Unicast mac addresses */
  77. struct netdev_hw_addr_list  mc; /* Multicast mac addresses */
  78. int         uc_promisc;
  79. unsigned int        promiscuity;
  80. unsigned int        allmulti;
  81. // 协议相关的指针
  82. /* Protocol specific pointers */
  83. void            *atalk_ptr; /* AppleTalk link   */
  84. struct in_device __rcu  *ip_ptr;    /* IPv4 specific data   */
  85. struct dn_dev __rcu     *dn_ptr;        /* DECnet specific data */
  86. struct inet6_dev __rcu  *ip6_ptr;       /* IPv6 specific data */
  87. void            *ec_ptr;    /* Econet specific data */
  88. void            *ax25_ptr;  /* AX.25 specific data */
  89. struct wireless_dev *ieee80211_ptr; /* IEEE 802.11 specific data,
  90. assign before registering */
  91. // 在接收通道中需要缓存的数据
  92. /*
  93. * Cache lines mostly used on receive path (including eth_type_trans())
  94. */
  95. unsigned long       last_rx;    /* Time of last Rx
  96. * This should not be set in
  97. * drivers, unless really needed,
  98. * because network stack (bonding)
  99. * use it if/when necessary, to
  100. * avoid dirtying this cache line.
  101. */
  102. struct net_device   *master; /* Pointer to master device of a group,
  103. * which this device is member of.
  104. */
  105. /* Interface address info used in eth_type_trans() */
  106. unsigned char       *dev_addr;  /* hw address, (before bcast
  107. because most packets are
  108. unicast) */
  109. struct netdev_hw_addr_list  dev_addrs; /* list of device
  110. hw addresses */
  111. unsigned char       broadcast[MAX_ADDR_LEN];    /* hw bcast add */
  112. #ifdef CONFIG_RPS
  113. struct kset     *queues_kset;
  114. struct netdev_rx_queue  *_rx;
  115. /* Number of RX queues allocated at register_netdev() time */
  116. unsigned int        num_rx_queues;
  117. /* Number of RX queues currently active in device */
  118. unsigned int        real_num_rx_queues;
  119. #ifdef CONFIG_RFS_ACCEL
  120. /* CPU reverse-mapping for RX completion interrupts, indexed
  121. * by RX queue number.  Assigned by driver.  This must only be
  122. * set if the ndo_rx_flow_steer operation is defined. */
  123. struct cpu_rmap     *rx_cpu_rmap;
  124. #endif
  125. #endif
  126. rx_handler_func_t __rcu *rx_handler;
  127. void __rcu      *rx_handler_data;
  128. struct netdev_queue __rcu *ingress_queue;
  129. // 在发送通道中需要缓存的数据
  130. /*
  131. * Cache lines mostly used on transmit path
  132. */
  133. struct netdev_queue *_tx ____cacheline_aligned_in_smp;
  134. /* Number of TX queues allocated at alloc_netdev_mq() time  */
  135. unsigned int        num_tx_queues;
  136. /* Number of TX queues currently active in device  */
  137. unsigned int        real_num_tx_queues;
  138. /* root qdisc from userspace point of view */
  139. struct Qdisc        *qdisc;
  140. unsigned long       tx_queue_len;   /* Max frames per queue allowed */
  141. spinlock_t      tx_global_lock;
  142. #ifdef CONFIG_XPS
  143. struct xps_dev_maps __rcu *xps_maps;
  144. #endif
  145. /* These may be needed for future network-power-down code. */
  146. /*
  147. * trans_start here is expensive for high speed devices on SMP,
  148. * please use netdev_queue->trans_start instead.
  149. */
  150. unsigned long       trans_start;    /* Time (in jiffies) of last Tx */
  151. int         watchdog_timeo; /* used by dev_watchdog() */
  152. struct timer_list   watchdog_timer;
  153. /* Number of references to this device */
  154. int __percpu        *pcpu_refcnt;
  155. /* delayed register/unregister */
  156. struct list_head    todo_list;
  157. /* device index hash chain */
  158. struct hlist_node   index_hlist;
  159. struct list_head    link_watch_list;
  160. /* register/unregister state machine */
  161. enum { NETREG_UNINITIALIZED=0,
  162. NETREG_REGISTERED,   /* completed register_netdevice */
  163. NETREG_UNREGISTERING,    /* called unregister_netdevice */
  164. NETREG_UNREGISTERED, /* completed unregister todo */
  165. NETREG_RELEASED,     /* called free_netdev */
  166. NETREG_DUMMY,        /* dummy device for NAPI poll */
  167. } reg_state:8;
  168. bool dismantle; /* device is going do be freed */
  169. enum {
  170. RTNL_LINK_INITIALIZED,
  171. RTNL_LINK_INITIALIZING,
  172. } rtnl_link_state:16;
  173. /* Called from unregister, can be used to call free_netdev */
  174. void (*destructor)(struct net_device *dev);
  175. #ifdef CONFIG_NETPOLL
  176. struct netpoll_info *npinfo;
  177. #endif
  178. #ifdef CONFIG_NET_NS
  179. /* Network namespace this network device is inside */
  180. struct net      *nd_net;
  181. #endif
  182. /* mid-layer private */
  183. union {
  184. void                *ml_priv;
  185. struct pcpu_lstats __percpu *lstats; /* loopback stats */
  186. struct pcpu_tstats __percpu *tstats; /* tunnel stats */
  187. struct pcpu_dstats __percpu *dstats; /* dummy stats */
  188. };
  189. /* GARP */
  190. struct garp_port __rcu  *garp_port;
  191. /* class/net/name entry */
  192. struct device       dev;
  193. /* space for optional device, statistics, and wireless sysfs groups */
  194. const struct attribute_group *sysfs_groups[4];
  195. /* rtnetlink link ops */
  196. const struct rtnl_link_ops *rtnl_link_ops;
  197. /* for setting kernel sock attribute on TCP connection setup */
  198. #define GSO_MAX_SIZE        65536
  199. unsigned int        gso_max_size;
  200. u8 num_tc;
  201. struct netdev_tc_txq tc_to_txq[TC_MAX_QUEUE];
  202. u8 prio_tc_map[TC_BITMASK + 1];
  203. /* n-tuple filter list attached to this device */
  204. struct ethtool_rx_ntuple_list ethtool_ntuple_list;
  205. /* phy device may attach itself for hardware timestamping */
  206. struct phy_device *phydev;
  207. /* group the device belongs to */
  208. int group;
  209. }

net_device是每个网络设备的基础,它不仅包含network adapter硬件信息(如:interrupt, ports, driver functions等),也包含高层网络协议的配置数据(如:IP address, subnet mask等).
     在/sys/class/net下列出来所有网络设备的名字,如我的为:
     shell@android:/sys/class/net # ll
     lrwxrwxrwx root     root              2013-07-05 17:08 ip6tnl0 
     lrwxrwxrwx root     root              2013-07-05 17:08 lo  (loopback设备)
     lrwxrwxrwx root     root              2013-07-05 17:08 sit0 
     lrwxrwxrwx root     root              2000-01-01 08:00 wlan0 (Wifi设备)

3.2 管理net_device

从上面的协议实例看net_device。

3.2.1注册和注销网络设备(net_device)

位于文件:kernel/net/core/dev.c

int register_netdev(struct net_device *dev)

void unregister_netdev(struct net_device *dev)

网络设备(net_device)与一个已经存在的network adapter一一对应。

3.2.2 打开和关闭网络设备(net_device)

位于文件:kernel/net/core/dev.c

int dev_open(struct net_device *dev)

int dev_close(struct net_device *dev)

3.2.3 创建、释放和查找网络设备(net_device)

位于文件:kernel/net/core/dev.c

struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
                                                  void (*setup)(struct net_device *),
                                                  unsigned int txqs, unsigned int rxqs)

void free_netdev(struct net_device *dev)

int dev_alloc_name(struct net_device *dev, const char *name)

struct net_device *dev_get_by_index(struct net *net, int ifindex)

struct net_device *dev_get_by_name(struct net *net, const char *name)

void dev_load(struct net *net, const char *name)

3.2.4网络设备通知上层协议状态变化

int call_netdevice_notifiers(unsigned long val, struct net_device *dev)

网络状态有如下值:

NETDEV_UP: 激活一个网络设备 (dev_open)
       NETDEV_DOWN: 禁止一个网络设备 (dev_close)
       NETDEV_CHANGE: 通知网络设备状态变化
       NETDEV_REGISTER: 网络设备已经被注册,但是没有打开实例
       NETDEV_UNREGISTER: 网络设备已经被删除
       NETDEV_CHANGEMTU: 网络设备MTU被修改
       NETDEV_CHANGEADDR: 网络设备硬件地址被修改
       NETDEV_CHANGENAME:网络设备名字被修改

3.2.5 通过net_device发送数据

int dev_queue_xmit(struct sk_buff *skb)   // kernel/net/core/dev.c

它由高层的协议实例调用,以通过一个net_device(skb->dev)发送一个socket buffer.

3.3 net_device_ops

[cpp] view plaincopy
  1. struct net_device_ops {
  2. int         (*ndo_init)(struct net_device *dev);
  3. void            (*ndo_uninit)(struct net_device *dev);
  4. int         (*ndo_open)(struct net_device *dev);
  5. int         (*ndo_stop)(struct net_device *dev);
  6. netdev_tx_t     (*ndo_start_xmit) (struct sk_buff *skb,
  7. struct net_device *dev);
  8. u16         (*ndo_select_queue)(struct net_device *dev,
  9. struct sk_buff *skb);
  10. void            (*ndo_change_rx_flags)(struct net_device *dev,
  11. int flags);
  12. void            (*ndo_set_rx_mode)(struct net_device *dev);
  13. void            (*ndo_set_multicast_list)(struct net_device *dev);
  14. int         (*ndo_set_mac_address)(struct net_device *dev,
  15. void *addr);
  16. int         (*ndo_validate_addr)(struct net_device *dev);
  17. int         (*ndo_do_ioctl)(struct net_device *dev,
  18. struct ifreq *ifr, int cmd);
  19. int         (*ndo_set_config)(struct net_device *dev,
  20. struct ifmap *map);
  21. int         (*ndo_change_mtu)(struct net_device *dev,
  22. int new_mtu);
  23. int         (*ndo_neigh_setup)(struct net_device *dev,
  24. struct neigh_parms *);
  25. void            (*ndo_tx_timeout) (struct net_device *dev);
  26. struct rtnl_link_stats64* (*ndo_get_stats64)(struct net_device *dev,
  27. struct rtnl_link_stats64 *storage);
  28. struct net_device_stats* (*ndo_get_stats)(struct net_device *dev);
  29. void            (*ndo_vlan_rx_register)(struct net_device *dev,
  30. struct vlan_group *grp);
  31. void            (*ndo_vlan_rx_add_vid)(struct net_device *dev,
  32. unsigned short vid);
  33. void            (*ndo_vlan_rx_kill_vid)(struct net_device *dev,
  34. unsigned short vid);
  35. #ifdef CONFIG_NET_POLL_CONTROLLER
  36. void                    (*ndo_poll_controller)(struct net_device *dev);
  37. int         (*ndo_netpoll_setup)(struct net_device *dev,
  38. struct netpoll_info *info);
  39. void            (*ndo_netpoll_cleanup)(struct net_device *dev);
  40. #endif
  41. int         (*ndo_set_vf_mac)(struct net_device *dev,
  42. int queue, u8 *mac);
  43. int         (*ndo_set_vf_vlan)(struct net_device *dev,
  44. int queue, u16 vlan, u8 qos);
  45. int         (*ndo_set_vf_tx_rate)(struct net_device *dev,
  46. int vf, int rate);
  47. int         (*ndo_get_vf_config)(struct net_device *dev,
  48. int vf,
  49. struct ifla_vf_info *ivf);
  50. int         (*ndo_set_vf_port)(struct net_device *dev,
  51. int vf,
  52. struct nlattr *port[]);
  53. int         (*ndo_get_vf_port)(struct net_device *dev,
  54. int vf, struct sk_buff *skb);
  55. int         (*ndo_setup_tc)(struct net_device *dev, u8 tc);
  56. #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
  57. int         (*ndo_fcoe_enable)(struct net_device *dev);
  58. int         (*ndo_fcoe_disable)(struct net_device *dev);
  59. int         (*ndo_fcoe_ddp_setup)(struct net_device *dev,
  60. u16 xid,
  61. struct scatterlist *sgl,
  62. unsigned int sgc);
  63. int         (*ndo_fcoe_ddp_done)(struct net_device *dev,
  64. u16 xid);
  65. int         (*ndo_fcoe_ddp_target)(struct net_device *dev,
  66. u16 xid,
  67. struct scatterlist *sgl,
  68. unsigned int sgc);
  69. #define NETDEV_FCOE_WWNN 0
  70. #define NETDEV_FCOE_WWPN 1
  71. int         (*ndo_fcoe_get_wwn)(struct net_device *dev,
  72. u64 *wwn, int type);
  73. #endif
  74. #ifdef CONFIG_RFS_ACCEL
  75. int         (*ndo_rx_flow_steer)(struct net_device *dev,
  76. const struct sk_buff *skb,
  77. u16 rxq_index,
  78. u32 flow_id);
  79. #endif
  80. int         (*ndo_add_slave)(struct net_device *dev,
  81. struct net_device *slave_dev);
  82. int         (*ndo_del_slave)(struct net_device *dev,
  83. struct net_device *slave_dev);
  84. u32         (*ndo_fix_features)(struct net_device *dev,
  85. u32 features);
  86. int         (*ndo_set_features)(struct net_device *dev,
  87. u32 features);
  88. }

4. Network Drivers

4.1 初始化网络适配器(Network Adapter)

在net_device被激活之前,我们必须找到一个匹配的network adapter。网络驱动(network driver)的初始化函数(init/probe)负责找到一个匹配的network adapter并且使用对应的信息初始化net_device。在驱动的probe函数中,主要完成以下任务:(参考:kernel/drivers/net/pci-skeleton.c)

1) 创建net_device

2) 填充相关的硬件信息

3) 调用register_netdev进行注册

4) 设置net_device->netdev_ops (netdev_ops由驱动实现)

4.2 打开、关闭网络适配器

1) 打开: ifconfig wlan0 up->ioctl->dev_open->net_device.netdev_ops.ndo_open

2) 关闭: ifconfig wlan0 down->ioctl->dev_close->net_device.netdev_ops.ndo_stop

4.3 发送数据

在驱动中实现与ndo_start_xmit对应的函数

4.4 接收数据

其流程如下图所示:

在网络驱动的中断处理函数中,首先调用dev_alloc_skb创建socket buffer,然后把接收到的数据copy到其中,最后调用netif_rx把socket buffer放入队列中,供协议层处理。

int netif_rx(struct sk_buff *skb)  // kernel/net/core/dev.c

5. Data-Link Layer


     1) 逻辑链路控制(LLC)层由Linux内核实现,网络适配器通过net_device连接到操作系统内核。

2) 数据链路层(Data-Link Layer)由LLC和MAC组成。LLC隐藏了所有不同传输介质的差异,从而以上层协议提供统一的接口;而MAC层则反应了不同传输技术(传输协议,如802.3与802.11不同)的差异。

逻辑链路控制 LLC (Logical Link Control)子层
        媒体接入控制 MAC (Medium Access Control)子层
        与接入到传输媒体有关的内容都放在 MAC子层,而LLC 子层则与传输媒体无关,不管采用何种协议的局域网对 LLC 子层来说都是透明的。

5.1 接收网络包流程

5.2 发送网络包流程

Linux--Socket Buffer--Netowrk Devices--Network Drivers相关推荐

  1. linux接收网络数据并存存储,linux网络数据包数据结构 Socket Buffer

    Linux网络核心数据结构是套接字缓存(socket buffer),简称skb.它代表一个要发送或处理的报文,并贯穿于整个协议栈.1.套接字缓存skb由两部分组成:(1)报文数据:它保存了实际在网络 ...

  2. Linux网络协议栈(二)——套接字缓存(socket buffer)

    Linux网络核心数据结构是套接字缓存(socket buffer),简称skb.它代表一个要发送或处理的报文,并贯穿于整个协议栈. 1.    套接字缓存 skb由两部分组成: (1)    报文数 ...

  3. linux下bus、devices和platform的基础模型

    转自:http://blog.chinaunix.net/uid-20672257-id-3147337.html 一.kobject的定义: kobject是Linux2.6引入的设备管理机制,在内 ...

  4. 深入理解Linux socket

    坚持思考,就会很酷 socket fd 长什么样子? 什么是 socket fd ?粗糙的来讲,就是网络 fd,比如我们最常见的 C/S 客户端服务端的编程模式,就是网络通信的一种方式.撇开底层和协议 ...

  5. linux下bus、devices和platform的基础模型 【转】

    转自:http://blog.chinaunix.net/uid-20672257-id-3147337.html 一.kobject的定义: kobject是Linux2.6引入的设备管理机制,在内 ...

  6. Linux Socket详解 大全 基础知识

    1. Socket基础概念: 1.1:形象类比: Socket和电话网络的概念可以做一个很好的类比: Linux 编程中所说的socket就如同一个端点,类比到电话网中,它就如同一个电话机. 而Soc ...

  7. Linux Socket编程

    IP socket 是在其上建立高级Internet 协议的最低级的层:从HTTP到SSL到POP3到Kerberos再到UDP-Time,每种Internet协议都建立在它的基础上.为了实现自定义的 ...

  8. Linux Socket基础介绍

    Linux Socket函数库是从Berkeley大学开发的BSD UNIX系统中移植过来的.BSD Socket接口是众多Unix系统中被广泛支持的TCP/IP通信接口,Linux下的Socket程 ...

  9. linux socket关闭连接 shutdown与close

    在Linux socket关闭连接的方法有两种分别是shutdown和close,首先看一下shutdown的定义 #include<sys/socket.h>int shutdown(i ...

  10. Linux socket关闭连接shutdown与close

    在Linux socket关闭连接的方法有两种分别是shutdown和close,首先看一下shutdown的定义 #include<sys/socket.h> int shutdown( ...

最新文章

  1. 根据json文件读取json信息
  2. [云炬创业管理笔记]第三章测试3
  3. 转:用ASP.NET创建网络相册
  4. 关闭加速渲染_“瀑布屏”旗舰 摩托罗拉Edge+渲染图曝光,Moto G8正式发布
  5. mysql数据表案例_mysql中库和表的简单操作案例
  6. HDU-2057(16进制的输入输出)
  7. 如何在windows上安装和配置php-7.3.5-Win32-VC15-x64
  8. android语言包,安卓系统添加多国语言包
  9. (翻译)简化模式(Reduce)
  10. Java类和对象之对象引用之模拟手机功能
  11. 朋友圈图片评论功能,来了!
  12. SMARTBI权限管理
  13. 网络爬虫——四种思维导图
  14. 300张现场照片,揭秘移动云大会!
  15. 假面舞会狂欢节·圆桌 | 当Thinker遇上Artist
  16. win11更新软件商店
  17. “中国天眼”启动地外文明搜索,真的能找到吗?
  18. 程序员画图利器——Visio
  19. 数据分析六、案例实战---Apr 算法之公众号关联分析
  20. STM32之GPIO_Mode定义和区别

热门文章

  1. entity framework 6 我写了一个公用数据类
  2. Spring JdbcTemplate小结
  3. 软件测试2019:第四次作业
  4. Django 2.2 LTS 发布,长期支持版来了
  5. Netty3 源代码分析 - NIO server绑定过程分析
  6. WebBrowser(超文本浏览框)控件默认使用IE9,IE10的方法
  7. Android 搜索框 search dialog 和 search widget
  8. CoFun 1612 单词分组(容斥)
  9. 通过yumdownloader下载rpm包
  10. Repeater嵌套HyperLink,前台代码中绑定参数