aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2009-01-06 13:49:34 -0500
committerDavid S. Miller <davem@davemloft.net>2009-01-06 13:49:34 -0500
commit96e93eab20337d063c70d537bd7bc70d90e04fa3 (patch)
tree6b50a8d19e6c4d99f035dbede3b7836eed5a7d44 /net/core
parentff5bfc3584efdadf826a21bc76ef42bdfcf3f612 (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.c82
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}
2388EXPORT_SYMBOL(napi_gro_flush); 2388EXPORT_SYMBOL(napi_gro_flush);
2389 2389
2390static int __napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) 2390int 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:
2463normal: 2466normal:
2464 return -1; 2467 return -1;
2465} 2468}
2469EXPORT_SYMBOL(dev_gro_receive);
2470
2471static 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
2467int napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) 2483int 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}
2480EXPORT_SYMBOL(napi_gro_receive); 2496EXPORT_SYMBOL(napi_gro_receive);
2481 2497
2482int napi_gro_frags(struct napi_struct *napi, struct napi_gro_fraginfo *info) 2498void 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}
2511EXPORT_SYMBOL(napi_reuse_skb);
2512
2513struct 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
2547out:
2548 return skb;
2549}
2550EXPORT_SYMBOL(napi_fraginfo_skb);
2551
2552int 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
2524reuse: 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
2536out: 2572out:
2537 return err; 2573 return err;