diff options
Diffstat (limited to 'include/linux/netdevice.h')
-rw-r--r-- | include/linux/netdevice.h | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 586b71f0358c..61890ed0bcf2 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -1008,6 +1008,9 @@ void netif_napi_add(struct net_device *dev, struct napi_struct *napi, | |||
1008 | void netif_napi_del(struct napi_struct *napi); | 1008 | void netif_napi_del(struct napi_struct *napi); |
1009 | 1009 | ||
1010 | struct napi_gro_cb { | 1010 | struct napi_gro_cb { |
1011 | /* Virtual address of skb_shinfo(skb)->frags[0].page + offset. */ | ||
1012 | void *frag0; | ||
1013 | |||
1011 | /* This indicates where we are processing relative to skb->data. */ | 1014 | /* This indicates where we are processing relative to skb->data. */ |
1012 | int data_offset; | 1015 | int data_offset; |
1013 | 1016 | ||
@@ -1107,9 +1110,9 @@ extern int dev_restart(struct net_device *dev); | |||
1107 | #ifdef CONFIG_NETPOLL_TRAP | 1110 | #ifdef CONFIG_NETPOLL_TRAP |
1108 | extern int netpoll_trap(void); | 1111 | extern int netpoll_trap(void); |
1109 | #endif | 1112 | #endif |
1110 | extern void *skb_gro_header(struct sk_buff *skb, unsigned int hlen); | ||
1111 | extern int skb_gro_receive(struct sk_buff **head, | 1113 | extern int skb_gro_receive(struct sk_buff **head, |
1112 | struct sk_buff *skb); | 1114 | struct sk_buff *skb); |
1115 | extern void skb_gro_reset_offset(struct sk_buff *skb); | ||
1113 | 1116 | ||
1114 | static inline unsigned int skb_gro_offset(const struct sk_buff *skb) | 1117 | static inline unsigned int skb_gro_offset(const struct sk_buff *skb) |
1115 | { | 1118 | { |
@@ -1126,23 +1129,28 @@ static inline void skb_gro_pull(struct sk_buff *skb, unsigned int len) | |||
1126 | NAPI_GRO_CB(skb)->data_offset += len; | 1129 | NAPI_GRO_CB(skb)->data_offset += len; |
1127 | } | 1130 | } |
1128 | 1131 | ||
1129 | static inline void skb_gro_reset_offset(struct sk_buff *skb) | 1132 | static inline void *skb_gro_header(struct sk_buff *skb, unsigned int hlen) |
1130 | { | 1133 | { |
1131 | NAPI_GRO_CB(skb)->data_offset = 0; | 1134 | unsigned int offset = skb_gro_offset(skb); |
1135 | |||
1136 | hlen += offset; | ||
1137 | if (!NAPI_GRO_CB(skb)->frag0 || | ||
1138 | unlikely(skb_shinfo(skb)->frags[0].size + skb_headlen(skb) < hlen)) | ||
1139 | return pskb_may_pull(skb, hlen) ? skb->data + offset : NULL; | ||
1140 | |||
1141 | return NAPI_GRO_CB(skb)->frag0 + offset; | ||
1132 | } | 1142 | } |
1133 | 1143 | ||
1134 | static inline void *skb_gro_mac_header(struct sk_buff *skb) | 1144 | static inline void *skb_gro_mac_header(struct sk_buff *skb) |
1135 | { | 1145 | { |
1136 | return skb_headlen(skb) ? skb_mac_header(skb) : | 1146 | return skb_headlen(skb) ? skb_mac_header(skb) : |
1137 | page_address(skb_shinfo(skb)->frags[0].page) + | 1147 | NAPI_GRO_CB(skb)->frag0; |
1138 | skb_shinfo(skb)->frags[0].page_offset; | ||
1139 | } | 1148 | } |
1140 | 1149 | ||
1141 | static inline void *skb_gro_network_header(struct sk_buff *skb) | 1150 | static inline void *skb_gro_network_header(struct sk_buff *skb) |
1142 | { | 1151 | { |
1143 | return skb_headlen(skb) ? skb_network_header(skb) : | 1152 | return skb_headlen(skb) ? skb_network_header(skb) : |
1144 | page_address(skb_shinfo(skb)->frags[0].page) + | 1153 | NAPI_GRO_CB(skb)->frag0 + skb_network_offset(skb); |
1145 | skb_shinfo(skb)->frags[0].page_offset + skb_network_offset(skb); | ||
1146 | } | 1154 | } |
1147 | 1155 | ||
1148 | static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev, | 1156 | static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev, |