summaryrefslogtreecommitdiff
path: root/kernel/driver/pptp.c
diff options
context:
space:
mode:
authorKozlov Dmitry <dima@server>2010-08-03 13:21:08 +0400
committerKozlov Dmitry <dima@server>2010-08-03 13:23:13 +0400
commitba8e1a64e75930a161afac9048e7d03b7f880644 (patch)
tree2067af947e0434c823a907f99b5b6de5ca57f97c /kernel/driver/pptp.c
parent65422c607e372089677b7b254928d052b9bbe8fb (diff)
downloadaccel-ppp-ba8e1a64e75930a161afac9048e7d03b7f880644.tar.gz
accel-ppp-ba8e1a64e75930a161afac9048e7d03b7f880644.zip
* merged http://code.google.com/p/wl500g/source/browse/trunk/kernel/312-accel-pptp-custom.patch
* introduced gre demultiplexer module for pptp and ip_gre may coexists (prepare to merge pptp module to mainstream kernel, disabled by default)
Diffstat (limited to 'kernel/driver/pptp.c')
-rw-r--r--kernel/driver/pptp.c54
1 files changed, 45 insertions, 9 deletions
diff --git a/kernel/driver/pptp.c b/kernel/driver/pptp.c
index aa9e2f6e..3837b373 100644
--- a/kernel/driver/pptp.c
+++ b/kernel/driver/pptp.c
@@ -49,6 +49,11 @@
#include <asm/uaccess.h>
#define DEBUG
+//#define USE_GRE_MOD
+
+#ifdef USE_GRE_MOD
+#include "gre.h"
+#endif
#define PPTP_DRIVER_VERSION "0.8.4"
@@ -60,6 +65,8 @@ static int log_level=0;
static int log_packets=10;
#define MAX_CALLID 65535
+#define PPP_LCP_ECHOREQ 0x09
+#define PPP_LCP_ECHOREP 0x0A
static unsigned long *callid_bitmap=NULL;
static struct pppox_sock **callid_sock=NULL;
@@ -185,7 +192,6 @@ found_middle:
}
#endif
-
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
static rwlock_t chan_lock=RW_LOCK_UNLOCKED;
#define SK_STATE(sk) (sk)->state
@@ -399,8 +405,8 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
*/
if ((opt->ppp_flags & SC_COMP_AC) == 0 || islcp) {
data=skb_push(skb,2);
- data[0]=0xff;
- data[1]=0x03;
+ data[0]=PPP_ALLSTATIONS;
+ data[1]=PPP_UI;
}
len=skb->len;
@@ -469,13 +475,16 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
#endif
iph->version = 4;
iph->ihl = sizeof(struct iphdr) >> 2;
- iph->frag_off = 0;//df;
+ if (ip_dont_fragment(sk, &rt->u.dst))
+ iph->frag_off = htons(IP_DF);
+ else
+ iph->frag_off = 0;
iph->protocol = IPPROTO_GRE;
iph->tos = 0;
iph->daddr = rt->rt_dst;
iph->saddr = rt->rt_src;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
- iph->ttl = sysctl_ip_default_ttl;
+ iph->ttl = sk->protinfo.af_inet.ttl;
#else
iph->ttl = dst_metric(&rt->u.dst, RTAX_HOPLIMIT);
#endif
@@ -559,12 +568,24 @@ static int pptp_rcv_core(struct sock *sk,struct sk_buff *skb)
payload=skb->data+headersize;
/* check for expected sequence number */
if ( seq < opt->seq_recv + 1 || WRAPPED(opt->seq_recv, seq) ){
+ if ( (payload[0] == PPP_ALLSTATIONS) && (payload[1] == PPP_UI) &&
+ (PPP_PROTOCOL(payload) == PPP_LCP) &&
+ ((payload[4] == PPP_LCP_ECHOREQ) || (payload[4] == PPP_LCP_ECHOREP)) ){
+ #ifdef DEBUG
+ if ( log_level >= 1)
+ printk(KERN_INFO"PPTP[%i]: allowing old LCP Echo packet %d (expecting %d)\n", opt->src_addr.call_id,
+ seq, opt->seq_recv + 1);
+ #endif
+ goto allow_packet;
+ }
#ifdef DEBUG
if ( log_level >= 1)
printk(KERN_INFO"PPTP[%i]: discarding duplicate or old packet %d (expecting %d)\n",opt->src_addr.call_id,
seq, opt->seq_recv + 1);
#endif
}else{
+ opt->seq_recv = seq;
+allow_packet:
#ifdef DEBUG
if ( log_level >= 3 && opt->seq_sent<=log_packets)
printk(KERN_INFO"PPTP[%i]: accepting packet %d size=%i (%02x %02x %02x %02x %02x %02x)\n",opt->src_addr.call_id, seq,payload_len,
@@ -575,7 +596,6 @@ static int pptp_rcv_core(struct sock *sk,struct sk_buff *skb)
*(payload +4),
*(payload +5));
#endif
- opt->seq_recv = seq;
skb_pull(skb,headersize);
@@ -592,7 +612,7 @@ static int pptp_rcv_core(struct sock *sk,struct sk_buff *skb)
}
skb->ip_summed=CHECKSUM_NONE;
- #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19)
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21)
skb_set_network_header(skb,skb->head-skb->data);
#endif
ppp_input(&po->chan,skb);
@@ -617,8 +637,8 @@ static int pptp_rcv(struct sk_buff *skb)
if (skb->pkt_type != PACKET_HOST)
goto drop;
- if (!pskb_may_pull(skb, 12))
- goto drop;
+ /*if (!pskb_may_pull(skb, 12))
+ goto drop;*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
iph = ip_hdr(skb);
@@ -1082,7 +1102,11 @@ static struct inet_protocol net_pptp_protocol = {
.name = "PPTP",
};
#else
+#ifdef USE_GRE_MOD
+static struct gre_protocol gre_pptp_protocol = {
+#else
static struct net_protocol net_pptp_protocol = {
+#endif
.handler = pptp_rcv,
//.err_handler = pptp_err,
};
@@ -1096,7 +1120,11 @@ static int pptp_init_module(void)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
inet_add_protocol(&net_pptp_protocol);
#else
+ #ifdef USE_GRE_MOD
+ if (gre_add_protocol(&gre_pptp_protocol, GREPROTO_PPTP) < 0) {
+ #else
if (inet_add_protocol(&net_pptp_protocol, IPPROTO_GRE) < 0) {
+ #endif
printk(KERN_INFO "PPTP: can't add protocol\n");
goto out;
}
@@ -1145,8 +1173,12 @@ out_inet_del_protocol:
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
inet_del_protocol(&net_pptp_protocol);
#else
+ #ifdef USE_GRE_MOD
+ gre_del_protocol(&gre_pptp_protocol, GREPROTO_PPTP);
+ #else
inet_del_protocol(&net_pptp_protocol, IPPROTO_GRE);
#endif
+ #endif
goto out;
}
@@ -1163,8 +1195,12 @@ static void pptp_exit_module(void)
inet_del_protocol(&net_pptp_protocol);
#else
proto_unregister(&pptp_sk_proto);
+ #ifdef USE_GRE_MOD
+ gre_del_protocol(&gre_pptp_protocol, GREPROTO_PPTP);
+ #else
inet_del_protocol(&net_pptp_protocol, IPPROTO_GRE);
#endif
+ #endif
if (callid_bitmap) free_pages((unsigned long)callid_bitmap,1);
if (callid_sock) {
#if (BITS_PER_LONG == 32)