diff options
| -rw-r--r-- | drivers/net/pppoe.c | 50 |
1 files changed, 13 insertions, 37 deletions
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index 5ac3eff6a2a6..8818253102f2 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c | |||
| @@ -850,9 +850,7 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb) | |||
| 850 | struct net_device *dev = po->pppoe_dev; | 850 | struct net_device *dev = po->pppoe_dev; |
| 851 | struct pppoe_hdr hdr; | 851 | struct pppoe_hdr hdr; |
| 852 | struct pppoe_hdr *ph; | 852 | struct pppoe_hdr *ph; |
| 853 | int headroom = skb_headroom(skb); | ||
| 854 | int data_len = skb->len; | 853 | int data_len = skb->len; |
| 855 | struct sk_buff *skb2; | ||
| 856 | 854 | ||
| 857 | if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED)) | 855 | if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED)) |
| 858 | goto abort; | 856 | goto abort; |
| @@ -866,53 +864,31 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb) | |||
| 866 | if (!dev) | 864 | if (!dev) |
| 867 | goto abort; | 865 | goto abort; |
| 868 | 866 | ||
| 869 | /* Copy the skb if there is no space for the header. */ | 867 | /* Copy the data if there is no space for the header or if it's |
| 870 | if (headroom < (sizeof(struct pppoe_hdr) + dev->hard_header_len)) { | 868 | * read-only. |
| 871 | skb2 = dev_alloc_skb(32+skb->len + | 869 | */ |
| 872 | sizeof(struct pppoe_hdr) + | 870 | if (skb_cow(skb, sizeof(*ph) + dev->hard_header_len)) |
| 873 | dev->hard_header_len); | 871 | goto abort; |
| 874 | |||
| 875 | if (skb2 == NULL) | ||
| 876 | goto abort; | ||
| 877 | |||
| 878 | skb_reserve(skb2, dev->hard_header_len + sizeof(struct pppoe_hdr)); | ||
| 879 | skb_copy_from_linear_data(skb, skb_put(skb2, skb->len), | ||
| 880 | skb->len); | ||
| 881 | } else { | ||
| 882 | /* Make a clone so as to not disturb the original skb, | ||
| 883 | * give dev_queue_xmit something it can free. | ||
| 884 | */ | ||
| 885 | skb2 = skb_clone(skb, GFP_ATOMIC); | ||
| 886 | |||
| 887 | if (skb2 == NULL) | ||
| 888 | goto abort; | ||
| 889 | } | ||
| 890 | 872 | ||
| 891 | ph = (struct pppoe_hdr *) skb_push(skb2, sizeof(struct pppoe_hdr)); | 873 | ph = (struct pppoe_hdr *) skb_push(skb, sizeof(struct pppoe_hdr)); |
| 892 | memcpy(ph, &hdr, sizeof(struct pppoe_hdr)); | 874 | memcpy(ph, &hdr, sizeof(struct pppoe_hdr)); |
| 893 | skb2->protocol = __constant_htons(ETH_P_PPP_SES); | 875 | skb->protocol = __constant_htons(ETH_P_PPP_SES); |
| 894 | 876 | ||
| 895 | skb_reset_network_header(skb2); | 877 | skb_reset_network_header(skb); |
| 896 | 878 | ||
| 897 | skb2->dev = dev; | 879 | skb->dev = dev; |
| 898 | 880 | ||
| 899 | dev->hard_header(skb2, dev, ETH_P_PPP_SES, | 881 | dev->hard_header(skb, dev, ETH_P_PPP_SES, |
| 900 | po->pppoe_pa.remote, NULL, data_len); | 882 | po->pppoe_pa.remote, NULL, data_len); |
| 901 | 883 | ||
| 902 | /* We're transmitting skb2, and assuming that dev_queue_xmit | 884 | if (dev_queue_xmit(skb) < 0) |
| 903 | * will free it. The generic ppp layer however, is expecting | ||
| 904 | * that we give back 'skb' (not 'skb2') in case of failure, | ||
| 905 | * but free it in case of success. | ||
| 906 | */ | ||
| 907 | |||
| 908 | if (dev_queue_xmit(skb2) < 0) | ||
| 909 | goto abort; | 885 | goto abort; |
| 910 | 886 | ||
| 911 | kfree_skb(skb); | ||
| 912 | return 1; | 887 | return 1; |
| 913 | 888 | ||
| 914 | abort: | 889 | abort: |
| 915 | return 0; | 890 | kfree_skb(skb); |
| 891 | return 1; | ||
| 916 | } | 892 | } |
| 917 | 893 | ||
| 918 | 894 | ||
