[xl2tpd/f17] * Fri Jun 15 2012 Paul Wouters <pwouters at redhat.com> - 1.3.1-7 - Moved modprobe code from daemon to

Paul Wouters pwouters at fedoraproject.org
Fri Jun 15 22:21:37 UTC 2012


commit 61848b58843af6cfd64bcc4c867d27e9aac62623
Author: Paul Wouters <paul at libreswan.org>
Date:   Fri Jun 15 16:27:04 2012 -0400

    * Fri Jun 15 2012 Paul Wouters <pwouters at redhat.com> - 1.3.1-7
    - Moved modprobe code from daemon to initscript/systemd
      (SElinux does not allow a daemon to do this, see rhbz#832149)

 xl2tpd-1.3.1-kernelmode.patch |  362 +++++++++++++++++++++++++++++++++++++++++
 xl2tpd.init                   |    6 +
 xl2tpd.service                |    2 +
 xl2tpd.spec                   |    8 +-
 4 files changed, 376 insertions(+), 2 deletions(-)
---
diff --git a/xl2tpd-1.3.1-kernelmode.patch b/xl2tpd-1.3.1-kernelmode.patch
new file mode 100644
index 0000000..34c2e09
--- /dev/null
+++ b/xl2tpd-1.3.1-kernelmode.patch
@@ -0,0 +1,362 @@
+diff -Naur xl2tpd-1.3.1-orig/call.c xl2tpd-1.3.1/call.c
+--- xl2tpd-1.3.1-orig/call.c	2011-10-06 15:22:05.000000000 -0400
++++ xl2tpd-1.3.1/call.c	2012-06-15 15:57:17.250953288 -0400
+@@ -680,6 +680,8 @@
+         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 -Naur xl2tpd-1.3.1-orig/control.c xl2tpd-1.3.1/control.c
+--- xl2tpd-1.3.1-orig/control.c	2012-06-15 15:56:30.169585604 -0400
++++ xl2tpd-1.3.1/control.c	2012-06-15 15:57:17.251953296 -0400
+@@ -596,6 +596,9 @@
+         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 @@
+ 		  "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 @@
+ 		  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 -Naur xl2tpd-1.3.1-orig/l2tp.h xl2tpd-1.3.1/l2tp.h
+--- xl2tpd-1.3.1-orig/l2tp.h	2011-10-06 15:22:05.000000000 -0400
++++ xl2tpd-1.3.1/l2tp.h	2012-06-15 15:57:17.251953296 -0400
+@@ -167,6 +167,8 @@
+     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 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 -Naur xl2tpd-1.3.1-orig/Makefile xl2tpd-1.3.1/Makefile
+--- xl2tpd-1.3.1-orig/Makefile	2011-10-06 15:22:05.000000000 -0400
++++ xl2tpd-1.3.1/Makefile	2012-06-15 15:57:17.250953288 -0400
+@@ -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 at gmail.com>
++OSFLAGS+= -DUSE_KERNEL
+ #
+ # Uncomment the next line for FreeBSD
+ #
+diff -Naur xl2tpd-1.3.1-orig/network.c xl2tpd-1.3.1/network.c
+--- xl2tpd-1.3.1-orig/network.c	2012-06-15 15:56:30.169585604 -0400
++++ xl2tpd-1.3.1/network.c	2012-06-15 16:00:26.259429931 -0400
+@@ -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,7 +37,6 @@
+ int kernel_support;             /* Kernel Support there or not? */
+ #endif
+ 
+-
+ int init_network (void)
+ {
+     long arg;
+@@ -45,6 +45,7 @@
+     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 +53,10 @@
+         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);
+@@ -94,7 +99,7 @@
+         int kernel_fd = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OL2TP);
+         if (kernel_fd < 0)
+         {
+-            l2tp_log (LOG_INFO, "L2TP kernel support not detected.\n");
++            l2tp_log (LOG_INFO, "L2TP kernel support not detected (try modprobing l2tp_ppp and pppol2tp)\n");
+             kernel_support = 0;
+         }
+         else
+@@ -321,6 +326,11 @@
+ 
+ 	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 +400,8 @@
+     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 +440,21 @@
+         {
+             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.
+@@ -456,12 +482,19 @@
+ 	    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",
+@@ -566,6 +599,8 @@
+ 		}
+ 	    };
+ 	}
++	if (st) st=st->next;
++	}
+ 
+ 	/*
+ 	 * finished obvious sources, look for data from PPP connections.
+@@ -638,3 +673,82 @@
+     }
+ 
+ }
++
++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 -Naur xl2tpd-1.3.1-orig/xl2tpd.c xl2tpd-1.3.1/xl2tpd.c
+--- xl2tpd-1.3.1-orig/xl2tpd.c	2011-10-06 15:22:05.000000000 -0400
++++ xl2tpd-1.3.1/xl2tpd.c	2012-06-15 15:57:25.189015286 -0400
+@@ -278,7 +278,11 @@
+     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 flags;
+ #endif
+     int pos = 1;
+-    int fd2;
++    int fd2 = -1;
+ #ifdef DEBUG_PPPD
+     int x;
+ #endif
+@@ -397,7 +401,7 @@
+        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 @@
+        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 @@
+         dup2 (fd2, 0);
+         dup2 (fd2, 1);
+ 	close(fd2);
+-
++       }
+         /* close all the calls pty fds */
+         st = tunnels.head;
+         while (st)
+@@ -492,12 +497,17 @@
+             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 @@
+        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/xl2tpd.init b/xl2tpd.init
index e0494e3..8f20b9d 100644
--- a/xl2tpd.init
+++ b/xl2tpd.init
@@ -39,6 +39,12 @@ RETVAL=0
 
 start() {
 	echo -n "Starting $SERVICE: "
+
+	# Look for the L2TP kernel handler module, load when needed
+	if [ ! -d /sys/module/l2tp_ppp ]; then modprobe l2tp_ppp
+	# if still not found, try legacy one
+	if [ ! -d /sys/module/l2tp_ppp ]; then modprobe pppol2tp
+
 	if [ ! -d /var/run/xl2tpd ]
 	then
 		mkdir /var/run/xl2tpd
diff --git a/xl2tpd.service b/xl2tpd.service
index b17a447..d222874 100644
--- a/xl2tpd.service
+++ b/xl2tpd.service
@@ -7,7 +7,9 @@ Wants=openswan.service
 [Service]
 Type=simple
 PIDFile=/var/run/xl2tpd/xl2tpd.pid
+ExecStartPre=/sbin/modprobe -q l2tp_ppp
 ExecStart=/usr/sbin/xl2tpd -D
+Restart=on-abort
 
 [Install]
 WantedBy=multi-user.target
diff --git a/xl2tpd.spec b/xl2tpd.spec
index d0b360f..60672d9 100644
--- a/xl2tpd.spec
+++ b/xl2tpd.spec
@@ -1,7 +1,7 @@
 Summary: Layer 2 Tunnelling Protocol Daemon (RFC 2661)
 Name: xl2tpd
 Version: 1.3.1
-Release: 6%{?dist}
+Release: 7%{?dist}
 License: GPL+
 Url: http://www.xelerance.com/software/xl2tpd/
 Group: System Environment/Daemons
@@ -10,7 +10,7 @@ Source1: xl2tpd.service
 Source2: tmpfiles-xl2tpd.conf
 Patch1: xl2tpd-1.3.1-Wunused.patch
 Patch2: xl2tpd-bz80693.patch
-Patch3: xl2tpd-1.3.0-kernelmode.patch
+Patch3: xl2tpd-1.3.1-kernelmode.patch
 Patch4: xl2tpd-1.3.1-conf.patch
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 Requires: ppp >= 2.4.5-18
@@ -118,6 +118,10 @@ fi
 %ghost %attr(0600,root,root) %{_localstatedir}/run/xl2tpd/l2tp-control
 
 %changelog
+* Fri Jun 15 2012 Paul Wouters <pwouters at redhat.com> - 1.3.1-7
+- Moved modprobe code from daemon to initscript/systemd
+  (SElinux does not allow a daemon to do this, see rhbz#832149)
+
 * Tue Jun 12 2012 Paul Wouters <pwouters at redhat.com> - 1.3.1-6
 - Added patch for xl2tpd.conf to improve interop settings
   (no longer need to say "no encryption" on Windows)


More information about the scm-commits mailing list