diff options
Diffstat (limited to 'net/core/dev.c')
-rw-r--r-- | net/core/dev.c | 76 |
1 files changed, 25 insertions, 51 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 355df36360b4..c95d664b2b42 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -3752,7 +3752,7 @@ static int napi_gro_complete(struct sk_buff *skb) | |||
3752 | if (ptype->type != type || !ptype->callbacks.gro_complete) | 3752 | if (ptype->type != type || !ptype->callbacks.gro_complete) |
3753 | continue; | 3753 | continue; |
3754 | 3754 | ||
3755 | err = ptype->callbacks.gro_complete(skb); | 3755 | err = ptype->callbacks.gro_complete(skb, 0); |
3756 | break; | 3756 | break; |
3757 | } | 3757 | } |
3758 | rcu_read_unlock(); | 3758 | rcu_read_unlock(); |
@@ -3818,6 +3818,23 @@ static void gro_list_prepare(struct napi_struct *napi, struct sk_buff *skb) | |||
3818 | } | 3818 | } |
3819 | } | 3819 | } |
3820 | 3820 | ||
3821 | static void skb_gro_reset_offset(struct sk_buff *skb) | ||
3822 | { | ||
3823 | const struct skb_shared_info *pinfo = skb_shinfo(skb); | ||
3824 | const skb_frag_t *frag0 = &pinfo->frags[0]; | ||
3825 | |||
3826 | NAPI_GRO_CB(skb)->data_offset = 0; | ||
3827 | NAPI_GRO_CB(skb)->frag0 = NULL; | ||
3828 | NAPI_GRO_CB(skb)->frag0_len = 0; | ||
3829 | |||
3830 | if (skb_mac_header(skb) == skb_tail_pointer(skb) && | ||
3831 | pinfo->nr_frags && | ||
3832 | !PageHighMem(skb_frag_page(frag0))) { | ||
3833 | NAPI_GRO_CB(skb)->frag0 = skb_frag_address(frag0); | ||
3834 | NAPI_GRO_CB(skb)->frag0_len = skb_frag_size(frag0); | ||
3835 | } | ||
3836 | } | ||
3837 | |||
3821 | static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb) | 3838 | static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb) |
3822 | { | 3839 | { |
3823 | struct sk_buff **pp = NULL; | 3840 | struct sk_buff **pp = NULL; |
@@ -3833,6 +3850,7 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff | |||
3833 | if (skb_is_gso(skb) || skb_has_frag_list(skb)) | 3850 | if (skb_is_gso(skb) || skb_has_frag_list(skb)) |
3834 | goto normal; | 3851 | goto normal; |
3835 | 3852 | ||
3853 | skb_gro_reset_offset(skb); | ||
3836 | gro_list_prepare(napi, skb); | 3854 | gro_list_prepare(napi, skb); |
3837 | 3855 | ||
3838 | rcu_read_lock(); | 3856 | rcu_read_lock(); |
@@ -3938,27 +3956,8 @@ static gro_result_t napi_skb_finish(gro_result_t ret, struct sk_buff *skb) | |||
3938 | return ret; | 3956 | return ret; |
3939 | } | 3957 | } |
3940 | 3958 | ||
3941 | static void skb_gro_reset_offset(struct sk_buff *skb) | ||
3942 | { | ||
3943 | const struct skb_shared_info *pinfo = skb_shinfo(skb); | ||
3944 | const skb_frag_t *frag0 = &pinfo->frags[0]; | ||
3945 | |||
3946 | NAPI_GRO_CB(skb)->data_offset = 0; | ||
3947 | NAPI_GRO_CB(skb)->frag0 = NULL; | ||
3948 | NAPI_GRO_CB(skb)->frag0_len = 0; | ||
3949 | |||
3950 | if (skb_mac_header(skb) == skb_tail_pointer(skb) && | ||
3951 | pinfo->nr_frags && | ||
3952 | !PageHighMem(skb_frag_page(frag0))) { | ||
3953 | NAPI_GRO_CB(skb)->frag0 = skb_frag_address(frag0); | ||
3954 | NAPI_GRO_CB(skb)->frag0_len = skb_frag_size(frag0); | ||
3955 | } | ||
3956 | } | ||
3957 | |||
3958 | gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) | 3959 | gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) |
3959 | { | 3960 | { |
3960 | skb_gro_reset_offset(skb); | ||
3961 | |||
3962 | return napi_skb_finish(dev_gro_receive(napi, skb), skb); | 3961 | return napi_skb_finish(dev_gro_receive(napi, skb), skb); |
3963 | } | 3962 | } |
3964 | EXPORT_SYMBOL(napi_gro_receive); | 3963 | EXPORT_SYMBOL(napi_gro_receive); |
@@ -3992,12 +3991,7 @@ static gro_result_t napi_frags_finish(struct napi_struct *napi, struct sk_buff * | |||
3992 | { | 3991 | { |
3993 | switch (ret) { | 3992 | switch (ret) { |
3994 | case GRO_NORMAL: | 3993 | case GRO_NORMAL: |
3995 | case GRO_HELD: | 3994 | if (netif_receive_skb(skb)) |
3996 | skb->protocol = eth_type_trans(skb, skb->dev); | ||
3997 | |||
3998 | if (ret == GRO_HELD) | ||
3999 | skb_gro_pull(skb, -ETH_HLEN); | ||
4000 | else if (netif_receive_skb(skb)) | ||
4001 | ret = GRO_DROP; | 3995 | ret = GRO_DROP; |
4002 | break; | 3996 | break; |
4003 | 3997 | ||
@@ -4006,6 +4000,7 @@ static gro_result_t napi_frags_finish(struct napi_struct *napi, struct sk_buff * | |||
4006 | napi_reuse_skb(napi, skb); | 4000 | napi_reuse_skb(napi, skb); |
4007 | break; | 4001 | break; |
4008 | 4002 | ||
4003 | case GRO_HELD: | ||
4009 | case GRO_MERGED: | 4004 | case GRO_MERGED: |
4010 | break; | 4005 | break; |
4011 | } | 4006 | } |
@@ -4016,36 +4011,15 @@ static gro_result_t napi_frags_finish(struct napi_struct *napi, struct sk_buff * | |||
4016 | static struct sk_buff *napi_frags_skb(struct napi_struct *napi) | 4011 | static struct sk_buff *napi_frags_skb(struct napi_struct *napi) |
4017 | { | 4012 | { |
4018 | struct sk_buff *skb = napi->skb; | 4013 | struct sk_buff *skb = napi->skb; |
4019 | struct ethhdr *eth; | ||
4020 | unsigned int hlen; | ||
4021 | unsigned int off; | ||
4022 | 4014 | ||
4023 | napi->skb = NULL; | 4015 | napi->skb = NULL; |
4024 | 4016 | ||
4025 | skb_reset_mac_header(skb); | 4017 | if (unlikely(!pskb_may_pull(skb, sizeof(struct ethhdr)))) { |
4026 | skb_gro_reset_offset(skb); | 4018 | napi_reuse_skb(napi, skb); |
4027 | 4019 | return NULL; | |
4028 | off = skb_gro_offset(skb); | ||
4029 | hlen = off + sizeof(*eth); | ||
4030 | eth = skb_gro_header_fast(skb, off); | ||
4031 | if (skb_gro_header_hard(skb, hlen)) { | ||
4032 | eth = skb_gro_header_slow(skb, hlen, off); | ||
4033 | if (unlikely(!eth)) { | ||
4034 | napi_reuse_skb(napi, skb); | ||
4035 | skb = NULL; | ||
4036 | goto out; | ||
4037 | } | ||
4038 | } | 4020 | } |
4021 | skb->protocol = eth_type_trans(skb, skb->dev); | ||
4039 | 4022 | ||
4040 | skb_gro_pull(skb, sizeof(*eth)); | ||
4041 | |||
4042 | /* | ||
4043 | * This works because the only protocols we care about don't require | ||
4044 | * special handling. We'll fix it up properly at the end. | ||
4045 | */ | ||
4046 | skb->protocol = eth->h_proto; | ||
4047 | |||
4048 | out: | ||
4049 | return skb; | 4023 | return skb; |
4050 | } | 4024 | } |
4051 | 4025 | ||