On 25/05/20(Mon) 21:42, Sergey Ryazanov wrote:
> Add dedicated option to activate kernel L2TP acceleration via
> the pipex(4). The options should be passed by a L2TP tunnel
> management daemon (e.g. xl2tpd).

What is the difference between npppd(8) and pppd(8)?   Aren't those two
redundant?  Why did you choose to modify pppd(8) and not npppd(8)?

> This diff is complete, but kernel support in ppp(4) is not ready.
> ---
>  usr.sbin/pppd/ipcp.c    |  5 +++
>  usr.sbin/pppd/options.c | 82 +++++++++++++++++++++++++++++++++++++++++
>  usr.sbin/pppd/pppd.8    | 18 +++++++++
>  usr.sbin/pppd/pppd.h    |  7 ++++
>  usr.sbin/pppd/sys-bsd.c | 56 ++++++++++++++++++++++++++++
>  5 files changed, 168 insertions(+)
> 
> diff --git usr.sbin/pppd/ipcp.c usr.sbin/pppd/ipcp.c
> index 1296d897b14..e7a6dbd6ee7 100644
> --- usr.sbin/pppd/ipcp.c
> +++ usr.sbin/pppd/ipcp.c
> @@ -1251,6 +1251,10 @@ ipcp_up(f)
>           return;
>       }
>  
> +     /* enable pipex(4), keep working if failed */
> +     if (pipex_conf.pr_protocol && !apipex(go->ouraddr, ho->hisaddr, mask))
> +         IPCPDEBUG((LOG_WARNING, "apipex failed"));
> +
>  #if (defined(SVR4) && (defined(SNI) || defined(__USLC__)))
>       if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) {
>           IPCPDEBUG((LOG_WARNING, "sifaddr failed"));
> @@ -1304,6 +1308,7 @@ ipcp_down(f)
>      if (demand) {
>       sifnpmode(f->unit, PPP_IP, NPMODE_QUEUE);
>      } else {
> +     dpipex();
>       sifdown(f->unit);
>       ipcp_clear_addrs(f->unit);
>      }
> diff --git usr.sbin/pppd/options.c usr.sbin/pppd/options.c
> index 828f7cdce65..fe0e2e6b54b 100644
> --- usr.sbin/pppd/options.c
> +++ usr.sbin/pppd/options.c
> @@ -144,6 +144,9 @@ struct    bpf_program pass_filter;/* Filter program for 
> packets to pass */
>  struct       bpf_program active_filter; /* Filter program for link-active 
> pkts */
>  pcap_t  pc;                  /* Fake struct pcap so we can compile expr */
>  #endif
> +struct pipex_session_req pipex_conf = {      /* pipex(4) session 
> configuration */
> +  .pr_protocol = 0,
> +};
>  
>  /*
>   * Prototypes
> @@ -253,6 +256,8 @@ static int setactivefilter(char **);
>  static int setmslanman(char **);
>  #endif
>  
> +static int setpipexl2tp(char **);
> +
>  static int number_option(char *, u_int32_t *, int);
>  static int int_option(char *, int *);
>  static int readable(int fd);
> @@ -391,6 +396,8 @@ static struct cmd {
>      {"ms-lanman", 0, setmslanman},   /* Use LanMan psswd when using MS-CHAP 
> */
>  #endif
>  
> +    {"pipex-l2tp", 6, setpipexl2tp}, /* set pipex(4) L2TP parameters */
> +
>      {NULL, 0, NULL}
>  };
>  
> @@ -2283,3 +2290,78 @@ setmslanman(argv)
>      return (1);
>  }
>  #endif
> +
> +static int
> +inet_atoss(cp, ss)
> +    char *cp;
> +    struct sockaddr_storage *ss;
> +{
> +    struct sockaddr_in *sin = (struct sockaddr_in *)ss;
> +    char *c, *p;
> +    unsigned port;
> +
> +    if ((c = strchr(cp, ':')) == NULL)
> +     return 0;
> +    *c = '\0';
> +    if (!inet_aton(cp, &sin->sin_addr))
> +     return 0;
> +    if (!(port = strtoul(c + 1, &p, 10)) || *p != '\0')
> +     return 0;
> +    sin->sin_port = htons(port);
> +    sin->sin_family = AF_INET;
> +    ss->ss_len = sizeof(*sin);
> +
> +    return 1;
> +}
> +
> +static int
> +strtou16(str, valp)
> +    char *str;
> +    uint16_t *valp;
> +{
> +    char *ptr;
> +
> +    *valp = strtoul(str, &ptr, 0);
> +
> +    return *ptr == '\0' ? 1 : 0;
> +}
> +
> +static int
> +setpipexl2tp(argv)
> +    char **argv;
> +{
> +    BZERO((char *)&pipex_conf, sizeof(pipex_conf));
> +
> +    if (!inet_atoss(argv[0], &pipex_conf.pr_local_address)) {
> +     option_error("pipex-l2tp: invalid local address of tunnel: %s", 
> argv[0]);
> +     return 0;
> +    }
> +    if (!inet_atoss(argv[1], &pipex_conf.pr_peer_address)) {
> +     option_error("pipex-l2tp: invalid peer address of tunnel: %s", argv[1]);
> +     return 0;
> +    }
> +    if (!strtou16(argv[2], &pipex_conf.pr_proto.l2tp.tunnel_id)) {
> +     option_error("pipex-l2tp: invalid local tunnel id: %s", argv[2]);
> +     return 0;
> +    }
> +    if (!strtou16(argv[3], &pipex_conf.pr_proto.l2tp.peer_tunnel_id)) {
> +     option_error("pipex-l2tp: invalid peer tunnel id: %s", argv[3]);
> +     return 0;
> +    }
> +    if (!strtou16(argv[4], &pipex_conf.pr_session_id)) {
> +     option_error("pipex-l2tp: invalid local call id: %s", argv[4]);
> +     return 0;
> +    }
> +    if (!strtou16(argv[5], &pipex_conf.pr_peer_session_id)) {
> +     option_error("pipex-l2tp: invalid peer call id: %s", argv[5]);
> +     return 0;
> +    }
> +
> +    /* Indicate address field presense */
> +    pipex_conf.pr_ppp_flags = PIPEX_PPP_HAS_ACF;
> +
> +    /* Finally set the protocol type to implicitly indicate config validity 
> */
> +    pipex_conf.pr_protocol = PIPEX_PROTO_L2TP;
> +
> +    return 1;
> +}
> diff --git usr.sbin/pppd/pppd.8 usr.sbin/pppd/pppd.8
> index 5fba6f1714d..6a7f6e01c09 100644
> --- usr.sbin/pppd/pppd.8
> +++ usr.sbin/pppd/pppd.8
> @@ -829,6 +829,24 @@ option is used.
>  .It Cm xonxoff
>  Use software flow control (i.e., XON/XOFF) to control the flow of data on
>  the serial port.
> +.It Cm pipex-l2tp Ar ltunaddr ptunaddr ltunid ptunid lcallid pcallid
> +OpenBSD specific. Activate and configure kernel L2TP acceleration. Set
> +pipex(4) local tunnel address to
> +.Ar ltunaddr ,
> +peer tunnel address to
> +.Ar ptunaddr ,
> +local L2TP tunnel id to
> +.Ar ltunid ,
> +peer L2TP tunnel id to
> +.Ar ptunid ,
> +local L2TP call id (local session id in terms of pipex(4)) to
> +.Ar lcallid
> +and peer L2TP call id (peer session id in terms of pipex(4)) to
> +.Ar pcallid .
> +This option should not be specified in the options file. Instead it
> +should be passed to
> +.Nm pppd
> +by a L2TP daemon, that is responsible for L2TP tunnel establishing.
>  .El
>  .Sh OPTIONS FILES
>  Options can be taken from files as well as the command line.
> diff --git usr.sbin/pppd/pppd.h usr.sbin/pppd/pppd.h
> index 9cd332939a3..27ddc45bd78 100644
> --- usr.sbin/pppd/pppd.h
> +++ usr.sbin/pppd/pppd.h
> @@ -51,7 +51,10 @@
>  
>  #include <sys/types.h>               /* for u_int32_t, if defined */
>  #include <sys/time.h>                /* for struct timeval */
> +#include <netinet/in.h>
>  #include <net/ppp_defs.h>
> +#include <net/if.h>
> +#include <net/pipex.h>
>  #include <stdio.h>           /* for FILE */
>  #include <stdarg.h>
>  
> @@ -128,6 +131,7 @@ extern int        refuse_chap;    /* Don't wanna auth. 
> ourselves with CHAP */
>  extern struct        bpf_program pass_filter;   /* Filter for pkts to pass */
>  extern struct        bpf_program active_filter; /* Filter for link-active 
> pkts */
>  #endif
> +extern struct pipex_session_req pipex_conf; /* pipex(4) session 
> configuration */
>  
>  #ifdef MSLANMAN
>  extern int   ms_lanman;      /* Nonzero if use LanMan password instead of NT 
> */
> @@ -306,6 +310,9 @@ int  cifproxyarp(int, u_int32_t);
>  u_int32_t GetMask(u_int32_t);        /* Get appropriate netmask for address 
> */
>  int  lock(char *);           /* Create lock file for device */
>  void unlock(void);           /* Delete previously-created lock file */
> +int  apipex(u_int32_t, u_int32_t, u_int32_t);
> +                             /* Add pipex(4) to interface */
> +void dpipex(void);           /* Delete pipex(4) from interface */
>  int  daemon(int, int);               /* Detach us from terminal session */
>  void logwtmp(const char *, const char *, const char *);
>                               /* Write entry to wtmp file */
> diff --git usr.sbin/pppd/sys-bsd.c usr.sbin/pppd/sys-bsd.c
> index e8deee6d2ff..085888cf06f 100644
> --- usr.sbin/pppd/sys-bsd.c
> +++ usr.sbin/pppd/sys-bsd.c
> @@ -801,6 +801,15 @@ ppp_recv_config(unit, mru, asyncmap, pcomp, accomp)
>       syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
>       quit();
>      }
> +    /* Update pipex(4) config */
> +    if (pcomp)
> +     pipex_conf.pr_ppp_flags |= PIPEX_PPP_PFC_ACCEPTED;
> +    else
> +     pipex_conf.pr_ppp_flags &= ~PIPEX_PPP_PFC_ACCEPTED;
> +    if (accomp)
> +     pipex_conf.pr_ppp_flags |= PIPEX_PPP_ACFC_ACCEPTED;
> +    else
> +     pipex_conf.pr_ppp_flags &= ~PIPEX_PPP_ACFC_ACCEPTED;
>  }
>  
>  /*
> @@ -1510,3 +1519,50 @@ unlock()
>       lock_file = NULL;
>      }
>  }
> +
> +/*
> + * apipex - enable pipex(4) and add session
> + */
> +int
> +apipex(o, h, m)
> +    u_int32_t o, h, m;
> +{
> +    int mode = 1;
> +
> +    if (ioctl(ttyfd, PIPEXSMODE, &mode) == -1) {
> +     syslog(LOG_WARNING, "Couldn't enable pipex: %m");
> +     return -1;
> +    }
> +
> +    /* Complete session creation request */
> +    pipex_conf.pr_ip_srcaddr.s_addr = o;
> +    pipex_conf.pr_ip_address.s_addr = h;
> +    pipex_conf.pr_ip_netmask.s_addr = m;
> +
> +    if (ioctl(ttyfd, PIPEXASESSION, &pipex_conf) == -1) {
> +     syslog(LOG_WARNING, "Couldn't add pipex session: %m");
> +     return -1;
> +    }
> +
> +    return 0;
> +}
> +
> +/*
> + * dpipex - del session and disable pipex(4)
> + */
> +void
> +dpipex()
> +{
> +    struct pipex_session_close_req cr;
> +    int mode = 0;
> +
> +    /* Copy required data from the session addition request */
> +    cr.psr_protocol = pipex_conf.pr_protocol;
> +    cr.psr_session_id = pipex_conf.pr_session_id;
> +
> +    if (ioctl(ttyfd, PIPEXDSESSION, &cr) == -1)
> +     syslog(LOG_WARNING, "Couldn't del pipex session: %m");
> +
> +    if (ioctl(ttyfd, PIPEXSMODE, &mode) == -1)
> +     syslog(LOG_WARNING, "Couldn't disable pipex: %m");
> +}
> -- 
> 2.26.0
> 

Reply via email to