Ticket #11058: xl2tpd-1.3.0-0001-Add-kernel-support-for-2.6.32.patch

File xl2tpd-1.3.0-0001-Add-kernel-support-for-2.6.32.patch, 10.5 KB (added by Igor Novgorodov <igor@…>, 5 years ago)
  • Makefile

    diff --git a/Makefile b/Makefile
    index 6f6481f..778f38d 100644
    a b OSFLAGS?= -DLINUX -I$(KERNELSRC)/include/ 
    6262# are packages seperately (eg kernel-headers on Fedora) 
    6363# Note: 2.6.23+ support still needs some changes in the xl2tpd source 
    6464# 
    65 #OSFLAGS+= -DUSE_KERNEL 
     65OSFLAGS+= -DUSE_KERNEL 
    6666# 
    6767# 
    6868# Uncomment the next line for FreeBSD 
  • call.c

    diff --git a/call.c b/call.c
    index d1b1858..9d4f27d 100644
    a b struct call *get_call (int tunnel, int call, struct in_addr addr, int port, 
    680680        st->peer.sin_port = port; 
    681681        st->refme  = refme; 
    682682        st->refhim = refhim; 
     683        st->u_fd = -1; 
     684        st->m_fd = -1; 
    683685        bcopy (&addr, &st->peer.sin_addr, sizeof (addr)); 
    684686        st->next = tunnels.head; 
    685687        tunnels.head = st; 
  • control.c

    diff --git a/control.c b/control.c
    index 0892df9..9362ffd 100644
    a b int control_finish (struct tunnel *t, struct call *c) 
    596596        if (gconfig.debug_state) 
    597597            l2tp_log (LOG_DEBUG, "%s: sending SCCCN\n", __FUNCTION__); 
    598598        control_xmit (buf); 
     599 
     600        connect_pppol2tp(t); 
     601 
    599602        /* Schedule a HELLO */ 
    600603        tv.tv_sec = HELLO_DELAY; 
    601604        tv.tv_usec = 0; 
    int control_finish (struct tunnel *t, struct call *c) 
    608611                  "Connection established to %s, %d.  Local: %d, Remote: %d (ref=%u/%u).\n", 
    609612                  IPADDY (t->peer.sin_addr), 
    610613                  ntohs (t->peer.sin_port), t->ourtid, t->tid, t->refme, t->refhim); 
     614 
    611615        if (t->lac) 
    612616        { 
    613617            /* This is part of a LAC, so we want to go ahead 
    int control_finish (struct tunnel *t, struct call *c) 
    635639                  IPADDY (t->peer.sin_addr), 
    636640                  ntohs (t->peer.sin_port), t->ourtid, t->tid, t->refme, t->refhim, 
    637641                  t->lns->entname); 
     642 
     643        connect_pppol2tp(t); 
     644 
    638645        /* Schedule a HELLO */ 
    639646        tv.tv_sec = HELLO_DELAY; 
    640647        tv.tv_usec = 0; 
  • l2tp.h

    diff --git a/l2tp.h b/l2tp.h
    index ac22f3f..62ad6c1 100644
    a b struct tunnel 
    167167    int ourrws;                 /* Receive Window Size */ 
    168168    int rxspeed;                /* Receive bps */ 
    169169    int txspeed;                /* Transmit bps */ 
     170    int u_fd;                   /* UDP fd */ 
     171    int m_fd;                   /* PPPOX fd */ 
    170172    struct call *self; 
    171173    struct lns *lns;            /* LNS that owns us */ 
    172174    struct lac *lac;            /* LAC that owns us */ 
    extern void control_xmit (void *); 
    220222extern int ppd; 
    221223extern int switch_io;           /* jz */ 
    222224extern int control_fd; 
     225extern int connect_pppol2tp(struct tunnel * t); 
    223226extern int start_pppd (struct call *c, struct ppp_opts *); 
    224227extern void magic_lac_dial (void *); 
    225228extern int get_entropy (unsigned char *, int); 
  • linux/include/linux/if_pppol2tp.h

    diff --git a/linux/include/linux/if_pppol2tp.h b/linux/include/linux/if_pppol2tp.h
    index a7d6a22..0795e4a 100644
    a b struct pppol2tp_addr 
    3636        __u16 d_tunnel, d_session;      /* For sending outgoing packets */ 
    3737}; 
    3838 
     39/* The L2TPv3 protocol changes tunnel and session ids from 16 to 32 
     40 * bits. So we need a different sockaddr structure. 
     41 */ 
     42struct pppol2tpv3_addr { 
     43        pid_t   pid;                    /* pid that owns the fd. 
     44                                         * 0 => current */ 
     45        int     fd;                     /* FD of UDP or IP socket to use */ 
     46 
     47        struct sockaddr_in addr;        /* IP address and port to send to */ 
     48 
     49        __u32 s_tunnel, s_session;      /* For matching incoming packets */ 
     50        __u32 d_tunnel, d_session;      /* For sending outgoing packets */ 
     51}; 
     52 
    3953/* Socket options: 
    4054 * DEBUG        - bitmask of debug message categories 
    4155 * SENDSEQ      - 0 => don't send packets with sequence numbers 
  • network.c

    diff --git a/network.c b/network.c
    index 783a181..86c0940 100644
    a b  
    22 * Layer Two Tunnelling Protocol Daemon 
    33 * Copyright (C) 1998 Adtran, Inc. 
    44 * Copyright (C) 2002 Jeff McAdams 
     5 * Portions copyright (c) 2011 wl500g.googlecode.com project 
    56 * 
    67 * Mark Spencer 
    78 * 
    int init_network (void) 
    5253        return -EINVAL; 
    5354    }; 
    5455 
     56    int flags=1; 
     57    setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &flags, sizeof(flags)); 
     58    setsockopt(server_socket, SOL_SOCKET, SO_NO_CHECK, &flags, sizeof(flags)); 
     59 
    5560    if (bind (server_socket, (struct sockaddr *) &server, sizeof (server))) 
    5661    { 
    5762        close (server_socket); 
    int build_fdset (fd_set *readfds) 
    321326 
    322327        while (tun) 
    323328        { 
     329                if (tun->u_fd > -1) { 
     330                        if (tun->u_fd > max) 
     331                                max = tun->u_fd; 
     332                        FD_SET (tun->u_fd, readfds); 
     333                } 
    324334                call = tun->call_head; 
    325335                while (call) 
    326336                { 
    void network_thread () 
    428438        { 
    429439            do_control (); 
    430440        } 
    431         if (FD_ISSET (server_socket, &readfds)) 
     441        int server_socket_processed = 0; 
     442        int * currentfd = NULL; 
     443        int oldfd = server_socket; 
     444        st = tunnels.head; 
     445        while (st || !server_socket_processed) { 
     446            if (st && (st->u_fd == -1)) { 
     447                st=st->next; 
     448                continue; 
     449            } 
     450            if (st) { 
     451                currentfd = &st->u_fd; 
     452            } else { 
     453                currentfd = &server_socket; 
     454                server_socket_processed = 1; 
     455            } 
     456        if (FD_ISSET (*currentfd, &readfds)) 
    432457        { 
    433458            /* 
    434459             * Okay, now we're ready for reading and processing new data. 
    void network_thread () 
    457482            msgh.msg_flags = 0; 
    458483             
    459484            /* Receive one packet. */ 
    460             recvsize = recvmsg(server_socket, &msgh, 0); 
     485            recvsize = recvmsg(*currentfd, &msgh, 0); 
    461486 
    462487            if (recvsize < MIN_PAYLOAD_HDR_LEN) 
    463488            { 
    464489                if (recvsize < 0) 
    465490                { 
     491                    if (errno == ECONNREFUSED) { 
     492                        close(*currentfd); 
     493                    } 
     494                    if ((errno == ECONNREFUSED) || 
     495                        (errno == EBADF)) { 
     496                        *currentfd = -1; 
     497                    } 
    466498                    if (errno != EAGAIN) 
    467499                        l2tp_log (LOG_WARNING, 
    468500                             "%s: recvfrom returned error %d (%s)\n", 
    void network_thread () 
    567599                } 
    568600            }; 
    569601        } 
     602        if (st) st=st->next; 
     603        } 
    570604 
    571605        /* 
    572606         * finished obvious sources, look for data from PPP connections. 
    void network_thread () 
    639673    } 
    640674 
    641675} 
     676 
     677int connect_pppol2tp(struct tunnel * t) { 
     678#ifdef USE_KERNEL 
     679        if (kernel_support) { 
     680            int ufd = -1, fd2 = -1; 
     681            int flags; 
     682            struct sockaddr_pppol2tp sax; 
     683            socklen_t sock_len; 
     684 
     685            struct sockaddr_in server; 
     686            server.sin_family = AF_INET; 
     687            server.sin_addr.s_addr = gconfig.listenaddr; 
     688            server.sin_port = htons (gconfig.port); 
     689            if ((ufd = socket (PF_INET, SOCK_DGRAM, 0)) < 0) 
     690            { 
     691                l2tp_log (LOG_CRIT, "%s: Unable to allocate UDP socket. Terminating.\n", 
     692                    __FUNCTION__); 
     693                return -EINVAL; 
     694            }; 
     695 
     696            flags=1; 
     697            setsockopt(ufd, SOL_SOCKET, SO_REUSEADDR, &flags, sizeof(flags)); 
     698            setsockopt(ufd, SOL_SOCKET, SO_NO_CHECK, &flags, sizeof(flags)); 
     699 
     700            if (bind (ufd, (struct sockaddr *) &server, sizeof (server))) 
     701            { 
     702                close (ufd); 
     703                l2tp_log (LOG_CRIT, "%s: Unable to bind UDP socket: %s. Terminating.\n", 
     704                     __FUNCTION__, strerror(errno), errno); 
     705                return -EINVAL; 
     706            }; 
     707            server = t->peer; 
     708            flags = fcntl(ufd, F_GETFL); 
     709            if (flags == -1 || fcntl(ufd, F_SETFL, flags | O_NONBLOCK) == -1) { 
     710                l2tp_log (LOG_WARNING, "%s: Unable to set UDP socket nonblock.\n", 
     711                     __FUNCTION__); 
     712                return -EINVAL; 
     713            } 
     714            if (connect (ufd, (struct sockaddr *) &server, sizeof(server)) < 0) { 
     715                l2tp_log (LOG_CRIT, "%s: Unable to connect UDP peer. Terminating.\n", 
     716                 __FUNCTION__); 
     717                return -EINVAL; 
     718            } 
     719 
     720            t->u_fd=ufd; 
     721 
     722            fd2 = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OL2TP); 
     723            if (fd2 < 0) { 
     724                l2tp_log (LOG_WARNING, "%s: Unable to allocate PPPoL2TP socket.\n", 
     725                     __FUNCTION__); 
     726                return -EINVAL; 
     727            } 
     728            flags = fcntl(fd2, F_GETFL); 
     729            if (flags == -1 || fcntl(fd2, F_SETFL, flags | O_NONBLOCK) == -1) { 
     730                l2tp_log (LOG_WARNING, "%s: Unable to set PPPoL2TP socket nonblock.\n", 
     731                     __FUNCTION__); 
     732                return -EINVAL; 
     733            } 
     734            sax.sa_family = AF_PPPOX; 
     735            sax.sa_protocol = PX_PROTO_OL2TP; 
     736            sax.pppol2tp.pid = 0; 
     737            sax.pppol2tp.fd = t->u_fd; 
     738            sax.pppol2tp.addr.sin_addr.s_addr = t->peer.sin_addr.s_addr; 
     739            sax.pppol2tp.addr.sin_port = t->peer.sin_port; 
     740            sax.pppol2tp.addr.sin_family = AF_INET; 
     741            sax.pppol2tp.s_tunnel  = t->ourtid; 
     742            sax.pppol2tp.s_session = 0; 
     743            sax.pppol2tp.d_tunnel  = t->tid; 
     744            sax.pppol2tp.d_session = 0; 
     745            if ((connect(fd2, (struct sockaddr *)&sax, sizeof(sax))) < 0) { 
     746                l2tp_log (LOG_WARNING, "%s: Unable to connect PPPoL2TP socket. %d %s\n", 
     747                     __FUNCTION__, errno, strerror(errno)); 
     748                close(fd2); 
     749                return -EINVAL; 
     750            } 
     751            t->m_fd = fd2; 
     752        } 
     753#endif 
     754} 
  • xl2tpd.c

    diff --git a/xl2tpd.c b/xl2tpd.c
    index 307ac2e..8f4d6d9 100644
    a b int start_pppd (struct call *c, struct ppp_opts *opts) 
    397397       sax.sa_family = AF_PPPOX; 
    398398       sax.sa_protocol = PX_PROTO_OL2TP; 
    399399       sax.pppol2tp.pid = 0; 
    400        sax.pppol2tp.fd = server_socket; 
     400       sax.pppol2tp.fd = c->container->u_fd; 
    401401       sax.pppol2tp.addr.sin_addr.s_addr = c->container->peer.sin_addr.s_addr; 
    402402       sax.pppol2tp.addr.sin_port = c->container->peer.sin_port; 
    403403       sax.pppol2tp.addr.sin_family = AF_INET; 
    int start_pppd (struct call *c, struct ppp_opts *opts) 
    408408       if (connect(fd2, (struct sockaddr *)&sax, sizeof(sax)) < 0) { 
    409409           l2tp_log (LOG_WARNING, "%s: Unable to connect PPPoL2TP socket.\n", 
    410410                __FUNCTION__); 
     411           close(fd2); 
    411412           return -EINVAL; 
    412413       } 
    413414       stropt[pos++] = strdup ("plugin"); 
    void destroy_tunnel (struct tunnel *t) 
    615616       the memory pointed to by t->chal_us.vector at some other place */ 
    616617    if (t->chal_them.vector) 
    617618        free (t->chal_them.vector); 
     619    if (t->m_fd > -1 ) 
     620        close (t->m_fd); 
     621    if (t->u_fd > -1 ) 
     622        close (t->u_fd); 
    618623    free (t); 
    619624    free (me); 
    620625}