aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/pppoe.c50
1 files changed, 13 insertions, 37 deletions
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index 5ac3eff6a2a..8818253102f 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
914abort: 889abort:
915 return 0; 890 kfree_skb(skb);
891 return 1;
916} 892}
917 893
918 894