Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

PPTP: PPP over IPv4 (Point-to-Point Tunneling Protocol)

PPP: introduce "pptp" module which implements point-to-point tunneling protocol using pppox framework
NET: introduce the "gre" module for demultiplexing GRE packets on version criteria
(required to pptp and ip_gre may coexists)
NET: ip_gre: update to use the "gre" module

This patch introduces then pptp support to the linux kernel which
dramatically speeds up pptp vpn connections and decreases cpu usage in
comparison of existing user-space implementation
(poptop/pptpclient). There is accel-pptp project
(https://sourceforge.net/projects/accel-pptp/) to utilize this module,
it contains plugin for pppd to use pptp in client-mode and modified
pptpd (poptop) to build high-performance pptp NAS.

There was many changes from initial submitted patch, most important are:
1. using rcu instead of read-write locks
2. using static bitmap instead of dynamically allocated
3. using vmalloc for memory allocation instead of BITS_PER_LONG + __get_free_pages
4. fixed many coding style issues
Thanks to Eric Dumazet.

Signed-off-by: Dmitry Kozlov <xeb@mail.ru>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Dmitry Kozlov and committed by
David S. Miller
00959ade 1003489e

+970 -23
+14
MAINTAINERS
··· 6528 6528 S: Maintained 6529 6529 F: drivers/serial/zs.* 6530 6530 6531 + GRE DEMULTIPLEXER DRIVER 6532 + M: Dmitry Kozlov <xeb@mail.ru> 6533 + L: netdev@vger.kernel.org 6534 + S: Maintained 6535 + F: net/ipv4/gre.c 6536 + F: include/net/gre.h 6537 + 6538 + PPTP DRIVER 6539 + M: Dmitry Kozlov <xeb@mail.ru> 6540 + L: netdev@vger.kernel.org 6541 + S: Maintained 6542 + F: drivers/net/pptp.c 6543 + W: http://sourceforge.net/projects/accel-pptp 6544 + 6531 6545 THE REST 6532 6546 M: Linus Torvalds <torvalds@linux-foundation.org> 6533 6547 L: linux-kernel@vger.kernel.org
+11
drivers/net/Kconfig
··· 3192 3192 which contains instruction on how to use this driver (under 3193 3193 the heading "Kernel mode PPPoE"). 3194 3194 3195 + config PPTP 3196 + tristate "PPP over IPv4 (PPTP) (EXPERIMENTAL)" 3197 + depends on EXPERIMENTAL && PPP && NET_IPGRE_DEMUX 3198 + help 3199 + Support for PPP over IPv4.(Point-to-Point Tunneling Protocol) 3200 + 3201 + This driver requires pppd plugin to work in client mode or 3202 + modified pptpd (poptop) to work in server mode. 3203 + See http://accel-pptp.sourceforge.net/ for information how to 3204 + utilize this module. 3205 + 3195 3206 config PPPOATM 3196 3207 tristate "PPP over ATM" 3197 3208 depends on ATM && PPP
+1
drivers/net/Makefile
··· 162 162 obj-$(CONFIG_PPP_MPPE) += ppp_mppe.o 163 163 obj-$(CONFIG_PPPOE) += pppox.o pppoe.o 164 164 obj-$(CONFIG_PPPOL2TP) += pppox.o 165 + obj-$(CONFIG_PPTP) += pppox.o pptp.o 165 166 166 167 obj-$(CONFIG_SLIP) += slip.o 167 168 obj-$(CONFIG_SLHC) += slhc.o
+726
drivers/net/pptp.c
··· 1 + /* 2 + * Point-to-Point Tunneling Protocol for Linux 3 + * 4 + * Authors: Dmitry Kozlov <xeb@mail.ru> 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public License 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the License, or (at your option) any later version. 10 + * 11 + */ 12 + 13 + #include <linux/string.h> 14 + #include <linux/module.h> 15 + #include <linux/kernel.h> 16 + #include <linux/slab.h> 17 + #include <linux/errno.h> 18 + #include <linux/netdevice.h> 19 + #include <linux/net.h> 20 + #include <linux/skbuff.h> 21 + #include <linux/vmalloc.h> 22 + #include <linux/init.h> 23 + #include <linux/ppp_channel.h> 24 + #include <linux/ppp_defs.h> 25 + #include <linux/if_pppox.h> 26 + #include <linux/if_ppp.h> 27 + #include <linux/notifier.h> 28 + #include <linux/file.h> 29 + #include <linux/in.h> 30 + #include <linux/ip.h> 31 + #include <linux/netfilter.h> 32 + #include <linux/netfilter_ipv4.h> 33 + #include <linux/version.h> 34 + #include <linux/rcupdate.h> 35 + #include <linux/spinlock.h> 36 + 37 + #include <net/sock.h> 38 + #include <net/protocol.h> 39 + #include <net/ip.h> 40 + #include <net/icmp.h> 41 + #include <net/route.h> 42 + #include <net/gre.h> 43 + 44 + #include <linux/uaccess.h> 45 + 46 + #define PPTP_DRIVER_VERSION "0.8.5" 47 + 48 + #define MAX_CALLID 65535 49 + 50 + static DECLARE_BITMAP(callid_bitmap, MAX_CALLID + 1); 51 + static struct pppox_sock **callid_sock; 52 + 53 + static DEFINE_SPINLOCK(chan_lock); 54 + 55 + static struct proto pptp_sk_proto __read_mostly; 56 + static struct ppp_channel_ops pptp_chan_ops; 57 + static const struct proto_ops pptp_ops; 58 + 59 + #define PPP_LCP_ECHOREQ 0x09 60 + #define PPP_LCP_ECHOREP 0x0A 61 + #define SC_RCV_BITS (SC_RCV_B7_1|SC_RCV_B7_0|SC_RCV_ODDP|SC_RCV_EVNP) 62 + 63 + #define MISSING_WINDOW 20 64 + #define WRAPPED(curseq, lastseq)\ 65 + ((((curseq) & 0xffffff00) == 0) &&\ 66 + (((lastseq) & 0xffffff00) == 0xffffff00)) 67 + 68 + #define PPTP_GRE_PROTO 0x880B 69 + #define PPTP_GRE_VER 0x1 70 + 71 + #define PPTP_GRE_FLAG_C 0x80 72 + #define PPTP_GRE_FLAG_R 0x40 73 + #define PPTP_GRE_FLAG_K 0x20 74 + #define PPTP_GRE_FLAG_S 0x10 75 + #define PPTP_GRE_FLAG_A 0x80 76 + 77 + #define PPTP_GRE_IS_C(f) ((f)&PPTP_GRE_FLAG_C) 78 + #define PPTP_GRE_IS_R(f) ((f)&PPTP_GRE_FLAG_R) 79 + #define PPTP_GRE_IS_K(f) ((f)&PPTP_GRE_FLAG_K) 80 + #define PPTP_GRE_IS_S(f) ((f)&PPTP_GRE_FLAG_S) 81 + #define PPTP_GRE_IS_A(f) ((f)&PPTP_GRE_FLAG_A) 82 + 83 + #define PPTP_HEADER_OVERHEAD (2+sizeof(struct pptp_gre_header)) 84 + struct pptp_gre_header { 85 + u8 flags; 86 + u8 ver; 87 + u16 protocol; 88 + u16 payload_len; 89 + u16 call_id; 90 + u32 seq; 91 + u32 ack; 92 + } __packed; 93 + 94 + static struct pppox_sock *lookup_chan(u16 call_id, __be32 s_addr) 95 + { 96 + struct pppox_sock *sock; 97 + struct pptp_opt *opt; 98 + 99 + rcu_read_lock(); 100 + sock = rcu_dereference(callid_sock[call_id]); 101 + if (sock) { 102 + opt = &sock->proto.pptp; 103 + if (opt->dst_addr.sin_addr.s_addr != s_addr) 104 + sock = NULL; 105 + else 106 + sock_hold(sk_pppox(sock)); 107 + } 108 + rcu_read_unlock(); 109 + 110 + return sock; 111 + } 112 + 113 + static int lookup_chan_dst(u16 call_id, __be32 d_addr) 114 + { 115 + struct pppox_sock *sock; 116 + struct pptp_opt *opt; 117 + int i; 118 + 119 + rcu_read_lock(); 120 + for (i = find_next_bit(callid_bitmap, MAX_CALLID, 1); i < MAX_CALLID; 121 + i = find_next_bit(callid_bitmap, MAX_CALLID, i + 1)) { 122 + sock = rcu_dereference(callid_sock[i]); 123 + if (!sock) 124 + continue; 125 + opt = &sock->proto.pptp; 126 + if (opt->dst_addr.call_id == call_id && 127 + opt->dst_addr.sin_addr.s_addr == d_addr) 128 + break; 129 + } 130 + rcu_read_unlock(); 131 + 132 + return i < MAX_CALLID; 133 + } 134 + 135 + static int add_chan(struct pppox_sock *sock) 136 + { 137 + static int call_id; 138 + 139 + spin_lock(&chan_lock); 140 + if (!sock->proto.pptp.src_addr.call_id) { 141 + call_id = find_next_zero_bit(callid_bitmap, MAX_CALLID, call_id + 1); 142 + if (call_id == MAX_CALLID) { 143 + call_id = find_next_zero_bit(callid_bitmap, MAX_CALLID, 1); 144 + if (call_id == MAX_CALLID) 145 + goto out_err; 146 + } 147 + sock->proto.pptp.src_addr.call_id = call_id; 148 + } else if (test_bit(sock->proto.pptp.src_addr.call_id, callid_bitmap)) 149 + goto out_err; 150 + 151 + set_bit(sock->proto.pptp.src_addr.call_id, callid_bitmap); 152 + rcu_assign_pointer(callid_sock[sock->proto.pptp.src_addr.call_id], sock); 153 + spin_unlock(&chan_lock); 154 + 155 + return 0; 156 + 157 + out_err: 158 + spin_unlock(&chan_lock); 159 + return -1; 160 + } 161 + 162 + static void del_chan(struct pppox_sock *sock) 163 + { 164 + spin_lock(&chan_lock); 165 + clear_bit(sock->proto.pptp.src_addr.call_id, callid_bitmap); 166 + rcu_assign_pointer(callid_sock[sock->proto.pptp.src_addr.call_id], NULL); 167 + spin_unlock(&chan_lock); 168 + synchronize_rcu(); 169 + } 170 + 171 + static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) 172 + { 173 + struct sock *sk = (struct sock *) chan->private; 174 + struct pppox_sock *po = pppox_sk(sk); 175 + struct pptp_opt *opt = &po->proto.pptp; 176 + struct pptp_gre_header *hdr; 177 + unsigned int header_len = sizeof(*hdr); 178 + int err = 0; 179 + int islcp; 180 + int len; 181 + unsigned char *data; 182 + __u32 seq_recv; 183 + 184 + 185 + struct rtable *rt; 186 + struct net_device *tdev; 187 + struct iphdr *iph; 188 + int max_headroom; 189 + 190 + if (sk_pppox(po)->sk_state & PPPOX_DEAD) 191 + goto tx_error; 192 + 193 + { 194 + struct flowi fl = { .oif = 0, 195 + .nl_u = { 196 + .ip4_u = { 197 + .daddr = opt->dst_addr.sin_addr.s_addr, 198 + .saddr = opt->src_addr.sin_addr.s_addr, 199 + .tos = RT_TOS(0) } }, 200 + .proto = IPPROTO_GRE }; 201 + err = ip_route_output_key(&init_net, &rt, &fl); 202 + if (err) 203 + goto tx_error; 204 + } 205 + tdev = rt->dst.dev; 206 + 207 + max_headroom = LL_RESERVED_SPACE(tdev) + sizeof(*iph) + sizeof(*hdr) + 2; 208 + 209 + if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) { 210 + struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); 211 + if (!new_skb) { 212 + ip_rt_put(rt); 213 + goto tx_error; 214 + } 215 + if (skb->sk) 216 + skb_set_owner_w(new_skb, skb->sk); 217 + kfree_skb(skb); 218 + skb = new_skb; 219 + } 220 + 221 + data = skb->data; 222 + islcp = ((data[0] << 8) + data[1]) == PPP_LCP && 1 <= data[2] && data[2] <= 7; 223 + 224 + /* compress protocol field */ 225 + if ((opt->ppp_flags & SC_COMP_PROT) && data[0] == 0 && !islcp) 226 + skb_pull(skb, 1); 227 + 228 + /* Put in the address/control bytes if necessary */ 229 + if ((opt->ppp_flags & SC_COMP_AC) == 0 || islcp) { 230 + data = skb_push(skb, 2); 231 + data[0] = PPP_ALLSTATIONS; 232 + data[1] = PPP_UI; 233 + } 234 + 235 + len = skb->len; 236 + 237 + seq_recv = opt->seq_recv; 238 + 239 + if (opt->ack_sent == seq_recv) 240 + header_len -= sizeof(hdr->ack); 241 + 242 + /* Push down and install GRE header */ 243 + skb_push(skb, header_len); 244 + hdr = (struct pptp_gre_header *)(skb->data); 245 + 246 + hdr->flags = PPTP_GRE_FLAG_K; 247 + hdr->ver = PPTP_GRE_VER; 248 + hdr->protocol = htons(PPTP_GRE_PROTO); 249 + hdr->call_id = htons(opt->dst_addr.call_id); 250 + 251 + hdr->flags |= PPTP_GRE_FLAG_S; 252 + hdr->seq = htonl(++opt->seq_sent); 253 + if (opt->ack_sent != seq_recv) { 254 + /* send ack with this message */ 255 + hdr->ver |= PPTP_GRE_FLAG_A; 256 + hdr->ack = htonl(seq_recv); 257 + opt->ack_sent = seq_recv; 258 + } 259 + hdr->payload_len = htons(len); 260 + 261 + /* Push down and install the IP header. */ 262 + 263 + skb_reset_transport_header(skb); 264 + skb_push(skb, sizeof(*iph)); 265 + skb_reset_network_header(skb); 266 + memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); 267 + IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | IPSKB_REROUTED); 268 + 269 + iph = ip_hdr(skb); 270 + iph->version = 4; 271 + iph->ihl = sizeof(struct iphdr) >> 2; 272 + if (ip_dont_fragment(sk, &rt->dst)) 273 + iph->frag_off = htons(IP_DF); 274 + else 275 + iph->frag_off = 0; 276 + iph->protocol = IPPROTO_GRE; 277 + iph->tos = 0; 278 + iph->daddr = rt->rt_dst; 279 + iph->saddr = rt->rt_src; 280 + iph->ttl = dst_metric(&rt->dst, RTAX_HOPLIMIT); 281 + iph->tot_len = htons(skb->len); 282 + 283 + skb_dst_drop(skb); 284 + skb_dst_set(skb, &rt->dst); 285 + 286 + nf_reset(skb); 287 + 288 + skb->ip_summed = CHECKSUM_NONE; 289 + ip_select_ident(iph, &rt->dst, NULL); 290 + ip_send_check(iph); 291 + 292 + ip_local_out(skb); 293 + 294 + tx_error: 295 + return 1; 296 + } 297 + 298 + static int pptp_rcv_core(struct sock *sk, struct sk_buff *skb) 299 + { 300 + struct pppox_sock *po = pppox_sk(sk); 301 + struct pptp_opt *opt = &po->proto.pptp; 302 + int headersize, payload_len, seq; 303 + __u8 *payload; 304 + struct pptp_gre_header *header; 305 + 306 + if (!(sk->sk_state & PPPOX_CONNECTED)) { 307 + if (sock_queue_rcv_skb(sk, skb)) 308 + goto drop; 309 + return NET_RX_SUCCESS; 310 + } 311 + 312 + header = (struct pptp_gre_header *)(skb->data); 313 + 314 + /* test if acknowledgement present */ 315 + if (PPTP_GRE_IS_A(header->ver)) { 316 + __u32 ack = (PPTP_GRE_IS_S(header->flags)) ? 317 + header->ack : header->seq; /* ack in different place if S = 0 */ 318 + 319 + ack = ntohl(ack); 320 + 321 + if (ack > opt->ack_recv) 322 + opt->ack_recv = ack; 323 + /* also handle sequence number wrap-around */ 324 + if (WRAPPED(ack, opt->ack_recv)) 325 + opt->ack_recv = ack; 326 + } 327 + 328 + /* test if payload present */ 329 + if (!PPTP_GRE_IS_S(header->flags)) 330 + goto drop; 331 + 332 + headersize = sizeof(*header); 333 + payload_len = ntohs(header->payload_len); 334 + seq = ntohl(header->seq); 335 + 336 + /* no ack present? */ 337 + if (!PPTP_GRE_IS_A(header->ver)) 338 + headersize -= sizeof(header->ack); 339 + /* check for incomplete packet (length smaller than expected) */ 340 + if (skb->len - headersize < payload_len) 341 + goto drop; 342 + 343 + payload = skb->data + headersize; 344 + /* check for expected sequence number */ 345 + if (seq < opt->seq_recv + 1 || WRAPPED(opt->seq_recv, seq)) { 346 + if ((payload[0] == PPP_ALLSTATIONS) && (payload[1] == PPP_UI) && 347 + (PPP_PROTOCOL(payload) == PPP_LCP) && 348 + ((payload[4] == PPP_LCP_ECHOREQ) || (payload[4] == PPP_LCP_ECHOREP))) 349 + goto allow_packet; 350 + } else { 351 + opt->seq_recv = seq; 352 + allow_packet: 353 + skb_pull(skb, headersize); 354 + 355 + if (payload[0] == PPP_ALLSTATIONS && payload[1] == PPP_UI) { 356 + /* chop off address/control */ 357 + if (skb->len < 3) 358 + goto drop; 359 + skb_pull(skb, 2); 360 + } 361 + 362 + if ((*skb->data) & 1) { 363 + /* protocol is compressed */ 364 + skb_push(skb, 1)[0] = 0; 365 + } 366 + 367 + skb->ip_summed = CHECKSUM_NONE; 368 + skb_set_network_header(skb, skb->head-skb->data); 369 + ppp_input(&po->chan, skb); 370 + 371 + return NET_RX_SUCCESS; 372 + } 373 + drop: 374 + kfree_skb(skb); 375 + return NET_RX_DROP; 376 + } 377 + 378 + static int pptp_rcv(struct sk_buff *skb) 379 + { 380 + struct pppox_sock *po; 381 + struct pptp_gre_header *header; 382 + struct iphdr *iph; 383 + 384 + if (skb->pkt_type != PACKET_HOST) 385 + goto drop; 386 + 387 + if (!pskb_may_pull(skb, 12)) 388 + goto drop; 389 + 390 + iph = ip_hdr(skb); 391 + 392 + header = (struct pptp_gre_header *)skb->data; 393 + 394 + if (ntohs(header->protocol) != PPTP_GRE_PROTO || /* PPTP-GRE protocol for PPTP */ 395 + PPTP_GRE_IS_C(header->flags) || /* flag C should be clear */ 396 + PPTP_GRE_IS_R(header->flags) || /* flag R should be clear */ 397 + !PPTP_GRE_IS_K(header->flags) || /* flag K should be set */ 398 + (header->flags&0xF) != 0) /* routing and recursion ctrl = 0 */ 399 + /* if invalid, discard this packet */ 400 + goto drop; 401 + 402 + po = lookup_chan(htons(header->call_id), iph->saddr); 403 + if (po) { 404 + skb_dst_drop(skb); 405 + nf_reset(skb); 406 + return sk_receive_skb(sk_pppox(po), skb, 0); 407 + } 408 + drop: 409 + kfree_skb(skb); 410 + return NET_RX_DROP; 411 + } 412 + 413 + static int pptp_bind(struct socket *sock, struct sockaddr *uservaddr, 414 + int sockaddr_len) 415 + { 416 + struct sock *sk = sock->sk; 417 + struct sockaddr_pppox *sp = (struct sockaddr_pppox *) uservaddr; 418 + struct pppox_sock *po = pppox_sk(sk); 419 + struct pptp_opt *opt = &po->proto.pptp; 420 + int error = 0; 421 + 422 + lock_sock(sk); 423 + 424 + opt->src_addr = sp->sa_addr.pptp; 425 + if (add_chan(po)) { 426 + release_sock(sk); 427 + error = -EBUSY; 428 + } 429 + 430 + release_sock(sk); 431 + return error; 432 + } 433 + 434 + static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr, 435 + int sockaddr_len, int flags) 436 + { 437 + struct sock *sk = sock->sk; 438 + struct sockaddr_pppox *sp = (struct sockaddr_pppox *) uservaddr; 439 + struct pppox_sock *po = pppox_sk(sk); 440 + struct pptp_opt *opt = &po->proto.pptp; 441 + struct rtable *rt; 442 + int error = 0; 443 + 444 + if (sp->sa_protocol != PX_PROTO_PPTP) 445 + return -EINVAL; 446 + 447 + if (lookup_chan_dst(sp->sa_addr.pptp.call_id, sp->sa_addr.pptp.sin_addr.s_addr)) 448 + return -EALREADY; 449 + 450 + lock_sock(sk); 451 + /* Check for already bound sockets */ 452 + if (sk->sk_state & PPPOX_CONNECTED) { 453 + error = -EBUSY; 454 + goto end; 455 + } 456 + 457 + /* Check for already disconnected sockets, on attempts to disconnect */ 458 + if (sk->sk_state & PPPOX_DEAD) { 459 + error = -EALREADY; 460 + goto end; 461 + } 462 + 463 + if (!opt->src_addr.sin_addr.s_addr || !sp->sa_addr.pptp.sin_addr.s_addr) { 464 + error = -EINVAL; 465 + goto end; 466 + } 467 + 468 + po->chan.private = sk; 469 + po->chan.ops = &pptp_chan_ops; 470 + 471 + { 472 + struct flowi fl = { 473 + .nl_u = { 474 + .ip4_u = { 475 + .daddr = opt->dst_addr.sin_addr.s_addr, 476 + .saddr = opt->src_addr.sin_addr.s_addr, 477 + .tos = RT_CONN_FLAGS(sk) } }, 478 + .proto = IPPROTO_GRE }; 479 + security_sk_classify_flow(sk, &fl); 480 + if (ip_route_output_key(&init_net, &rt, &fl)) { 481 + error = -EHOSTUNREACH; 482 + goto end; 483 + } 484 + sk_setup_caps(sk, &rt->dst); 485 + } 486 + po->chan.mtu = dst_mtu(&rt->dst); 487 + if (!po->chan.mtu) 488 + po->chan.mtu = PPP_MTU; 489 + ip_rt_put(rt); 490 + po->chan.mtu -= PPTP_HEADER_OVERHEAD; 491 + 492 + po->chan.hdrlen = 2 + sizeof(struct pptp_gre_header); 493 + error = ppp_register_channel(&po->chan); 494 + if (error) { 495 + pr_err("PPTP: failed to register PPP channel (%d)\n", error); 496 + goto end; 497 + } 498 + 499 + opt->dst_addr = sp->sa_addr.pptp; 500 + sk->sk_state = PPPOX_CONNECTED; 501 + 502 + end: 503 + release_sock(sk); 504 + return error; 505 + } 506 + 507 + static int pptp_getname(struct socket *sock, struct sockaddr *uaddr, 508 + int *usockaddr_len, int peer) 509 + { 510 + int len = sizeof(struct sockaddr_pppox); 511 + struct sockaddr_pppox sp; 512 + 513 + sp.sa_family = AF_PPPOX; 514 + sp.sa_protocol = PX_PROTO_PPTP; 515 + sp.sa_addr.pptp = pppox_sk(sock->sk)->proto.pptp.src_addr; 516 + 517 + memcpy(uaddr, &sp, len); 518 + 519 + *usockaddr_len = len; 520 + 521 + return 0; 522 + } 523 + 524 + static int pptp_release(struct socket *sock) 525 + { 526 + struct sock *sk = sock->sk; 527 + struct pppox_sock *po; 528 + struct pptp_opt *opt; 529 + int error = 0; 530 + 531 + if (!sk) 532 + return 0; 533 + 534 + lock_sock(sk); 535 + 536 + if (sock_flag(sk, SOCK_DEAD)) { 537 + release_sock(sk); 538 + return -EBADF; 539 + } 540 + 541 + po = pppox_sk(sk); 542 + opt = &po->proto.pptp; 543 + del_chan(po); 544 + 545 + pppox_unbind_sock(sk); 546 + sk->sk_state = PPPOX_DEAD; 547 + 548 + sock_orphan(sk); 549 + sock->sk = NULL; 550 + 551 + release_sock(sk); 552 + sock_put(sk); 553 + 554 + return error; 555 + } 556 + 557 + static void pptp_sock_destruct(struct sock *sk) 558 + { 559 + if (!(sk->sk_state & PPPOX_DEAD)) { 560 + del_chan(pppox_sk(sk)); 561 + pppox_unbind_sock(sk); 562 + } 563 + skb_queue_purge(&sk->sk_receive_queue); 564 + } 565 + 566 + static int pptp_create(struct net *net, struct socket *sock) 567 + { 568 + int error = -ENOMEM; 569 + struct sock *sk; 570 + struct pppox_sock *po; 571 + struct pptp_opt *opt; 572 + 573 + sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pptp_sk_proto); 574 + if (!sk) 575 + goto out; 576 + 577 + sock_init_data(sock, sk); 578 + 579 + sock->state = SS_UNCONNECTED; 580 + sock->ops = &pptp_ops; 581 + 582 + sk->sk_backlog_rcv = pptp_rcv_core; 583 + sk->sk_state = PPPOX_NONE; 584 + sk->sk_type = SOCK_STREAM; 585 + sk->sk_family = PF_PPPOX; 586 + sk->sk_protocol = PX_PROTO_PPTP; 587 + sk->sk_destruct = pptp_sock_destruct; 588 + 589 + po = pppox_sk(sk); 590 + opt = &po->proto.pptp; 591 + 592 + opt->seq_sent = 0; opt->seq_recv = 0; 593 + opt->ack_recv = 0; opt->ack_sent = 0; 594 + 595 + error = 0; 596 + out: 597 + return error; 598 + } 599 + 600 + static int pptp_ppp_ioctl(struct ppp_channel *chan, unsigned int cmd, 601 + unsigned long arg) 602 + { 603 + struct sock *sk = (struct sock *) chan->private; 604 + struct pppox_sock *po = pppox_sk(sk); 605 + struct pptp_opt *opt = &po->proto.pptp; 606 + void __user *argp = (void __user *)arg; 607 + int __user *p = argp; 608 + int err, val; 609 + 610 + err = -EFAULT; 611 + switch (cmd) { 612 + case PPPIOCGFLAGS: 613 + val = opt->ppp_flags; 614 + if (put_user(val, p)) 615 + break; 616 + err = 0; 617 + break; 618 + case PPPIOCSFLAGS: 619 + if (get_user(val, p)) 620 + break; 621 + opt->ppp_flags = val & ~SC_RCV_BITS; 622 + err = 0; 623 + break; 624 + default: 625 + err = -ENOTTY; 626 + } 627 + 628 + return err; 629 + } 630 + 631 + static struct ppp_channel_ops pptp_chan_ops = { 632 + .start_xmit = pptp_xmit, 633 + .ioctl = pptp_ppp_ioctl, 634 + }; 635 + 636 + static struct proto pptp_sk_proto __read_mostly = { 637 + .name = "PPTP", 638 + .owner = THIS_MODULE, 639 + .obj_size = sizeof(struct pppox_sock), 640 + }; 641 + 642 + static const struct proto_ops pptp_ops = { 643 + .family = AF_PPPOX, 644 + .owner = THIS_MODULE, 645 + .release = pptp_release, 646 + .bind = pptp_bind, 647 + .connect = pptp_connect, 648 + .socketpair = sock_no_socketpair, 649 + .accept = sock_no_accept, 650 + .getname = pptp_getname, 651 + .poll = sock_no_poll, 652 + .listen = sock_no_listen, 653 + .shutdown = sock_no_shutdown, 654 + .setsockopt = sock_no_setsockopt, 655 + .getsockopt = sock_no_getsockopt, 656 + .sendmsg = sock_no_sendmsg, 657 + .recvmsg = sock_no_recvmsg, 658 + .mmap = sock_no_mmap, 659 + .ioctl = pppox_ioctl, 660 + }; 661 + 662 + static struct pppox_proto pppox_pptp_proto = { 663 + .create = pptp_create, 664 + .owner = THIS_MODULE, 665 + }; 666 + 667 + static struct gre_protocol gre_pptp_protocol = { 668 + .handler = pptp_rcv, 669 + }; 670 + 671 + static int __init pptp_init_module(void) 672 + { 673 + int err = 0; 674 + pr_info("PPTP driver version " PPTP_DRIVER_VERSION "\n"); 675 + 676 + callid_sock = __vmalloc((MAX_CALLID + 1) * sizeof(void *), 677 + GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL); 678 + if (!callid_sock) { 679 + pr_err("PPTP: cann't allocate memory\n"); 680 + return -ENOMEM; 681 + } 682 + 683 + err = gre_add_protocol(&gre_pptp_protocol, GREPROTO_PPTP); 684 + if (err) { 685 + pr_err("PPTP: can't add gre protocol\n"); 686 + goto out_mem_free; 687 + } 688 + 689 + err = proto_register(&pptp_sk_proto, 0); 690 + if (err) { 691 + pr_err("PPTP: can't register sk_proto\n"); 692 + goto out_gre_del_protocol; 693 + } 694 + 695 + err = register_pppox_proto(PX_PROTO_PPTP, &pppox_pptp_proto); 696 + if (err) { 697 + pr_err("PPTP: can't register pppox_proto\n"); 698 + goto out_unregister_sk_proto; 699 + } 700 + 701 + return 0; 702 + 703 + out_unregister_sk_proto: 704 + proto_unregister(&pptp_sk_proto); 705 + out_gre_del_protocol: 706 + gre_del_protocol(&gre_pptp_protocol, GREPROTO_PPTP); 707 + out_mem_free: 708 + vfree(callid_sock); 709 + 710 + return err; 711 + } 712 + 713 + static void __exit pptp_exit_module(void) 714 + { 715 + unregister_pppox_proto(PX_PROTO_PPTP); 716 + proto_unregister(&pptp_sk_proto); 717 + gre_del_protocol(&gre_pptp_protocol, GREPROTO_PPTP); 718 + vfree(callid_sock); 719 + } 720 + 721 + module_init(pptp_init_module); 722 + module_exit(pptp_exit_module); 723 + 724 + MODULE_DESCRIPTION("Point-to-Point Tunneling Protocol"); 725 + MODULE_AUTHOR("D. Kozlov (xeb@mail.ru)"); 726 + MODULE_LICENSE("GPL");
+34 -16
include/linux/if_pppox.h
··· 40 40 * PPPoE addressing definition 41 41 */ 42 42 typedef __be16 sid_t; 43 - struct pppoe_addr{ 44 - sid_t sid; /* Session identifier */ 45 - unsigned char remote[ETH_ALEN]; /* Remote address */ 46 - char dev[IFNAMSIZ]; /* Local device to use */ 43 + struct pppoe_addr { 44 + sid_t sid; /* Session identifier */ 45 + unsigned char remote[ETH_ALEN]; /* Remote address */ 46 + char dev[IFNAMSIZ]; /* Local device to use */ 47 47 }; 48 48 49 49 /************************************************************************ 50 - * Protocols supported by AF_PPPOX 51 - */ 50 + * PPTP addressing definition 51 + */ 52 + struct pptp_addr { 53 + u16 call_id; 54 + struct in_addr sin_addr; 55 + }; 56 + 57 + /************************************************************************ 58 + * Protocols supported by AF_PPPOX 59 + */ 52 60 #define PX_PROTO_OE 0 /* Currently just PPPoE */ 53 61 #define PX_PROTO_OL2TP 1 /* Now L2TP also */ 54 - #define PX_MAX_PROTO 2 62 + #define PX_PROTO_PPTP 2 63 + #define PX_MAX_PROTO 3 55 64 56 - struct sockaddr_pppox { 57 - sa_family_t sa_family; /* address family, AF_PPPOX */ 58 - unsigned int sa_protocol; /* protocol identifier */ 59 - union{ 60 - struct pppoe_addr pppoe; 61 - }sa_addr; 65 + struct sockaddr_pppox { 66 + sa_family_t sa_family; /* address family, AF_PPPOX */ 67 + unsigned int sa_protocol; /* protocol identifier */ 68 + union { 69 + struct pppoe_addr pppoe; 70 + struct pptp_addr pptp; 71 + } sa_addr; 62 72 } __packed; 63 73 64 74 /* The use of the above union isn't viable because the size of this ··· 111 101 __be16 tag_type; 112 102 __be16 tag_len; 113 103 char tag_data[0]; 114 - } __attribute ((packed)); 104 + } __packed; 115 105 116 106 /* Tag identifiers */ 117 107 #define PTT_EOL __cpu_to_be16(0x0000) ··· 160 150 relayed to (PPPoE relaying) */ 161 151 }; 162 152 153 + struct pptp_opt { 154 + struct pptp_addr src_addr; 155 + struct pptp_addr dst_addr; 156 + u32 ack_sent, ack_recv; 157 + u32 seq_sent, seq_recv; 158 + int ppp_flags; 159 + }; 163 160 #include <net/sock.h> 164 161 165 162 struct pppox_sock { 166 163 /* struct sock must be the first member of pppox_sock */ 167 - struct sock sk; 168 - struct ppp_channel chan; 164 + struct sock sk; 165 + struct ppp_channel chan; 169 166 struct pppox_sock *next; /* for hash table */ 170 167 union { 171 168 struct pppoe_opt pppoe; 169 + struct pptp_opt pptp; 172 170 } proto; 173 171 __be16 num; 174 172 };
+18
include/net/gre.h
··· 1 + #ifndef __LINUX_GRE_H 2 + #define __LINUX_GRE_H 3 + 4 + #include <linux/skbuff.h> 5 + 6 + #define GREPROTO_CISCO 0 7 + #define GREPROTO_PPTP 1 8 + #define GREPROTO_MAX 2 9 + 10 + struct gre_protocol { 11 + int (*handler)(struct sk_buff *skb); 12 + void (*err_handler)(struct sk_buff *skb, u32 info); 13 + }; 14 + 15 + int gre_add_protocol(const struct gre_protocol *proto, u8 version); 16 + int gre_del_protocol(const struct gre_protocol *proto, u8 version); 17 + 18 + #endif
+7
net/ipv4/Kconfig
··· 215 215 be inserted in and removed from the running kernel whenever you 216 216 want). Most people won't need this and can say N. 217 217 218 + config NET_IPGRE_DEMUX 219 + tristate "IP: GRE demultiplexer" 220 + help 221 + This is helper module to demultiplex GRE packets on GRE version field criteria. 222 + Required by ip_gre and pptp modules. 223 + 218 224 config NET_IPGRE 219 225 tristate "IP: GRE tunnels over IP" 226 + depends on NET_IPGRE_DEMUX 220 227 help 221 228 Tunneling means encapsulating data of one protocol type within 222 229 another protocol and sending it over a channel that understands the
+1
net/ipv4/Makefile
··· 20 20 obj-$(CONFIG_IP_MULTIPLE_TABLES) += fib_rules.o 21 21 obj-$(CONFIG_IP_MROUTE) += ipmr.o 22 22 obj-$(CONFIG_NET_IPIP) += ipip.o 23 + obj-$(CONFIG_NET_IPGRE_DEMUX) += gre.o 23 24 obj-$(CONFIG_NET_IPGRE) += ip_gre.o 24 25 obj-$(CONFIG_SYN_COOKIES) += syncookies.o 25 26 obj-$(CONFIG_INET_AH) += ah4.o
+151
net/ipv4/gre.c
··· 1 + /* 2 + * GRE over IPv4 demultiplexer driver 3 + * 4 + * Authors: Dmitry Kozlov (xeb@mail.ru) 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public License 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the License, or (at your option) any later version. 10 + * 11 + */ 12 + 13 + #include <linux/module.h> 14 + #include <linux/kernel.h> 15 + #include <linux/kmod.h> 16 + #include <linux/skbuff.h> 17 + #include <linux/in.h> 18 + #include <linux/netdevice.h> 19 + #include <linux/version.h> 20 + #include <linux/spinlock.h> 21 + #include <net/protocol.h> 22 + #include <net/gre.h> 23 + 24 + 25 + const struct gre_protocol *gre_proto[GREPROTO_MAX] __read_mostly; 26 + static DEFINE_SPINLOCK(gre_proto_lock); 27 + 28 + int gre_add_protocol(const struct gre_protocol *proto, u8 version) 29 + { 30 + if (version >= GREPROTO_MAX) 31 + goto err_out; 32 + 33 + spin_lock(&gre_proto_lock); 34 + if (gre_proto[version]) 35 + goto err_out_unlock; 36 + 37 + rcu_assign_pointer(gre_proto[version], proto); 38 + spin_unlock(&gre_proto_lock); 39 + return 0; 40 + 41 + err_out_unlock: 42 + spin_unlock(&gre_proto_lock); 43 + err_out: 44 + return -1; 45 + } 46 + EXPORT_SYMBOL_GPL(gre_add_protocol); 47 + 48 + int gre_del_protocol(const struct gre_protocol *proto, u8 version) 49 + { 50 + if (version >= GREPROTO_MAX) 51 + goto err_out; 52 + 53 + spin_lock(&gre_proto_lock); 54 + if (gre_proto[version] != proto) 55 + goto err_out_unlock; 56 + rcu_assign_pointer(gre_proto[version], NULL); 57 + spin_unlock(&gre_proto_lock); 58 + synchronize_rcu(); 59 + return 0; 60 + 61 + err_out_unlock: 62 + spin_unlock(&gre_proto_lock); 63 + err_out: 64 + return -1; 65 + } 66 + EXPORT_SYMBOL_GPL(gre_del_protocol); 67 + 68 + static int gre_rcv(struct sk_buff *skb) 69 + { 70 + const struct gre_protocol *proto; 71 + u8 ver; 72 + int ret; 73 + 74 + if (!pskb_may_pull(skb, 12)) 75 + goto drop; 76 + 77 + ver = skb->data[1]&0x7f; 78 + if (ver >= GREPROTO_MAX) 79 + goto drop; 80 + 81 + rcu_read_lock(); 82 + proto = rcu_dereference(gre_proto[ver]); 83 + if (!proto || !proto->handler) 84 + goto drop_unlock; 85 + ret = proto->handler(skb); 86 + rcu_read_unlock(); 87 + return ret; 88 + 89 + drop_unlock: 90 + rcu_read_unlock(); 91 + drop: 92 + kfree_skb(skb); 93 + return NET_RX_DROP; 94 + } 95 + 96 + static void gre_err(struct sk_buff *skb, u32 info) 97 + { 98 + const struct gre_protocol *proto; 99 + u8 ver; 100 + 101 + if (!pskb_may_pull(skb, 12)) 102 + goto drop; 103 + 104 + ver = skb->data[1]&0x7f; 105 + if (ver >= GREPROTO_MAX) 106 + goto drop; 107 + 108 + rcu_read_lock(); 109 + proto = rcu_dereference(gre_proto[ver]); 110 + if (!proto || !proto->err_handler) 111 + goto drop_unlock; 112 + proto->err_handler(skb, info); 113 + rcu_read_unlock(); 114 + return; 115 + 116 + drop_unlock: 117 + rcu_read_unlock(); 118 + drop: 119 + kfree_skb(skb); 120 + } 121 + 122 + static const struct net_protocol net_gre_protocol = { 123 + .handler = gre_rcv, 124 + .err_handler = gre_err, 125 + .netns_ok = 1, 126 + }; 127 + 128 + static int __init gre_init(void) 129 + { 130 + pr_info("GRE over IPv4 demultiplexor driver"); 131 + 132 + if (inet_add_protocol(&net_gre_protocol, IPPROTO_GRE) < 0) { 133 + pr_err("gre: can't add protocol\n"); 134 + return -EAGAIN; 135 + } 136 + 137 + return 0; 138 + } 139 + 140 + static void __exit gre_exit(void) 141 + { 142 + inet_del_protocol(&net_gre_protocol, IPPROTO_GRE); 143 + } 144 + 145 + module_init(gre_init); 146 + module_exit(gre_exit); 147 + 148 + MODULE_DESCRIPTION("GRE over IPv4 demultiplexer driver"); 149 + MODULE_AUTHOR("D. Kozlov (xeb@mail.ru)"); 150 + MODULE_LICENSE("GPL"); 151 +
+7 -7
net/ipv4/ip_gre.c
··· 44 44 #include <net/net_namespace.h> 45 45 #include <net/netns/generic.h> 46 46 #include <net/rtnetlink.h> 47 + #include <net/gre.h> 47 48 48 49 #ifdef CONFIG_IPV6 49 50 #include <net/ipv6.h> ··· 1279 1278 } 1280 1279 1281 1280 1282 - static const struct net_protocol ipgre_protocol = { 1283 - .handler = ipgre_rcv, 1284 - .err_handler = ipgre_err, 1285 - .netns_ok = 1, 1281 + static const struct gre_protocol ipgre_protocol = { 1282 + .handler = ipgre_rcv, 1283 + .err_handler = ipgre_err, 1286 1284 }; 1287 1285 1288 1286 static void ipgre_destroy_tunnels(struct ipgre_net *ign, struct list_head *head) ··· 1663 1663 if (err < 0) 1664 1664 return err; 1665 1665 1666 - err = inet_add_protocol(&ipgre_protocol, IPPROTO_GRE); 1666 + err = gre_add_protocol(&ipgre_protocol, GREPROTO_CISCO); 1667 1667 if (err < 0) { 1668 1668 printk(KERN_INFO "ipgre init: can't add protocol\n"); 1669 1669 goto add_proto_failed; ··· 1683 1683 tap_ops_failed: 1684 1684 rtnl_link_unregister(&ipgre_link_ops); 1685 1685 rtnl_link_failed: 1686 - inet_del_protocol(&ipgre_protocol, IPPROTO_GRE); 1686 + gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO); 1687 1687 add_proto_failed: 1688 1688 unregister_pernet_device(&ipgre_net_ops); 1689 1689 goto out; ··· 1693 1693 { 1694 1694 rtnl_link_unregister(&ipgre_tap_ops); 1695 1695 rtnl_link_unregister(&ipgre_link_ops); 1696 - if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0) 1696 + if (gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO) < 0) 1697 1697 printk(KERN_INFO "ipgre close: can't remove protocol\n"); 1698 1698 unregister_pernet_device(&ipgre_net_ops); 1699 1699 }