X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fnet%2Fpppol2tp.c;h=e0b072d9fdb7caf571e6594af1f732068cba5dab;hb=45ab33b6c190c4a8c58f1d13be2ff89ee62024ba;hp=921d4ef6d14b66d1b66c0c4b606a571cbec82020;hpb=37ca506adc395a028cd12760eca419dd0dc14b5c;p=linux-2.6-omap-h63xx.git diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c index 921d4ef6d14..e0b072d9fdb 100644 --- a/drivers/net/pppol2tp.c +++ b/drivers/net/pppol2tp.c @@ -488,7 +488,7 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb) { struct pppol2tp_session *session = NULL; struct pppol2tp_tunnel *tunnel; - unsigned char *ptr; + unsigned char *ptr, *optr; u16 hdrflags; u16 tunnel_id, session_id; int length; @@ -496,7 +496,7 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb) tunnel = pppol2tp_sock_to_tunnel(sock); if (tunnel == NULL) - goto error; + goto no_tunnel; /* UDP always verifies the packet length. */ __skb_pull(skb, sizeof(struct udphdr)); @@ -509,7 +509,7 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb) } /* Point to L2TP header */ - ptr = skb->data; + optr = ptr = skb->data; /* Get L2TP header flags */ hdrflags = ntohs(*(__be16*)ptr); @@ -637,12 +637,14 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb) /* If offset bit set, skip it. */ if (hdrflags & L2TP_HDRFLAG_O) { offset = ntohs(*(__be16 *)ptr); - skb->transport_header += 2 + offset; - if (!pskb_may_pull(skb, skb_transport_offset(skb) + 2)) - goto discard; + ptr += 2 + offset; } - __skb_pull(skb, skb_transport_offset(skb)); + offset = ptr - optr; + if (!pskb_may_pull(skb, offset)) + goto discard; + + __skb_pull(skb, offset); /* Skip PPP header, if present. In testing, Microsoft L2TP clients * don't send the PPP header (PPP header compression enabled), but @@ -652,6 +654,9 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb) * Note that skb->data[] isn't dereferenced from a u16 ptr here since * the field may be unaligned. */ + if (!pskb_may_pull(skb, 2)) + goto discard; + if ((skb->data[0] == 0xff) && (skb->data[1] == 0x03)) skb_pull(skb, 2); @@ -709,6 +714,10 @@ discard: return 0; error: + /* Put UDP header back */ + __skb_push(skb, sizeof(struct udphdr)); + +no_tunnel: return 1; } @@ -1050,6 +1059,8 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) /* Get routing info from the tunnel socket */ dst_release(skb->dst); skb->dst = sk_dst_get(sk_tun); + skb_orphan(skb); + skb->sk = sk_tun; /* Queue the packet to IP for output */ len = skb->len; @@ -1416,7 +1427,7 @@ static int pppol2tp_create(struct net *net, struct socket *sock) int error = -ENOMEM; struct sock *sk; - sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pppol2tp_sk_proto, 1); + sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pppol2tp_sk_proto); if (!sk) goto out; @@ -2278,10 +2289,12 @@ static void pppol2tp_seq_tunnel_show(struct seq_file *m, void *v) atomic_read(&tunnel->ref_count) - 1); seq_printf(m, " %08x %llu/%llu/%llu %llu/%llu/%llu\n", tunnel->debug, - tunnel->stats.tx_packets, tunnel->stats.tx_bytes, - tunnel->stats.tx_errors, - tunnel->stats.rx_packets, tunnel->stats.rx_bytes, - tunnel->stats.rx_errors); + (unsigned long long)tunnel->stats.tx_packets, + (unsigned long long)tunnel->stats.tx_bytes, + (unsigned long long)tunnel->stats.tx_errors, + (unsigned long long)tunnel->stats.rx_packets, + (unsigned long long)tunnel->stats.rx_bytes, + (unsigned long long)tunnel->stats.rx_errors); } static void pppol2tp_seq_session_show(struct seq_file *m, void *v) @@ -2309,12 +2322,12 @@ static void pppol2tp_seq_session_show(struct seq_file *m, void *v) jiffies_to_msecs(session->reorder_timeout)); seq_printf(m, " %hu/%hu %llu/%llu/%llu %llu/%llu/%llu\n", session->nr, session->ns, - session->stats.tx_packets, - session->stats.tx_bytes, - session->stats.tx_errors, - session->stats.rx_packets, - session->stats.rx_bytes, - session->stats.rx_errors); + (unsigned long long)session->stats.tx_packets, + (unsigned long long)session->stats.tx_bytes, + (unsigned long long)session->stats.tx_errors, + (unsigned long long)session->stats.rx_packets, + (unsigned long long)session->stats.rx_bytes, + (unsigned long long)session->stats.rx_errors); } static int pppol2tp_seq_show(struct seq_file *m, void *v) @@ -2457,9 +2470,10 @@ static int __init pppol2tp_init(void) out: return err; - +#ifdef CONFIG_PROC_FS out_unregister_pppox_proto: unregister_pppox_proto(PX_PROTO_OL2TP); +#endif out_unregister_pppol2tp_proto: proto_unregister(&pppol2tp_sk_proto); goto out; @@ -2478,7 +2492,7 @@ static void __exit pppol2tp_exit(void) module_init(pppol2tp_init); module_exit(pppol2tp_exit); -MODULE_AUTHOR("Martijn van Oosterhout ," +MODULE_AUTHOR("Martijn van Oosterhout , " "James Chapman "); MODULE_DESCRIPTION("PPP over L2TP over UDP"); MODULE_LICENSE("GPL");