aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/dev.c
diff options
context:
space:
mode:
authorCong Wang <amwang@redhat.com>2013-02-05 11:36:38 -0500
committerDavid S. Miller <davem@davemloft.net>2013-02-06 15:58:00 -0500
commit12b0004d1d1e2a9aa667412d479041e403bcafae (patch)
tree132aecb3e4a78707552a0ddf4d4618734af47efa /net/core/dev.c
parent25060d8f3f2c21daadb4fc1fb0e37ce2c992e30b (diff)
net: adjust skb_gso_segment() for calling in rx path
skb_gso_segment() is almost always called in tx path, except for openvswitch. It calls this function when it receives the packet and tries to queue it to user-space. In this special case, the ->ip_summed check inside skb_gso_segment() is no longer true, as ->ip_summed value has different meanings on rx path. This patch adjusts skb_gso_segment() so that we can at least avoid such warnings on checksum. Cc: Jesse Gross <jesse@nicira.com> Cc: David S. Miller <davem@davemloft.net> Signed-off-by: Cong Wang <amwang@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/dev.c')
-rw-r--r--net/core/dev.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 2b275a7b8677..65da698c500b 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2327,18 +2327,29 @@ out:
2327} 2327}
2328EXPORT_SYMBOL(skb_checksum_help); 2328EXPORT_SYMBOL(skb_checksum_help);
2329 2329
2330/* openvswitch calls this on rx path, so we need a different check.
2331 */
2332static inline bool skb_needs_check(struct sk_buff *skb, bool tx_path)
2333{
2334 if (tx_path)
2335 return skb->ip_summed != CHECKSUM_PARTIAL;
2336 else
2337 return skb->ip_summed == CHECKSUM_NONE;
2338}
2339
2330/** 2340/**
2331 * skb_gso_segment - Perform segmentation on skb. 2341 * __skb_gso_segment - Perform segmentation on skb.
2332 * @skb: buffer to segment 2342 * @skb: buffer to segment
2333 * @features: features for the output path (see dev->features) 2343 * @features: features for the output path (see dev->features)
2344 * @tx_path: whether it is called in TX path
2334 * 2345 *
2335 * This function segments the given skb and returns a list of segments. 2346 * This function segments the given skb and returns a list of segments.
2336 * 2347 *
2337 * It may return NULL if the skb requires no segmentation. This is 2348 * It may return NULL if the skb requires no segmentation. This is
2338 * only possible when GSO is used for verifying header integrity. 2349 * only possible when GSO is used for verifying header integrity.
2339 */ 2350 */
2340struct sk_buff *skb_gso_segment(struct sk_buff *skb, 2351struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
2341 netdev_features_t features) 2352 netdev_features_t features, bool tx_path)
2342{ 2353{
2343 struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT); 2354 struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
2344 struct packet_offload *ptype; 2355 struct packet_offload *ptype;
@@ -2361,7 +2372,7 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb,
2361 skb->mac_len = skb->network_header - skb->mac_header; 2372 skb->mac_len = skb->network_header - skb->mac_header;
2362 __skb_pull(skb, skb->mac_len); 2373 __skb_pull(skb, skb->mac_len);
2363 2374
2364 if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) { 2375 if (unlikely(skb_needs_check(skb, tx_path))) {
2365 skb_warn_bad_offload(skb); 2376 skb_warn_bad_offload(skb);
2366 2377
2367 if (skb_header_cloned(skb) && 2378 if (skb_header_cloned(skb) &&
@@ -2390,7 +2401,7 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb,
2390 2401
2391 return segs; 2402 return segs;
2392} 2403}
2393EXPORT_SYMBOL(skb_gso_segment); 2404EXPORT_SYMBOL(__skb_gso_segment);
2394 2405
2395/* Take action when hardware reception checksum errors are detected. */ 2406/* Take action when hardware reception checksum errors are detected. */
2396#ifdef CONFIG_BUG 2407#ifdef CONFIG_BUG