aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netdevice.h11
-rw-r--r--net/core/dev.c21
-rw-r--r--net/openvswitch/datapath.c2
3 files changed, 26 insertions, 8 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 85b0949d9946..ab2774eb49e8 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2662,8 +2662,15 @@ extern int netdev_master_upper_dev_link(struct net_device *dev,
2662extern void netdev_upper_dev_unlink(struct net_device *dev, 2662extern void netdev_upper_dev_unlink(struct net_device *dev,
2663 struct net_device *upper_dev); 2663 struct net_device *upper_dev);
2664extern int skb_checksum_help(struct sk_buff *skb); 2664extern int skb_checksum_help(struct sk_buff *skb);
2665extern struct sk_buff *skb_gso_segment(struct sk_buff *skb, 2665extern struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
2666 netdev_features_t features); 2666 netdev_features_t features, bool tx_path);
2667
2668static inline
2669struct sk_buff *skb_gso_segment(struct sk_buff *skb, netdev_features_t features)
2670{
2671 return __skb_gso_segment(skb, features, true);
2672}
2673
2667#ifdef CONFIG_BUG 2674#ifdef CONFIG_BUG
2668extern void netdev_rx_csum_fault(struct net_device *dev); 2675extern void netdev_rx_csum_fault(struct net_device *dev);
2669#else 2676#else
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
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index d8c13a965459..9dc537df46c4 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -301,7 +301,7 @@ static int queue_gso_packets(struct net *net, int dp_ifindex,
301 struct sk_buff *segs, *nskb; 301 struct sk_buff *segs, *nskb;
302 int err; 302 int err;
303 303
304 segs = skb_gso_segment(skb, NETIF_F_SG | NETIF_F_HW_CSUM); 304 segs = __skb_gso_segment(skb, NETIF_F_SG | NETIF_F_HW_CSUM, false);
305 if (IS_ERR(segs)) 305 if (IS_ERR(segs))
306 return PTR_ERR(segs); 306 return PTR_ERR(segs);
307 307