aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/skbuff.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/skbuff.h')
-rw-r--r--include/linux/skbuff.h83
1 files changed, 72 insertions, 11 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 124f90cd5a38..7cdfb4d52847 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -187,7 +187,6 @@ union skb_shared_tx {
187 * the end of the header data, ie. at skb->end. 187 * the end of the header data, ie. at skb->end.
188 */ 188 */
189struct skb_shared_info { 189struct skb_shared_info {
190 atomic_t dataref;
191 unsigned short nr_frags; 190 unsigned short nr_frags;
192 unsigned short gso_size; 191 unsigned short gso_size;
193 /* Warning: this field is not always filled in (UFO)! */ 192 /* Warning: this field is not always filled in (UFO)! */
@@ -197,6 +196,12 @@ struct skb_shared_info {
197 union skb_shared_tx tx_flags; 196 union skb_shared_tx tx_flags;
198 struct sk_buff *frag_list; 197 struct sk_buff *frag_list;
199 struct skb_shared_hwtstamps hwtstamps; 198 struct skb_shared_hwtstamps hwtstamps;
199
200 /*
201 * Warning : all fields before dataref are cleared in __alloc_skb()
202 */
203 atomic_t dataref;
204
200 skb_frag_t frags[MAX_SKB_FRAGS]; 205 skb_frag_t frags[MAX_SKB_FRAGS];
201 /* Intermediate layers must ensure that destructor_arg 206 /* Intermediate layers must ensure that destructor_arg
202 * remains valid until skb destructor */ 207 * remains valid until skb destructor */
@@ -259,7 +264,7 @@ typedef unsigned char *sk_buff_data_t;
259 * @transport_header: Transport layer header 264 * @transport_header: Transport layer header
260 * @network_header: Network layer header 265 * @network_header: Network layer header
261 * @mac_header: Link layer header 266 * @mac_header: Link layer header
262 * @_skb_dst: destination entry 267 * @_skb_refdst: destination entry (with norefcount bit)
263 * @sp: the security path, used for xfrm 268 * @sp: the security path, used for xfrm
264 * @cb: Control buffer. Free for use by every layer. Put private vars here 269 * @cb: Control buffer. Free for use by every layer. Put private vars here
265 * @len: Length of actual data 270 * @len: Length of actual data
@@ -294,6 +299,7 @@ typedef unsigned char *sk_buff_data_t;
294 * @nfct_reasm: netfilter conntrack re-assembly pointer 299 * @nfct_reasm: netfilter conntrack re-assembly pointer
295 * @nf_bridge: Saved data about a bridged frame - see br_netfilter.c 300 * @nf_bridge: Saved data about a bridged frame - see br_netfilter.c
296 * @skb_iif: ifindex of device we arrived on 301 * @skb_iif: ifindex of device we arrived on
302 * @rxhash: the packet hash computed on receive
297 * @queue_mapping: Queue mapping for multiqueue devices 303 * @queue_mapping: Queue mapping for multiqueue devices
298 * @tc_index: Traffic control index 304 * @tc_index: Traffic control index
299 * @tc_verd: traffic control verdict 305 * @tc_verd: traffic control verdict
@@ -322,7 +328,7 @@ struct sk_buff {
322 */ 328 */
323 char cb[48] __aligned(8); 329 char cb[48] __aligned(8);
324 330
325 unsigned long _skb_dst; 331 unsigned long _skb_refdst;
326#ifdef CONFIG_XFRM 332#ifdef CONFIG_XFRM
327 struct sec_path *sp; 333 struct sec_path *sp;
328#endif 334#endif
@@ -369,6 +375,8 @@ struct sk_buff {
369#endif 375#endif
370#endif 376#endif
371 377
378 __u32 rxhash;
379
372 kmemcheck_bitfield_begin(flags2); 380 kmemcheck_bitfield_begin(flags2);
373 __u16 queue_mapping:16; 381 __u16 queue_mapping:16;
374#ifdef CONFIG_IPV6_NDISC_NODETYPE 382#ifdef CONFIG_IPV6_NDISC_NODETYPE
@@ -411,14 +419,64 @@ struct sk_buff {
411 419
412#include <asm/system.h> 420#include <asm/system.h>
413 421
422/*
423 * skb might have a dst pointer attached, refcounted or not.
424 * _skb_refdst low order bit is set if refcount was _not_ taken
425 */
426#define SKB_DST_NOREF 1UL
427#define SKB_DST_PTRMASK ~(SKB_DST_NOREF)
428
429/**
430 * skb_dst - returns skb dst_entry
431 * @skb: buffer
432 *
433 * Returns skb dst_entry, regardless of reference taken or not.
434 */
414static inline struct dst_entry *skb_dst(const struct sk_buff *skb) 435static inline struct dst_entry *skb_dst(const struct sk_buff *skb)
415{ 436{
416 return (struct dst_entry *)skb->_skb_dst; 437 /* If refdst was not refcounted, check we still are in a
438 * rcu_read_lock section
439 */
440 WARN_ON((skb->_skb_refdst & SKB_DST_NOREF) &&
441 !rcu_read_lock_held() &&
442 !rcu_read_lock_bh_held());
443 return (struct dst_entry *)(skb->_skb_refdst & SKB_DST_PTRMASK);
417} 444}
418 445
446/**
447 * skb_dst_set - sets skb dst
448 * @skb: buffer
449 * @dst: dst entry
450 *
451 * Sets skb dst, assuming a reference was taken on dst and should
452 * be released by skb_dst_drop()
453 */
419static inline void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst) 454static inline void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst)
420{ 455{
421 skb->_skb_dst = (unsigned long)dst; 456 skb->_skb_refdst = (unsigned long)dst;
457}
458
459/**
460 * skb_dst_set_noref - sets skb dst, without a reference
461 * @skb: buffer
462 * @dst: dst entry
463 *
464 * Sets skb dst, assuming a reference was not taken on dst
465 * skb_dst_drop() should not dst_release() this dst
466 */
467static inline void skb_dst_set_noref(struct sk_buff *skb, struct dst_entry *dst)
468{
469 WARN_ON(!rcu_read_lock_held() && !rcu_read_lock_bh_held());
470 skb->_skb_refdst = (unsigned long)dst | SKB_DST_NOREF;
471}
472
473/**
474 * skb_dst_is_noref - Test if skb dst isnt refcounted
475 * @skb: buffer
476 */
477static inline bool skb_dst_is_noref(const struct sk_buff *skb)
478{
479 return (skb->_skb_refdst & SKB_DST_NOREF) && skb_dst(skb);
422} 480}
423 481
424static inline struct rtable *skb_rtable(const struct sk_buff *skb) 482static inline struct rtable *skb_rtable(const struct sk_buff *skb)
@@ -467,11 +525,6 @@ extern int skb_cow_data(struct sk_buff *skb, int tailbits,
467 struct sk_buff **trailer); 525 struct sk_buff **trailer);
468extern int skb_pad(struct sk_buff *skb, int pad); 526extern int skb_pad(struct sk_buff *skb, int pad);
469#define dev_kfree_skb(a) consume_skb(a) 527#define dev_kfree_skb(a) consume_skb(a)
470#define dev_consume_skb(a) kfree_skb_clean(a)
471extern void skb_over_panic(struct sk_buff *skb, int len,
472 void *here);
473extern void skb_under_panic(struct sk_buff *skb, int len,
474 void *here);
475 528
476extern int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb, 529extern int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,
477 int getfrag(void *from, char *to, int offset, 530 int getfrag(void *from, char *to, int offset,
@@ -1130,6 +1183,11 @@ static inline unsigned char *__skb_pull(struct sk_buff *skb, unsigned int len)
1130 return skb->data += len; 1183 return skb->data += len;
1131} 1184}
1132 1185
1186static inline unsigned char *skb_pull_inline(struct sk_buff *skb, unsigned int len)
1187{
1188 return unlikely(len > skb->len) ? NULL : __skb_pull(skb, len);
1189}
1190
1133extern unsigned char *__pskb_pull_tail(struct sk_buff *skb, int delta); 1191extern unsigned char *__pskb_pull_tail(struct sk_buff *skb, int delta);
1134 1192
1135static inline unsigned char *__pskb_pull(struct sk_buff *skb, unsigned int len) 1193static inline unsigned char *__pskb_pull(struct sk_buff *skb, unsigned int len)
@@ -1353,9 +1411,12 @@ static inline int skb_network_offset(const struct sk_buff *skb)
1353 * 1411 *
1354 * Various parts of the networking layer expect at least 32 bytes of 1412 * Various parts of the networking layer expect at least 32 bytes of
1355 * headroom, you should not reduce this. 1413 * headroom, you should not reduce this.
1414 * With RPS, we raised NET_SKB_PAD to 64 so that get_rps_cpus() fetches span
1415 * a 64 bytes aligned block to fit modern (>= 64 bytes) cache line sizes
1416 * NET_IP_ALIGN(2) + ethernet_header(14) + IP_header(20/40) + ports(8)
1356 */ 1417 */
1357#ifndef NET_SKB_PAD 1418#ifndef NET_SKB_PAD
1358#define NET_SKB_PAD 32 1419#define NET_SKB_PAD 64
1359#endif 1420#endif
1360 1421
1361extern int ___pskb_trim(struct sk_buff *skb, unsigned int len); 1422extern int ___pskb_trim(struct sk_buff *skb, unsigned int len);