diff options
Diffstat (limited to 'net/core/dev.c')
-rw-r--r-- | net/core/dev.c | 63 |
1 files changed, 56 insertions, 7 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index b715a55cccc4..5379b0c1190a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1534,7 +1534,19 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features) | |||
1534 | skb->mac_len = skb->network_header - skb->mac_header; | 1534 | skb->mac_len = skb->network_header - skb->mac_header; |
1535 | __skb_pull(skb, skb->mac_len); | 1535 | __skb_pull(skb, skb->mac_len); |
1536 | 1536 | ||
1537 | if (WARN_ON(skb->ip_summed != CHECKSUM_PARTIAL)) { | 1537 | if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) { |
1538 | struct net_device *dev = skb->dev; | ||
1539 | struct ethtool_drvinfo info = {}; | ||
1540 | |||
1541 | if (dev && dev->ethtool_ops && dev->ethtool_ops->get_drvinfo) | ||
1542 | dev->ethtool_ops->get_drvinfo(dev, &info); | ||
1543 | |||
1544 | WARN(1, "%s: caps=(0x%lx, 0x%lx) len=%d data_len=%d " | ||
1545 | "ip_summed=%d", | ||
1546 | info.driver, dev ? dev->features : 0L, | ||
1547 | skb->sk ? skb->sk->sk_route_caps : 0L, | ||
1548 | skb->len, skb->data_len, skb->ip_summed); | ||
1549 | |||
1538 | if (skb_header_cloned(skb) && | 1550 | if (skb_header_cloned(skb) && |
1539 | (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) | 1551 | (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) |
1540 | return ERR_PTR(err); | 1552 | return ERR_PTR(err); |
@@ -2392,6 +2404,9 @@ int dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb) | |||
2392 | if (!(skb->dev->features & NETIF_F_GRO)) | 2404 | if (!(skb->dev->features & NETIF_F_GRO)) |
2393 | goto normal; | 2405 | goto normal; |
2394 | 2406 | ||
2407 | if (skb_is_gso(skb) || skb_shinfo(skb)->frag_list) | ||
2408 | goto normal; | ||
2409 | |||
2395 | rcu_read_lock(); | 2410 | rcu_read_lock(); |
2396 | list_for_each_entry_rcu(ptype, head, list) { | 2411 | list_for_each_entry_rcu(ptype, head, list) { |
2397 | struct sk_buff *p; | 2412 | struct sk_buff *p; |
@@ -2488,12 +2503,6 @@ EXPORT_SYMBOL(napi_gro_receive); | |||
2488 | 2503 | ||
2489 | void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb) | 2504 | void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb) |
2490 | { | 2505 | { |
2491 | skb_shinfo(skb)->nr_frags = 0; | ||
2492 | |||
2493 | skb->len -= skb->data_len; | ||
2494 | skb->truesize -= skb->data_len; | ||
2495 | skb->data_len = 0; | ||
2496 | |||
2497 | __skb_pull(skb, skb_headlen(skb)); | 2506 | __skb_pull(skb, skb_headlen(skb)); |
2498 | skb_reserve(skb, NET_IP_ALIGN - skb_headroom(skb)); | 2507 | skb_reserve(skb, NET_IP_ALIGN - skb_headroom(skb)); |
2499 | 2508 | ||
@@ -2527,6 +2536,7 @@ struct sk_buff *napi_fraginfo_skb(struct napi_struct *napi, | |||
2527 | 2536 | ||
2528 | if (!pskb_may_pull(skb, ETH_HLEN)) { | 2537 | if (!pskb_may_pull(skb, ETH_HLEN)) { |
2529 | napi_reuse_skb(napi, skb); | 2538 | napi_reuse_skb(napi, skb); |
2539 | skb = NULL; | ||
2530 | goto out; | 2540 | goto out; |
2531 | } | 2541 | } |
2532 | 2542 | ||
@@ -4434,6 +4444,45 @@ err_uninit: | |||
4434 | } | 4444 | } |
4435 | 4445 | ||
4436 | /** | 4446 | /** |
4447 | * init_dummy_netdev - init a dummy network device for NAPI | ||
4448 | * @dev: device to init | ||
4449 | * | ||
4450 | * This takes a network device structure and initialize the minimum | ||
4451 | * amount of fields so it can be used to schedule NAPI polls without | ||
4452 | * registering a full blown interface. This is to be used by drivers | ||
4453 | * that need to tie several hardware interfaces to a single NAPI | ||
4454 | * poll scheduler due to HW limitations. | ||
4455 | */ | ||
4456 | int init_dummy_netdev(struct net_device *dev) | ||
4457 | { | ||
4458 | /* Clear everything. Note we don't initialize spinlocks | ||
4459 | * are they aren't supposed to be taken by any of the | ||
4460 | * NAPI code and this dummy netdev is supposed to be | ||
4461 | * only ever used for NAPI polls | ||
4462 | */ | ||
4463 | memset(dev, 0, sizeof(struct net_device)); | ||
4464 | |||
4465 | /* make sure we BUG if trying to hit standard | ||
4466 | * register/unregister code path | ||
4467 | */ | ||
4468 | dev->reg_state = NETREG_DUMMY; | ||
4469 | |||
4470 | /* initialize the ref count */ | ||
4471 | atomic_set(&dev->refcnt, 1); | ||
4472 | |||
4473 | /* NAPI wants this */ | ||
4474 | INIT_LIST_HEAD(&dev->napi_list); | ||
4475 | |||
4476 | /* a dummy interface is started by default */ | ||
4477 | set_bit(__LINK_STATE_PRESENT, &dev->state); | ||
4478 | set_bit(__LINK_STATE_START, &dev->state); | ||
4479 | |||
4480 | return 0; | ||
4481 | } | ||
4482 | EXPORT_SYMBOL_GPL(init_dummy_netdev); | ||
4483 | |||
4484 | |||
4485 | /** | ||
4437 | * register_netdev - register a network device | 4486 | * register_netdev - register a network device |
4438 | * @dev: device to register | 4487 | * @dev: device to register |
4439 | * | 4488 | * |