diff options
| author | Herbert Xu <herbert@gondor.apana.org.au> | 2009-01-06 13:49:34 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2009-01-06 13:49:34 -0500 |
| commit | 96e93eab20337d063c70d537bd7bc70d90e04fa3 (patch) | |
| tree | 6b50a8d19e6c4d99f035dbede3b7836eed5a7d44 /net/core | |
| parent | ff5bfc3584efdadf826a21bc76ef42bdfcf3f612 (diff) | |
gro: Add internal interfaces for VLAN
Previously GRO's only entry point from the outside is through
napi_gro_receive and napi_gro_frags. These interfaces are for
device drivers.
This patch rearranges things to provide a new set of interfaces
for VLANs. These interfaces are for internal use only. The
VLAN code itself can then provide a set of entry points for
device drivers.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
| -rw-r--r-- | net/core/dev.c | 82 |
1 files changed, 59 insertions, 23 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 382df6c09eec..bab8bcedd62e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -2387,7 +2387,7 @@ void napi_gro_flush(struct napi_struct *napi) | |||
| 2387 | } | 2387 | } |
| 2388 | EXPORT_SYMBOL(napi_gro_flush); | 2388 | EXPORT_SYMBOL(napi_gro_flush); |
| 2389 | 2389 | ||
| 2390 | static int __napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) | 2390 | int dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb) |
| 2391 | { | 2391 | { |
| 2392 | struct sk_buff **pp = NULL; | 2392 | struct sk_buff **pp = NULL; |
| 2393 | struct packet_type *ptype; | 2393 | struct packet_type *ptype; |
| @@ -2417,11 +2417,14 @@ static int __napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) | |||
| 2417 | 2417 | ||
| 2418 | for (p = napi->gro_list; p; p = p->next) { | 2418 | for (p = napi->gro_list; p; p = p->next) { |
| 2419 | count++; | 2419 | count++; |
| 2420 | NAPI_GRO_CB(p)->same_flow = | 2420 | |
| 2421 | p->mac_len == mac_len && | 2421 | if (!NAPI_GRO_CB(p)->same_flow) |
| 2422 | !memcmp(skb_mac_header(p), skb_mac_header(skb), | 2422 | continue; |
| 2423 | mac_len); | 2423 | |
| 2424 | NAPI_GRO_CB(p)->flush = 0; | 2424 | if (p->mac_len != mac_len || |
| 2425 | memcmp(skb_mac_header(p), skb_mac_header(skb), | ||
| 2426 | mac_len)) | ||
| 2427 | NAPI_GRO_CB(p)->same_flow = 0; | ||
| 2425 | } | 2428 | } |
| 2426 | 2429 | ||
| 2427 | pp = ptype->gro_receive(&napi->gro_list, skb); | 2430 | pp = ptype->gro_receive(&napi->gro_list, skb); |
| @@ -2463,6 +2466,19 @@ ok: | |||
| 2463 | normal: | 2466 | normal: |
| 2464 | return -1; | 2467 | return -1; |
| 2465 | } | 2468 | } |
| 2469 | EXPORT_SYMBOL(dev_gro_receive); | ||
| 2470 | |||
| 2471 | static int __napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) | ||
| 2472 | { | ||
| 2473 | struct sk_buff *p; | ||
| 2474 | |||
| 2475 | for (p = napi->gro_list; p; p = p->next) { | ||
| 2476 | NAPI_GRO_CB(p)->same_flow = 1; | ||
| 2477 | NAPI_GRO_CB(p)->flush = 0; | ||
| 2478 | } | ||
| 2479 | |||
| 2480 | return dev_gro_receive(napi, skb); | ||
| 2481 | } | ||
| 2466 | 2482 | ||
| 2467 | int napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) | 2483 | int napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) |
| 2468 | { | 2484 | { |
| @@ -2479,11 +2495,26 @@ int napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) | |||
| 2479 | } | 2495 | } |
| 2480 | EXPORT_SYMBOL(napi_gro_receive); | 2496 | EXPORT_SYMBOL(napi_gro_receive); |
| 2481 | 2497 | ||
| 2482 | int napi_gro_frags(struct napi_struct *napi, struct napi_gro_fraginfo *info) | 2498 | void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb) |
| 2499 | { | ||
| 2500 | skb_shinfo(skb)->nr_frags = 0; | ||
| 2501 | |||
| 2502 | skb->len -= skb->data_len; | ||
| 2503 | skb->truesize -= skb->data_len; | ||
| 2504 | skb->data_len = 0; | ||
| 2505 | |||
| 2506 | __skb_pull(skb, skb_headlen(skb)); | ||
| 2507 | skb_reserve(skb, NET_IP_ALIGN - skb_headroom(skb)); | ||
| 2508 | |||
| 2509 | napi->skb = skb; | ||
| 2510 | } | ||
| 2511 | EXPORT_SYMBOL(napi_reuse_skb); | ||
| 2512 | |||
| 2513 | struct sk_buff *napi_fraginfo_skb(struct napi_struct *napi, | ||
| 2514 | struct napi_gro_fraginfo *info) | ||
| 2483 | { | 2515 | { |
| 2484 | struct net_device *dev = napi->dev; | 2516 | struct net_device *dev = napi->dev; |
| 2485 | struct sk_buff *skb = napi->skb; | 2517 | struct sk_buff *skb = napi->skb; |
| 2486 | int err = NET_RX_DROP; | ||
| 2487 | 2518 | ||
| 2488 | napi->skb = NULL; | 2519 | napi->skb = NULL; |
| 2489 | 2520 | ||
| @@ -2503,16 +2534,31 @@ int napi_gro_frags(struct napi_struct *napi, struct napi_gro_fraginfo *info) | |||
| 2503 | skb->len += info->len; | 2534 | skb->len += info->len; |
| 2504 | skb->truesize += info->len; | 2535 | skb->truesize += info->len; |
| 2505 | 2536 | ||
| 2506 | if (!pskb_may_pull(skb, ETH_HLEN)) | 2537 | if (!pskb_may_pull(skb, ETH_HLEN)) { |
| 2507 | goto reuse; | 2538 | napi_reuse_skb(napi, skb); |
| 2508 | 2539 | goto out; | |
| 2509 | err = NET_RX_SUCCESS; | 2540 | } |
| 2510 | 2541 | ||
| 2511 | skb->protocol = eth_type_trans(skb, dev); | 2542 | skb->protocol = eth_type_trans(skb, dev); |
| 2512 | 2543 | ||
| 2513 | skb->ip_summed = info->ip_summed; | 2544 | skb->ip_summed = info->ip_summed; |
| 2514 | skb->csum = info->csum; | 2545 | skb->csum = info->csum; |
| 2515 | 2546 | ||
| 2547 | out: | ||
| 2548 | return skb; | ||
| 2549 | } | ||
| 2550 | EXPORT_SYMBOL(napi_fraginfo_skb); | ||
| 2551 | |||
| 2552 | int napi_gro_frags(struct napi_struct *napi, struct napi_gro_fraginfo *info) | ||
| 2553 | { | ||
| 2554 | struct sk_buff *skb = napi_fraginfo_skb(napi, info); | ||
| 2555 | int err = NET_RX_DROP; | ||
| 2556 | |||
| 2557 | if (!skb) | ||
| 2558 | goto out; | ||
| 2559 | |||
| 2560 | err = NET_RX_SUCCESS; | ||
| 2561 | |||
| 2516 | switch (__napi_gro_receive(napi, skb)) { | 2562 | switch (__napi_gro_receive(napi, skb)) { |
| 2517 | case -1: | 2563 | case -1: |
| 2518 | return netif_receive_skb(skb); | 2564 | return netif_receive_skb(skb); |
| @@ -2521,17 +2567,7 @@ int napi_gro_frags(struct napi_struct *napi, struct napi_gro_fraginfo *info) | |||
| 2521 | goto out; | 2567 | goto out; |
| 2522 | } | 2568 | } |
| 2523 | 2569 | ||
| 2524 | reuse: | 2570 | napi_reuse_skb(napi, skb); |
| 2525 | skb_shinfo(skb)->nr_frags = 0; | ||
| 2526 | |||
| 2527 | skb->len -= skb->data_len; | ||
| 2528 | skb->truesize -= skb->data_len; | ||
| 2529 | skb->data_len = 0; | ||
| 2530 | |||
| 2531 | __skb_pull(skb, skb_headlen(skb)); | ||
| 2532 | skb_reserve(skb, NET_IP_ALIGN - skb_headroom(skb)); | ||
| 2533 | |||
| 2534 | napi->skb = skb; | ||
| 2535 | 2571 | ||
| 2536 | out: | 2572 | out: |
| 2537 | return err; | 2573 | return err; |
