skbuff.h
来自「linux 内核源代码」· C头文件 代码 · 共 1,809 行 · 第 1/4 页
H
1,809 行
int delta = 0; if (headroom < NET_SKB_PAD) headroom = NET_SKB_PAD; if (headroom > skb_headroom(skb)) delta = headroom - skb_headroom(skb); if (delta || cloned) return pskb_expand_head(skb, ALIGN(delta, NET_SKB_PAD), 0, GFP_ATOMIC); return 0;}/** * skb_cow - copy header of skb when it is required * @skb: buffer to cow * @headroom: needed headroom * * If the skb passed lacks sufficient headroom or its data part * is shared, data is reallocated. If reallocation fails, an error * is returned and original skb is not changed. * * The result is skb with writable area skb->head...skb->tail * and at least @headroom of space at head. */static inline int skb_cow(struct sk_buff *skb, unsigned int headroom){ return __skb_cow(skb, headroom, skb_cloned(skb));}/** * skb_cow_head - skb_cow but only making the head writable * @skb: buffer to cow * @headroom: needed headroom * * This function is identical to skb_cow except that we replace the * skb_cloned check by skb_header_cloned. It should be used when * you only need to push on some header and do not need to modify * the data. */static inline int skb_cow_head(struct sk_buff *skb, unsigned int headroom){ return __skb_cow(skb, headroom, skb_header_cloned(skb));}/** * skb_padto - pad an skbuff up to a minimal size * @skb: buffer to pad * @len: minimal length * * Pads up a buffer to ensure the trailing bytes exist and are * blanked. If the buffer already contains sufficient data it * is untouched. Otherwise it is extended. Returns zero on * success. The skb is freed on error. */ static inline int skb_padto(struct sk_buff *skb, unsigned int len){ unsigned int size = skb->len; if (likely(size >= len)) return 0; return skb_pad(skb, len-size);}static inline int skb_add_data(struct sk_buff *skb, char __user *from, int copy){ const int off = skb->len; if (skb->ip_summed == CHECKSUM_NONE) { int err = 0; __wsum csum = csum_and_copy_from_user(from, skb_put(skb, copy), copy, 0, &err); if (!err) { skb->csum = csum_block_add(skb->csum, csum, off); return 0; } } else if (!copy_from_user(skb_put(skb, copy), from, copy)) return 0; __skb_trim(skb, off); return -EFAULT;}static inline int skb_can_coalesce(struct sk_buff *skb, int i, struct page *page, int off){ if (i) { struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i - 1]; return page == frag->page && off == frag->page_offset + frag->size; } return 0;}static inline int __skb_linearize(struct sk_buff *skb){ return __pskb_pull_tail(skb, skb->data_len) ? 0 : -ENOMEM;}/** * skb_linearize - convert paged skb to linear one * @skb: buffer to linarize * * If there is no free memory -ENOMEM is returned, otherwise zero * is returned and the old skb data released. */static inline int skb_linearize(struct sk_buff *skb){ return skb_is_nonlinear(skb) ? __skb_linearize(skb) : 0;}/** * skb_linearize_cow - make sure skb is linear and writable * @skb: buffer to process * * If there is no free memory -ENOMEM is returned, otherwise zero * is returned and the old skb data released. */static inline int skb_linearize_cow(struct sk_buff *skb){ return skb_is_nonlinear(skb) || skb_cloned(skb) ? __skb_linearize(skb) : 0;}/** * skb_postpull_rcsum - update checksum for received skb after pull * @skb: buffer to update * @start: start of data before pull * @len: length of data pulled * * After doing a pull on a received packet, you need to call this to * update the CHECKSUM_COMPLETE checksum, or set ip_summed to * CHECKSUM_NONE so that it can be recomputed from scratch. */static inline void skb_postpull_rcsum(struct sk_buff *skb, const void *start, unsigned int len){ if (skb->ip_summed == CHECKSUM_COMPLETE) skb->csum = csum_sub(skb->csum, csum_partial(start, len, 0));}unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len);/** * pskb_trim_rcsum - trim received skb and update checksum * @skb: buffer to trim * @len: new length * * This is exactly the same as pskb_trim except that it ensures the * checksum of received packets are still valid after the operation. */static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len){ if (likely(len >= skb->len)) return 0; if (skb->ip_summed == CHECKSUM_COMPLETE) skb->ip_summed = CHECKSUM_NONE; return __pskb_trim(skb, len);}#define skb_queue_walk(queue, skb) \ for (skb = (queue)->next; \ prefetch(skb->next), (skb != (struct sk_buff *)(queue)); \ skb = skb->next)#define skb_queue_walk_safe(queue, skb, tmp) \ for (skb = (queue)->next, tmp = skb->next; \ skb != (struct sk_buff *)(queue); \ skb = tmp, tmp = skb->next)#define skb_queue_reverse_walk(queue, skb) \ for (skb = (queue)->prev; \ prefetch(skb->prev), (skb != (struct sk_buff *)(queue)); \ skb = skb->prev)extern struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags, int noblock, int *err);extern unsigned int datagram_poll(struct file *file, struct socket *sock, struct poll_table_struct *wait);extern int skb_copy_datagram_iovec(const struct sk_buff *from, int offset, struct iovec *to, int size);extern int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb, int hlen, struct iovec *iov);extern void skb_free_datagram(struct sock *sk, struct sk_buff *skb);extern void skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags);extern __wsum skb_checksum(const struct sk_buff *skb, int offset, int len, __wsum csum);extern int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len);extern int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len);extern __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, u8 *to, int len, __wsum csum);extern void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to);extern void skb_split(struct sk_buff *skb, struct sk_buff *skb1, const u32 len);extern struct sk_buff *skb_segment(struct sk_buff *skb, int features);static inline void *skb_header_pointer(const struct sk_buff *skb, int offset, int len, void *buffer){ int hlen = skb_headlen(skb); if (hlen - offset >= len) return skb->data + offset; if (skb_copy_bits(skb, offset, buffer, len) < 0) return NULL; return buffer;}static inline void skb_copy_from_linear_data(const struct sk_buff *skb, void *to, const unsigned int len){ memcpy(to, skb->data, len);}static inline void skb_copy_from_linear_data_offset(const struct sk_buff *skb, const int offset, void *to, const unsigned int len){ memcpy(to, skb->data + offset, len);}static inline void skb_copy_to_linear_data(struct sk_buff *skb, const void *from, const unsigned int len){ memcpy(skb->data, from, len);}static inline void skb_copy_to_linear_data_offset(struct sk_buff *skb, const int offset, const void *from, const unsigned int len){ memcpy(skb->data + offset, from, len);}extern void skb_init(void);/** * skb_get_timestamp - get timestamp from a skb * @skb: skb to get stamp from * @stamp: pointer to struct timeval to store stamp in * * Timestamps are stored in the skb as offsets to a base timestamp. * This function converts the offset back to a struct timeval and stores * it in stamp. */static inline void skb_get_timestamp(const struct sk_buff *skb, struct timeval *stamp){ *stamp = ktime_to_timeval(skb->tstamp);}static inline void __net_timestamp(struct sk_buff *skb){ skb->tstamp = ktime_get_real();}static inline ktime_t net_timedelta(ktime_t t){ return ktime_sub(ktime_get_real(), t);}static inline ktime_t net_invalid_timestamp(void){ return ktime_set(0, 0);}extern __sum16 __skb_checksum_complete_head(struct sk_buff *skb, int len);extern __sum16 __skb_checksum_complete(struct sk_buff *skb);static inline int skb_csum_unnecessary(const struct sk_buff *skb){ return skb->ip_summed & CHECKSUM_UNNECESSARY;}/** * skb_checksum_complete - Calculate checksum of an entire packet * @skb: packet to process * * This function calculates the checksum over the entire packet plus * the value of skb->csum. The latter can be used to supply the * checksum of a pseudo header as used by TCP/UDP. It returns the * checksum. * * For protocols that contain complete checksums such as ICMP/TCP/UDP, * this function can be used to verify that checksum on received * packets. In that case the function should return zero if the * checksum is correct. In particular, this function will return zero * if skb->ip_summed is CHECKSUM_UNNECESSARY which indicates that the * hardware has already verified the correctness of the checksum. */static inline __sum16 skb_checksum_complete(struct sk_buff *skb){ return skb_csum_unnecessary(skb) ? 0 : __skb_checksum_complete(skb);}#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)extern void nf_conntrack_destroy(struct nf_conntrack *nfct);static inline void nf_conntrack_put(struct nf_conntrack *nfct){ if (nfct && atomic_dec_and_test(&nfct->use)) nf_conntrack_destroy(nfct);}static inline void nf_conntrack_get(struct nf_conntrack *nfct){ if (nfct) atomic_inc(&nfct->use);}static inline void nf_conntrack_get_reasm(struct sk_buff *skb){ if (skb) atomic_inc(&skb->users);}static inline void nf_conntrack_put_reasm(struct sk_buff *skb){ if (skb) kfree_skb(skb);}#endif#ifdef CONFIG_BRIDGE_NETFILTERstatic inline void nf_bridge_put(struct nf_bridge_info *nf_bridge){ if (nf_bridge && atomic_dec_and_test(&nf_bridge->use)) kfree(nf_bridge);}static inline void nf_bridge_get(struct nf_bridge_info *nf_bridge){ if (nf_bridge) atomic_inc(&nf_bridge->use);}#endif /* CONFIG_BRIDGE_NETFILTER */static inline void nf_reset(struct sk_buff *skb){#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) nf_conntrack_put(skb->nfct); skb->nfct = NULL; nf_conntrack_put_reasm(skb->nfct_reasm); skb->nfct_reasm = NULL;#endif#ifdef CONFIG_BRIDGE_NETFILTER nf_bridge_put(skb->nf_bridge); skb->nf_bridge = NULL;#endif}/* Note: This doesn't put any conntrack and bridge info in dst. */static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src){#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) dst->nfct = src->nfct; nf_conntrack_get(src->nfct); dst->nfctinfo = src->nfctinfo; dst->nfct_reasm = src->nfct_reasm; nf_conntrack_get_reasm(src->nfct_reasm);#endif#ifdef CONFIG_BRIDGE_NETFILTER dst->nf_bridge = src->nf_bridge; nf_bridge_get(src->nf_bridge);#endif}static inline void nf_copy(struct sk_buff *dst, const struct sk_buff *src){#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) nf_conntrack_put(dst->nfct); nf_conntrack_put_reasm(dst->nfct_reasm);#endif#ifdef CONFIG_BRIDGE_NETFILTER nf_bridge_put(dst->nf_bridge);#endif __nf_copy(dst, src);}#ifdef CONFIG_NETWORK_SECMARKstatic inline void skb_copy_secmark(struct sk_buff *to, const struct sk_buff *from){ to->secmark = from->secmark;}static inline void skb_init_secmark(struct sk_buff *skb){ skb->secmark = 0;}#elsestatic inline void skb_copy_secmark(struct sk_buff *to, const struct sk_buff *from){ }static inline void skb_init_secmark(struct sk_buff *skb){ }#endifstatic inline void skb_set_queue_mapping(struct sk_buff *skb, u16 queue_mapping){#ifdef CONFIG_NETDEVICES_MULTIQUEUE skb->queue_mapping = queue_mapping;#endif}static inline u16 skb_get_queue_mapping(struct sk_buff *skb){#ifdef CONFIG_NETDEVICES_MULTIQUEUE return skb->queue_mapping;#else return 0;#endif}static inline void skb_copy_queue_mapping(struct sk_buff *to, const struct sk_buff *from){#ifdef CONFIG_NETDEVICES_MULTIQUEUE to->queue_mapping = from->queue_mapping;#endif}static inline int skb_is_gso(const struct sk_buff *skb){ return skb_shinfo(skb)->gso_size;}static inline int skb_is_gso_v6(const struct sk_buff *skb){ return skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6;}static inline void skb_forward_csum(struct sk_buff *skb){ /* Unfortunately we don't support this one. Any brave souls? */ if (skb->ip_summed == CHECKSUM_COMPLETE) skb->ip_summed = CHECKSUM_NONE;}#endif /* __KERNEL__ */#endif /* _LINUX_SKBUFF_H */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?