Update and fix x2ltpd, add connect script
authorGabor Juhos <juhosg@openwrt.org>
Wed, 2 May 2012 19:28:10 +0000 (19:28 +0000)
committerGabor Juhos <juhosg@openwrt.org>
Wed, 2 May 2012 19:28:10 +0000 (19:28 +0000)
Remove unwanted services from default configuration
Ship xl2tpd-config
Use kernel mode L2TP
Don't scribble on ipparam

Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
SVN-Revision: 31561

net/xl2tpd/Makefile
net/xl2tpd/files/l2tp.sh [new file with mode: 0644]
net/xl2tpd/files/xl2tpd.conf
net/xl2tpd/patches/120-kernel-mode-l2tp.patch [new file with mode: 0644]
net/xl2tpd/patches/130-no-kill-ipparam.patch [new file with mode: 0644]

index 467efb9..0119236 100644 (file)
@@ -8,12 +8,14 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=xl2tpd
-PKG_VERSION:=1.3.0
+PKG_VERSION:=1.3.1
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=ftp://ftp.xelerance.com/xl2tpd/
-PKG_MD5SUM:=28264284552c442b24cf421755a2bb48
+# Host seems to be down.
+#PKG_SOURCE_URL:=ftp://ftp.xelerance.com/xl2tpd/
+PKG_MD5SUM:=cf61576fef5c2d6c68279a408ec1f0d5
+PKG_SOURCE_URL:=http://pkgs.fedoraproject.org/lookaside/pkgs/xl2tpd/xl2tpd-$(PKG_VERSION).tar.gz/$(PKG_MD5SUM)/
 
 PKG_INSTALL:=1
 
@@ -25,6 +27,7 @@ define Package/xl2tpd
   TITLE:=An L2TP (Layer 2 Tunneling Protocol) daemon
   URL:=http://www.xelerance.com/software/xl2tpd/
   SUBMENU:=VPN
+  DEPENDS:=+ppp-mod-pppol2tp +ip +resolveip
 endef
 
 define Package/xl2tpd/description
@@ -46,6 +49,7 @@ endef
 define Package/xl2tpd/install
        $(INSTALL_DIR) $(1)/usr/sbin
        $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/local/sbin/xl2tpd $(1)/usr/sbin/
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/local/sbin/xl2tpd-control $(1)/usr/sbin/
 
        $(INSTALL_DIR) $(1)/etc/init.d
        $(INSTALL_BIN) ./files/xl2tpd.init $(1)/etc/init.d/xl2tpd
@@ -56,6 +60,9 @@ define Package/xl2tpd/install
 
        $(INSTALL_DIR) $(1)/etc/ppp
        $(INSTALL_DATA) ./files/options.xl2tpd $(1)/etc/ppp/
+
+       $(INSTALL_DIR) $(1)/lib/network
+       $(INSTALL_DATA) ./files/l2tp.sh $(1)/lib/network
 endef
 
 $(eval $(call BuildPackage,xl2tpd))
diff --git a/net/xl2tpd/files/l2tp.sh b/net/xl2tpd/files/l2tp.sh
new file mode 100644 (file)
index 0000000..f2a4d55
--- /dev/null
@@ -0,0 +1,124 @@
+find_route() {
+       ip route get $1 | sed -e 's/ /\n/g' | \
+            sed -ne '1p;/via/{N;p};/dev/{N;p};/src/{N;p};/mtu/{N;p}'
+}
+
+scan_l2tp() {
+       config_set "$1" device "l2tp-$1"
+}
+
+stop_interface_l2tp() {
+       local config="$1"
+       local lock="/var/lock/l2tp-${config}"
+       local optfile="/tmp/l2tp/options.${config}"
+       local l2tpcontrol=/var/run/xl2tpd/l2tp-control
+
+       lock "$lock"
+
+       [ -p ${l2tpcontrol} ] && echo "r l2tp-${config}" > ${l2tpcontrol}
+       rm -f ${optfile}
+
+       for ip in $(uci_get_state network "$1" serv_addrs); do
+           ip route del "$ip" 2>/dev/null
+       done
+
+       lock -u "$lock"
+}
+
+setup_interface_l2tp() {
+       local config="$2"
+       local lock="/var/lock/l2tp-${config}"
+       local optfile="/tmp/l2tp/options.${config}"
+
+       lock "$lock"
+
+       if [ ! -p /var/run/xl2tpd/l2tp-control ]; then
+           /etc/init.d/xl2tpd start
+       fi
+       
+       local device
+       config_get device "$config" device "l2tp-$config"
+
+       local server
+       config_get server "$config" server
+
+       local username
+       config_get username "$config" username
+
+       local password
+       config_get password "$config" password
+
+       local keepalive
+       config_get keepalive "$config" keepalive
+
+       local pppd_options
+       config_get pppd_options "$config" pppd_options
+
+       local defaultroute
+       config_get_bool defaultroute "$config" defaultroute 1
+       [ "$defaultroute" -eq 1 ] && \
+               defaultroute="defaultroute replacedefaultroute" || defaultroute="nodefaultroute"
+
+       local interval="${keepalive##*[, ]}"
+       [ "$interval" != "$keepalive" ] || interval=5
+
+       local dns
+       config_get dns "$config" dns
+
+       local has_dns=0
+       local peer_default=1
+       [ -n "$dns" ] && {
+               has_dns=1
+               peer_default=0
+       }
+
+       local peerdns
+       config_get_bool peerdns "$config" peerdns $peer_default
+
+       [ "$peerdns" -eq 1 ] && {
+               peerdns="usepeerdns"
+       } || {
+               peerdns=""
+               add_dns "$config" $dns
+       }
+
+       local ipv6
+       config_get ipv6 "$config" ipv6 1
+       [ "$ipv6" -eq 1 ] && ipv6="+ipv6" || ipv6=""
+
+       local serv_addrs=""
+       for ip in $(resolveip -t 3 "$server"); do
+               append serv_addrs "$ip"
+               ip route replace $(find_route $ip)
+       done
+       uci_toggle_state network "$config" serv_addrs "$serv_addrs"
+
+       # fix up the netmask
+       config_get netmask "$config" netmask
+       [ -z "$netmask" -o -z "$device" ] || ifconfig $device netmask $netmask
+
+       config_get mtu "$config" mtu
+
+       mkdir -p /tmp/l2tp
+
+       echo ${keepalive:+lcp-echo-interval $interval lcp-echo-failure ${keepalive%%[, ]*}} > "${optfile}"
+       echo "$peerdns" >> "${optfile}"
+       echo "$defaultroute" >> "${optfile}"
+       echo "${username:+user \"$username\" password \"$password\"}" >> "${optfile}"
+       echo "ipparam \"$config\"" >> "${optfile}"
+       echo "ifname \"l2tp-$config\"" >> "${optfile}"
+       # Don't wait for LCP term responses; exit immediately when killed.
+       echo "lcp-max-terminate 0" >> "${optfile}"
+       echo "${ipv6} ${pppd_options}" >> "${optfile}"
+
+       xl2tpd-control remove l2tp-${config}
+       # Wait and ensure pppd has died.
+       while [ -d /sys/class/net/l2tp-${config} ]; do
+           sleep 1
+       done
+       
+       xl2tpd-control add l2tp-${config} pppoptfile=${optfile} lns=${server} redial=yes redial timeout=20
+       xl2tpd-control connect l2tp-${config}
+
+       lock -u "${lock}"
+}
index e04d2fd..2423ff6 100644 (file)
@@ -3,21 +3,21 @@ port = 1701
 auth file = /etc/xl2tpd/xl2tp-secrets
 access control = no
 
-[lns default]
-exclusive = yes
-ip range = 192.168.254.202-192.168.254.210
-lac = 10.0.1.2
-hidden bit = no
-local ip = 192.168.254.200
-length bit = yes
-refuse authentication = yes
-name = VersaLink
-ppp debug = yes
-pppoptfile = /etc/ppp/options.xl2tpd
+;[lns default]
+;exclusive = yes
+;ip range = 192.168.254.202-192.168.254.210
+;lac = 10.0.1.2
+;hidden bit = no
+;local ip = 192.168.254.200
+;length bit = yes
+;refuse authentication = yes
+;name = VersaLink
+;ppp debug = yes
+;pppoptfile = /etc/ppp/options.xl2tpd
 
-[lac left]
-lns = 10.0.1.2
-refuse authentication = yes
-name = VersaLink
-ppp debug = yes
-pppoptfile = /etc/ppp/options.xl2tpd
+;[lac left]
+;lns = 10.0.1.2
+;refuse authentication = yes
+;name = VersaLink
+;ppp debug = yes
+;pppoptfile = /etc/ppp/options.xl2tpd
diff --git a/net/xl2tpd/patches/120-kernel-mode-l2tp.patch b/net/xl2tpd/patches/120-kernel-mode-l2tp.patch
new file mode 100644 (file)
index 0000000..fafa456
--- /dev/null
@@ -0,0 +1,436 @@
+diff --git a/Makefile b/Makefile
+index 6f6481f..778f38d 100644
+--- a/Makefile
++++ b/Makefile
+@@ -62,8 +62,8 @@
+ # are packages seperately (eg kernel-headers on Fedora)
+ # Note: 2.6.23+ support still needs some changes in the xl2tpd source
+ #
+-#OSFLAGS+= -DUSE_KERNEL
+-#
++# Kernel mode fixed by sigwall <fionov@gmail.com>
++OSFLAGS+= -DUSE_KERNEL
+ #
+ # Uncomment the next line for FreeBSD
+ #
+diff --git a/call.c b/call.c
+index d1b1858..b672f91 100644
+--- a/call.c
++++ b/call.c
+@@ -680,6 +680,8 @@ struct call *get_call (int tunnel, int call,  struct in_addr addr, int port,
+         st->peer.sin_port = port;
+       st->refme  = refme;
+       st->refhim = refhim;
++        st->udp_fd = -1;
++        st->pppox_fd = -1;
+         bcopy (&addr, &st->peer.sin_addr, sizeof (addr));
+         st->next = tunnels.head;
+         tunnels.head = st;
+diff --git a/control.c b/control.c
+index 0892df9..9362ffd 100644
+--- a/control.c
++++ b/control.c
+@@ -596,6 +596,9 @@ int control_finish (struct tunnel *t, struct call *c)
+         if (gconfig.debug_state)
+             l2tp_log (LOG_DEBUG, "%s: sending SCCCN\n", __FUNCTION__);
+         control_xmit (buf);
++
++        connect_pppol2tp(t);
++
+         /* Schedule a HELLO */
+         tv.tv_sec = HELLO_DELAY;
+         tv.tv_usec = 0;
+@@ -608,6 +611,7 @@ int control_finish (struct tunnel *t, struct call *c)
+                 "Connection established to %s, %d.  Local: %d, Remote: %d (ref=%u/%u).\n",
+                 IPADDY (t->peer.sin_addr),
+                 ntohs (t->peer.sin_port), t->ourtid, t->tid, t->refme, t->refhim);
++
+         if (t->lac)
+         {
+             /* This is part of a LAC, so we want to go ahead
+@@ -635,6 +639,9 @@ int control_finish (struct tunnel *t, struct call *c)
+                 IPADDY (t->peer.sin_addr),
+                 ntohs (t->peer.sin_port), t->ourtid, t->tid, t->refme, t->refhim,
+                 t->lns->entname);
++
++        connect_pppol2tp(t);
++
+         /* Schedule a HELLO */
+         tv.tv_sec = HELLO_DELAY;
+         tv.tv_usec = 0;
+diff --git a/l2tp.h b/l2tp.h
+index 2724fff..856423f 100644
+--- a/l2tp.h
++++ b/l2tp.h
+@@ -167,6 +167,8 @@ struct tunnel
+     int ourrws;                 /* Receive Window Size */
+     int rxspeed;              /* Receive bps */
+     int txspeed;              /* Transmit bps */
++    int udp_fd;                       /* UDP fd */
++    int pppox_fd;                     /* PPPOX tunnel fd */
+     struct call *self;
+     struct lns *lns;            /* LNS that owns us */
+     struct lac *lac;            /* LAC that owns us */
+@@ -220,6 +222,7 @@ extern void control_xmit (void *);
+ extern int ppd;
+ extern int switch_io;           /* jz */
+ extern int control_fd;
++extern int connect_pppol2tp(struct tunnel *t);
+ extern int start_pppd (struct call *c, struct ppp_opts *);
+ extern void magic_lac_dial (void *);
+ extern int get_entropy (unsigned char *, int);
+diff --git a/linux/include/linux/if_pppol2tp.h b/linux/include/linux/if_pppol2tp.h
+index a7d6a22..0795e4a 100644
+--- a/linux/include/linux/if_pppol2tp.h
++++ b/linux/include/linux/if_pppol2tp.h
+@@ -36,6 +36,20 @@ struct pppol2tp_addr
+       __u16 d_tunnel, d_session;      /* For sending outgoing packets */
+ };
++/* The L2TPv3 protocol changes tunnel and session ids from 16 to 32
++ * bits. So we need a different sockaddr structure.
++ */
++struct pppol2tpv3_addr {
++      pid_t   pid;                    /* pid that owns the fd.
++                                       * 0 => current */
++      int     fd;                     /* FD of UDP or IP socket to use */
++
++      struct sockaddr_in addr;        /* IP address and port to send to */
++
++      __u32 s_tunnel, s_session;      /* For matching incoming packets */
++      __u32 d_tunnel, d_session;      /* For sending outgoing packets */
++};
++
+ /* Socket options:
+  * DEBUG      - bitmask of debug message categories
+  * SENDSEQ    - 0 => don't send packets with sequence numbers
+diff --git a/network.c b/network.c
+index 241bd82..fde250e 100644
+--- a/network.c
++++ b/network.c
+@@ -22,6 +22,7 @@
+ #include <unistd.h>
+ #include <stdlib.h>
+ #include <sys/ioctl.h>
++#include <sys/wait.h>
+ #ifndef LINUX
+ # include <sys/uio.h>
+ #endif
+@@ -36,6 +37,51 @@ int server_socket;              /* Server socket */
+ int kernel_support;             /* Kernel Support there or not? */
+ #endif
++#ifdef USE_KERNEL
++void modprobe() {
++    char * modules[] = { "l2tp_ppp", "pppol2tp", NULL };
++    char ** module;
++    char buf[256], *tok;
++    int pid, exit_status, fd;
++
++    FILE * fmod = fopen("/proc/modules", "r");
++
++    if (fmod == NULL)
++        return;
++
++    while (fgets(buf, 255, fmod) != NULL) {
++        if ((tok = strtok(buf, " ")) != NULL) {
++            for (module = modules; *module != NULL; ++module) {
++                if (!strcmp(*module, tok)) {
++                    fclose(fmod);
++                    return;
++                }
++            }
++        }
++    }
++
++    fclose(fmod);
++
++    for (module = modules; *module != NULL; ++module) {
++        if ((pid = fork()) >= 0) {
++            if (pid == 0) {
++                setenv("PATH", "/sbin:/usr/sbin:/bin:/usr/bin", 1);
++                if ((fd = open("/dev/null", O_RDWR)) > -1) {
++                    dup2(fd, 1);
++                    dup2(fd, 2);
++                }
++                execlp("modprobe", "modprobe", "-q", *module, (char *)NULL);
++                exit(1);
++            } else {
++                if ((pid = waitpid(pid, &exit_status, 0)) != -1 && WIFEXITED(exit_status)) {
++                    if (WEXITSTATUS(exit_status) == 0)
++                        return;
++                }
++            }
++        }
++    }
++}
++#endif
+ int init_network (void)
+ {
+@@ -45,6 +91,7 @@ int init_network (void)
+     server.sin_family = AF_INET;
+     server.sin_addr.s_addr = gconfig.listenaddr; 
+     server.sin_port = htons (gconfig.port);
++    int flags;
+     if ((server_socket = socket (PF_INET, SOCK_DGRAM, 0)) < 0)
+     {
+         l2tp_log (LOG_CRIT, "%s: Unable to allocate socket. Terminating.\n",
+@@ -52,6 +99,10 @@ int init_network (void)
+         return -EINVAL;
+     };
++    flags = 1;
++    setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &flags, sizeof(flags));
++    setsockopt(server_socket, SOL_SOCKET, SO_NO_CHECK, &flags, sizeof(flags));
++
+     if (bind (server_socket, (struct sockaddr *) &server, sizeof (server)))
+     {
+         close (server_socket);
+@@ -91,6 +142,7 @@ int init_network (void)
+     }
+     else
+     {
++        modprobe();
+         int kernel_fd = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OL2TP);
+         if (kernel_fd < 0)
+         {
+@@ -321,6 +373,11 @@ int build_fdset (fd_set *readfds)
+       while (tun)
+       {
++              if (tun->udp_fd > -1) {
++                      if (tun->udp_fd > max)
++                              max = tun->udp_fd;
++                      FD_SET (tun->udp_fd, readfds);
++              }
+               call = tun->call_head;
+               while (call)
+               {
+@@ -390,6 +447,8 @@ void network_thread ()
+     struct iovec iov;
+     char cbuf[256];
+     unsigned int refme, refhim;
++    int * currentfd;
++    int server_socket_processed;
+     /* This one buffer can be recycled for everything except control packets */
+     buf = new_buf (MAX_RECV_SIZE);
+@@ -428,7 +487,21 @@ void network_thread ()
+         {
+             do_control ();
+         }
+-        if (FD_ISSET (server_socket, &readfds))
++        server_socket_processed = 0;
++        currentfd = NULL;
++        st = tunnels.head;
++        while (st || !server_socket_processed) {
++            if (st && (st->udp_fd == -1)) {
++                st=st->next;
++                continue;
++            }
++            if (st) {
++                currentfd = &st->udp_fd;
++            } else {
++                currentfd = &server_socket;
++                server_socket_processed = 1;
++            }
++            if (FD_ISSET (*currentfd, &readfds))
+         {
+             /*
+              * Okay, now we're ready for reading and processing new data.
+@@ -457,12 +530,19 @@ void network_thread ()
+           msgh.msg_flags = 0;
+           
+           /* Receive one packet. */
+-          recvsize = recvmsg(server_socket, &msgh, 0);
++          recvsize = recvmsg(*currentfd, &msgh, 0);
+             if (recvsize < MIN_PAYLOAD_HDR_LEN)
+             {
+                 if (recvsize < 0)
+                 {
++                    if (errno == ECONNREFUSED) {
++                        close(*currentfd);
++                    }
++                    if ((errno == ECONNREFUSED) ||
++                        (errno == EBADF)) {
++                        *currentfd = -1;
++                    }
+                     if (errno != EAGAIN)
+                         l2tp_log (LOG_WARNING,
+                              "%s: recvfrom returned error %d (%s)\n",
+@@ -567,6 +647,8 @@ void network_thread ()
+               }
+           };
+       }
++      if (st) st=st->next;
++      }
+       /*
+        * finished obvious sources, look for data from PPP connections.
+@@ -639,3 +721,82 @@ void network_thread ()
+     }
+ }
++
++int connect_pppol2tp(struct tunnel *t) {
++#ifdef USE_KERNEL
++        if (kernel_support) {
++            int ufd = -1, fd2 = -1;
++            int flags;
++            struct sockaddr_pppol2tp sax;
++
++            struct sockaddr_in server;
++            server.sin_family = AF_INET;
++            server.sin_addr.s_addr = gconfig.listenaddr;
++            server.sin_port = htons (gconfig.port);
++            if ((ufd = socket (PF_INET, SOCK_DGRAM, 0)) < 0)
++            {
++                l2tp_log (LOG_CRIT, "%s: Unable to allocate UDP socket. Terminating.\n",
++                    __FUNCTION__);
++                return -EINVAL;
++            };
++
++            flags=1;
++            setsockopt(ufd, SOL_SOCKET, SO_REUSEADDR, &flags, sizeof(flags));
++            setsockopt(ufd, SOL_SOCKET, SO_NO_CHECK, &flags, sizeof(flags));
++
++            if (bind (ufd, (struct sockaddr *) &server, sizeof (server)))
++            {
++                close (ufd);
++                l2tp_log (LOG_CRIT, "%s: Unable to bind UDP socket: %s. Terminating.\n",
++                     __FUNCTION__, strerror(errno), errno);
++                return -EINVAL;
++            };
++            server = t->peer;
++            flags = fcntl(ufd, F_GETFL);
++            if (flags == -1 || fcntl(ufd, F_SETFL, flags | O_NONBLOCK) == -1) {
++                l2tp_log (LOG_WARNING, "%s: Unable to set UDP socket nonblock.\n",
++                     __FUNCTION__);
++                return -EINVAL;
++            }
++            if (connect (ufd, (struct sockaddr *) &server, sizeof(server)) < 0) {
++                l2tp_log (LOG_CRIT, "%s: Unable to connect UDP peer. Terminating.\n",
++                 __FUNCTION__);
++                return -EINVAL;
++            }
++
++            t->udp_fd=ufd;
++
++            fd2 = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OL2TP);
++            if (fd2 < 0) {
++                l2tp_log (LOG_WARNING, "%s: Unable to allocate PPPoL2TP socket.\n",
++                     __FUNCTION__);
++                return -EINVAL;
++            }
++            flags = fcntl(fd2, F_GETFL);
++            if (flags == -1 || fcntl(fd2, F_SETFL, flags | O_NONBLOCK) == -1) {
++                l2tp_log (LOG_WARNING, "%s: Unable to set PPPoL2TP socket nonblock.\n",
++                     __FUNCTION__);
++                return -EINVAL;
++            }
++            sax.sa_family = AF_PPPOX;
++            sax.sa_protocol = PX_PROTO_OL2TP;
++            sax.pppol2tp.pid = 0;
++            sax.pppol2tp.fd = t->udp_fd;
++            sax.pppol2tp.addr.sin_addr.s_addr = t->peer.sin_addr.s_addr;
++            sax.pppol2tp.addr.sin_port = t->peer.sin_port;
++            sax.pppol2tp.addr.sin_family = AF_INET;
++            sax.pppol2tp.s_tunnel  = t->ourtid;
++            sax.pppol2tp.s_session = 0;
++            sax.pppol2tp.d_tunnel  = t->tid;
++            sax.pppol2tp.d_session = 0;
++            if ((connect(fd2, (struct sockaddr *)&sax, sizeof(sax))) < 0) {
++                l2tp_log (LOG_WARNING, "%s: Unable to connect PPPoL2TP socket. %d %s\n",
++                     __FUNCTION__, errno, strerror(errno));
++                close(fd2);
++                return -EINVAL;
++            }
++            t->pppox_fd = fd2;
++        }
++#endif
++    return 0;
++}
+diff --git a/xl2tpd.c b/xl2tpd.c
+index 307ac2e..3fb6dd7 100644
+--- a/xl2tpd.c
++++ b/xl2tpd.c
+@@ -278,7 +278,11 @@ void death_handler (int signal)
+     struct tunnel *st, *st2;
+     int sec;
+     l2tp_log (LOG_CRIT, "%s: Fatal signal %d received\n", __FUNCTION__, signal);
++#ifdef USE_KERNEL
++        if (kernel_support || signal != SIGTERM) {
++#else
+         if (signal != SIGTERM) {
++#endif
+                 st = tunnels.head;
+                 while (st)
+                 {
+@@ -349,7 +353,7 @@ int start_pppd (struct call *c, struct ppp_opts *opts)
+     int flags;
+ #endif
+     int pos = 1;
+-    int fd2;
++    int fd2 = -1;
+ #ifdef DEBUG_PPPD
+     int x;
+ #endif
+@@ -397,7 +401,7 @@ int start_pppd (struct call *c, struct ppp_opts *opts)
+        sax.sa_family = AF_PPPOX;
+        sax.sa_protocol = PX_PROTO_OL2TP;
+        sax.pppol2tp.pid = 0;
+-       sax.pppol2tp.fd = server_socket;
++       sax.pppol2tp.fd = c->container->udp_fd;
+        sax.pppol2tp.addr.sin_addr.s_addr = c->container->peer.sin_addr.s_addr;
+        sax.pppol2tp.addr.sin_port = c->container->peer.sin_port;
+        sax.pppol2tp.addr.sin_family = AF_INET;
+@@ -408,6 +412,7 @@ int start_pppd (struct call *c, struct ppp_opts *opts)
+        if (connect(fd2, (struct sockaddr *)&sax, sizeof(sax)) < 0) {
+            l2tp_log (LOG_WARNING, "%s: Unable to connect PPPoL2TP socket.\n",
+                 __FUNCTION__);
++           close(fd2);
+            return -EINVAL;
+        }
+        stropt[pos++] = strdup ("plugin");
+@@ -484,7 +489,7 @@ int start_pppd (struct call *c, struct ppp_opts *opts)
+         dup2 (fd2, 0);
+         dup2 (fd2, 1);
+       close(fd2);
+-
++       }
+         /* close all the calls pty fds */
+         st = tunnels.head;
+         while (st)
+@@ -492,12 +497,17 @@ int start_pppd (struct call *c, struct ppp_opts *opts)
+             sc = st->call_head;
+             while (sc)
+             {
+-                close (sc->fd);
++#ifdef USE_KERNEL
++                if (kernel_support) {
++                    close(st->udp_fd); /* tunnel UDP fd */
++                    close(st->pppox_fd); /* tunnel PPPoX fd */
++                } else
++#endif
++                    close (sc->fd); /* call pty fd */
+                 sc = sc->next;
+             }
+             st = st->next;
+         }
+-       }
+         /* close the UDP socket fd */
+         close (server_socket);
+@@ -615,6 +625,10 @@ void destroy_tunnel (struct tunnel *t)
+        the memory pointed to by t->chal_us.vector at some other place */
+     if (t->chal_them.vector)
+         free (t->chal_them.vector);
++    if (t->pppox_fd > -1 )
++        close (t->pppox_fd);
++    if (t->udp_fd > -1 )
++        close (t->udp_fd);
+     free (t);
+     free (me);
+ }
diff --git a/net/xl2tpd/patches/130-no-kill-ipparam.patch b/net/xl2tpd/patches/130-no-kill-ipparam.patch
new file mode 100644 (file)
index 0000000..896d391
--- /dev/null
@@ -0,0 +1,11 @@
+--- xl2tpd-1.3.1/control.c.orig        2012-04-25 12:59:28.718825985 +0100
++++ xl2tpd-1.3.1/control.c     2012-04-25 12:59:37.063916785 +0100
+@@ -905,8 +905,6 @@ int control_finish (struct tunnel *t, st
+                 po = add_opt (po, c->lac->pppoptfile);
+             }
+         };
+-      po = add_opt (po, "ipparam");
+-        po = add_opt (po, IPADDY (t->peer.sin_addr));
+         start_pppd (c, po);
+         opt_destroy (po);
+         if (c->lac)