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 >