all the inner header fields are valid only if the 'encaspulation' flag is set, and the relevant fields are always initialized when the field is set: we don't need to initialize them at skb allocation time Signed-off-by: Paolo Abeni <pabeni@xxxxxxxxxx> --- v1 -> v2: - add CHECK_SKB_FIELD(__encapsulation_offset) in __copy_skb_header --- include/linux/skbuff.h | 31 ++++++++++++++++++++++--------- net/core/skbuff.c | 6 ++---- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index ea9fdcc7c7ca..a3e756575aa7 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -822,6 +822,9 @@ struct sk_buff { __u8 ip_summed:2; __u8 ooo_okay:1; + /* private: */ + __u8 __pkt_encapsulation_offset[0]; + /* public: */ __u8 l4_hash:1; __u8 sw_hash:1; __u8 wifi_acked_valid:1; @@ -911,15 +914,6 @@ struct sk_buff { __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; @@ -948,6 +942,19 @@ struct sk_buff { #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) unsigned long _nfct; #endif + union { + struct { + union { + __be16 inner_protocol; + __u8 inner_ipproto; + }; + + __u16 inner_transport_header; + __u16 inner_network_header; + __u16 inner_mac_header; + }; + __u64 inner_headers; + }; }; #ifdef __KERNEL__ @@ -2449,6 +2456,12 @@ static inline void skb_tailroom_reserve(struct sk_buff *skb, unsigned int mtu, #define ENCAP_TYPE_ETHER 0 #define ENCAP_TYPE_IPPROTO 1 +static inline void __skb_copy_inner_headers(struct sk_buff *dst, const struct sk_buff *src) +{ + if (src->encapsulation) + dst->inner_headers = src->inner_headers; +} + static inline void skb_set_inner_protocol(struct sk_buff *skb, __be16 protocol) { diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 9ed754da6e13..53b8db10e567 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -995,6 +995,7 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old) skb_dst_copy(new, old); __skb_ext_copy(new, old); __nf_copy(new, old, false); + __skb_copy_inner_headers(new, old); /* Note : this field could be in headers_start/headers_end section * It is not yet because we do not want to have a 16 bit hole @@ -1005,6 +1006,7 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old) offsetof(struct sk_buff, headers_end) - offsetof(struct sk_buff, headers_start)); CHECK_SKB_FIELD(_state); + CHECK_SKB_FIELD(__pkt_encapsulation_offset); CHECK_SKB_FIELD(protocol); CHECK_SKB_FIELD(csum); CHECK_SKB_FIELD(hash); @@ -1015,10 +1017,6 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old) CHECK_SKB_FIELD(transport_header); CHECK_SKB_FIELD(network_header); CHECK_SKB_FIELD(mac_header); - CHECK_SKB_FIELD(inner_protocol); - CHECK_SKB_FIELD(inner_transport_header); - CHECK_SKB_FIELD(inner_network_header); - CHECK_SKB_FIELD(inner_mac_header); CHECK_SKB_FIELD(mark); #ifdef CONFIG_NETWORK_SECMARK CHECK_SKB_FIELD(secmark); -- 2.26.3