struct sk_buff {union {struct { /* These two members must be first. 构成sk_buff链表*/struct sk_buff *next;struct sk_buff *prev;union {struct net_device *dev; //网络设备对应的结构体,很重要但是不是本文重点,所以不做展开 /* Some protocols might use this space to store information, * while device pointer would be NULL. * UDP receive path is one user. */unsignedlong dev_scratch; // 对于某些不适用net_device的协议需要采用该字段存储信息,如UDP的接收路径 }; };struct rb_node rbnode; /* used in netem, ip4 defrag, and tcp stack 将sk_buff以红黑树组织,在TCP中有用到*/struct list_head list; // sk_buff链表头指针 };union {struct sock *sk; // 指向网络层套接字结构体int ip_defrag_offset; };union {ktime_t tstamp; // 时间戳 u64 skb_mstamp_ns; /* earliest departure time */ }; /* 存储私有信息 * 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[48] __aligned(8);union {struct {unsignedlong _skb_refdst; // 目标entryvoid (*destructor)(struct sk_buff *skb); // 析构函数 };struct list_head tcp_tsorted_anchor; // TCP发送队列(tp->tsorted_sent_queue) };....unsignedint len, // 实际长度 data_len; // 数据长度 __u16 mac_len, // mac层长度 hdr_len; // 可写头部长度 /* Following fields are _not_ copied in __copy_skb_header() * Note that queue_mapping is here mostly to fill a hole. */ __u16 queue_mapping; // 多队列设备的队列映射...... /* fields enclosed in headers_start/headers_end are copied * using a single memcpy() in __copy_skb_header() */ /* private: */ __u32 headers_start[0]; /* public: */...... __u8 __pkt_type_offset[0]; __u8 pkt_type:3; __u8 ignore_df:1; __u8 nf_trace:1; __u8 ip_summed:2; __u8 ooo_okay:1; __u8 l4_hash:1; __u8 sw_hash:1; __u8 wifi_acked_valid:1; __u8 wifi_acked:1; __u8 no_fcs:1; /* Indicates the inner headers are valid in the skbuff. */ __u8 encapsulation:1; __u8 encap_hdr_csum:1; __u8 csum_valid:1;...... __u8 __pkt_vlan_present_offset[0]; __u8 vlan_present:1; __u8 csum_complete_sw:1; __u8 csum_level:2; __u8 csum_not_inet:1; __u8 dst_pending_confirm:1;...... __u8 ipvs_property:1; __u8 inner_protocol_type:1; __u8 remcsum_offload:1;......union { __wsum csum;struct { __u16 csum_start; __u16 csum_offset; }; }; __u32 priority;int skb_iif; // 接收到该数据包的网络接口的编号 __u32 hash; __be16 vlan_proto; __u16 vlan_tci;......union { __u32 mark; __u32 reserved_tailroom; };union { __be16 inner_protocol; __u8 inner_ipproto; }; __u16 inner_transport_header; __u16 inner_network_header; __u16 inner_mac_header; __be16 protocol; __u16 transport_header; // 传输层头部 __u16 network_header; // 网络层头部 __u16 mac_header; // mac层头部 /* private: */ __u32 headers_end[0]; /* public: */ /* These elements must be at the end, see alloc_skb() for details. */sk_buff_data_t tail;sk_buff_data_t end;unsignedchar*head,*data;unsignedint truesize;refcount_t users;......};
intsock_create(int family,int type,int protocol,struct socket **res){return__sock_create(current->nsproxy->net_ns, family, type, protocol, res,0);}int__sock_create(struct net *net,int family,int type,int protocol,struct socket **res,int kern){int err;struct socket *sock;conststruct net_proto_family *pf;...... /* * Allocate the socket and allow the family to set things up. if * the protocol is 0, the family is instructed to select an appropriate * default. */ sock =sock_alloc();......sock->type = type;......rcu_read_lock(); pf =rcu_dereference(net_families[family]);...... err =pf->create(net, sock, protocol, kern);......*res = sock;return0;......}//net/ipv4/af_inet.cstatic conststruct net_proto_family inet_family_ops = { .family = PF_INET, .create = inet_create,//这个用于socket系统调用创建 ......}