Re: Drop IPSec traffic that should be encapsulated but is not
On Thu, Sep 01 2016 at 46:18, Vincent Gross wrote: > On Thu, 1 Sep 2016 18:02:14 +0200 > Claer <cl...@claer.hammock.fr> wrote: > > > Hello, > > > > In some production systems, I'm still using an old patch to isakmpd for > > Nat-t. When negociating SAs with ASA peers and OpenBSD is nated, you have > > issues during negociation. The following discutions explain the issue > > > > http://openbsd.7691.n7.nabble.com/isakmpd-NAT-T-interoperability-td173004.html > > http://marc.info/?l=openbsd-tech=139140140105433=2 > > > > I think the patch is related to the parts of the code you are working on. > > > > Actually it is not. The issue you are referencing is in isakmpd, > whereas the diff below is in the OpenBSD kernel. Totally different > stuff. I do not plan to look at isakmpd at the moment, as it only > supports IKEv1, and its code is nearly twice the size of iked. > > I do not have Cisco gear available to test, is this issue present when > opening NAT-T tunnels with iked ? Sorry I overlooked your diff. Unfortunately I didn't have the opportunity to test with an ASA and iked. I don't have any ASA on hand (usually they are on the client's side :)) > Cheers Thanks for your time! Claer > > Would you mind looking at this issue also? :) > > > > Thanks! > > > > Claer > > > > On Thu, Sep 01 2016 at 31:10, Vincent Gross wrote: > > > > > Our IPSec stack rejects UDP-encapsulated traffic using a non > > > encapsulating SA, but not the other way around. This diff adds > > > the missing check and the corresponding stat counter. > > > > > > Ok ? > > > > > > Index: sys/netinet/ip_esp.h > > > === > > > RCS file: /cvs/src/sys/netinet/ip_esp.h,v > > > retrieving revision 1.42 > > > diff -u -p -r1.42 ip_esp.h > > > --- sys/netinet/ip_esp.h 10 Jan 2010 12:43:07 - > > > 1.42 +++ sys/netinet/ip_esp.h 1 Sep 2016 08:24:15 - > > > @@ -62,6 +62,7 @@ struct espstat > > > u_int32_tesps_udpencin; /* Input ESP-in-UDP packets */ > > > u_int32_tesps_udpencout; /* Output ESP-in-UDP packets > > > */ u_int32_t esps_udpinval; /* Invalid input ESP-in-UDP > > > packets */ > > > +u_int32_tesps_udpneeded; /* Trying to use a ESP-in-UDP > > > TDB */ }; > > > > > > /* > > > Index: sys/netinet/ipsec_input.c > > > === > > > RCS file: /cvs/src/sys/netinet/ipsec_input.c,v > > > retrieving revision 1.135 > > > diff -u -p -r1.135 ipsec_input.c > > > --- sys/netinet/ipsec_input.c 10 Sep 2015 17:52:05 > > > - 1.135 +++ sys/netinet/ipsec_input.c 1 Sep 2016 > > > 08:24:16 - @@ -262,6 +262,16 @@ ipsec_common_input(struct mbuf > > > *m, int s return EINVAL; > > > } > > > > > > + if (!udpencap && (tdbp->tdb_flags & TDBF_UDPENCAP)) { > > > + splx(s); > > > + DPRINTF(("ipsec_common_input(): attempted to use > > > udpencap " > > > + "SA %s/%08x/%u\n", ipsp_address(_address, > > > buf, > > > + sizeof(buf)), ntohl(spi), tdbp->tdb_sproto)); > > > + m_freem(m); > > > + espstat.esps_udpneeded++; > > > + return EINVAL; > > > + } > > > + > > > if (tdbp->tdb_xform == NULL) { > > > splx(s); > > > DPRINTF(("ipsec_common_input(): attempted to use > > > uninitialized " Index: usr.bin/netstat/inet.c > > > === > > > RCS file: /cvs/src/usr.bin/netstat/inet.c,v > > > retrieving revision 1.150 > > > diff -u -p -r1.150 inet.c > > > --- usr.bin/netstat/inet.c27 Aug 2016 04:13:43 - > > > 1.150 +++ usr.bin/netstat/inet.c 1 Sep 2016 08:24:16 - > > > @@ -1073,6 +1073,7 @@ esp_stats(char *name) > > > p(esps_udpencin, "\t%u input UDP encapsulated ESP > > > packet%s\n"); p(esps_udpencout, "\t%u output UDP encapsulated ESP > > > packet%s\n"); p(esps_udpinval, "\t%u UDP packet%s for > > > non-encapsulating TDB received\n"); > > > + p(esps_udpneeded, "\t%u raw ESP packet%s for encapsulating > > > TDB received\n"); p(esps_ibytes, "\t%llu input byte%s\n"); > > > p(esps_obytes, "\t%llu output byte%s\n"); > > > > > > >
Re: Drop IPSec traffic that should be encapsulated but is not
Hello, In some production systems, I'm still using an old patch to isakmpd for Nat-t. When negociating SAs with ASA peers and OpenBSD is nated, you have issues during negociation. The following discutions explain the issue http://openbsd.7691.n7.nabble.com/isakmpd-NAT-T-interoperability-td173004.html http://marc.info/?l=openbsd-tech=139140140105433=2 I think the patch is related to the parts of the code you are working on. Would you mind looking at this issue also? :) Thanks! Claer On Thu, Sep 01 2016 at 31:10, Vincent Gross wrote: > Our IPSec stack rejects UDP-encapsulated traffic using a non > encapsulating SA, but not the other way around. This diff adds > the missing check and the corresponding stat counter. > > Ok ? > > Index: sys/netinet/ip_esp.h > === > RCS file: /cvs/src/sys/netinet/ip_esp.h,v > retrieving revision 1.42 > diff -u -p -r1.42 ip_esp.h > --- sys/netinet/ip_esp.h 10 Jan 2010 12:43:07 - 1.42 > +++ sys/netinet/ip_esp.h 1 Sep 2016 08:24:15 - > @@ -62,6 +62,7 @@ struct espstat > u_int32_tesps_udpencin; /* Input ESP-in-UDP packets */ > u_int32_tesps_udpencout; /* Output ESP-in-UDP packets */ > u_int32_tesps_udpinval; /* Invalid input ESP-in-UDP packets */ > +u_int32_tesps_udpneeded; /* Trying to use a ESP-in-UDP TDB */ > }; > > /* > Index: sys/netinet/ipsec_input.c > === > RCS file: /cvs/src/sys/netinet/ipsec_input.c,v > retrieving revision 1.135 > diff -u -p -r1.135 ipsec_input.c > --- sys/netinet/ipsec_input.c 10 Sep 2015 17:52:05 - 1.135 > +++ sys/netinet/ipsec_input.c 1 Sep 2016 08:24:16 - > @@ -262,6 +262,16 @@ ipsec_common_input(struct mbuf *m, int s > return EINVAL; > } > > + if (!udpencap && (tdbp->tdb_flags & TDBF_UDPENCAP)) { > + splx(s); > + DPRINTF(("ipsec_common_input(): attempted to use udpencap " > + "SA %s/%08x/%u\n", ipsp_address(_address, buf, > + sizeof(buf)), ntohl(spi), tdbp->tdb_sproto)); > + m_freem(m); > + espstat.esps_udpneeded++; > + return EINVAL; > + } > + > if (tdbp->tdb_xform == NULL) { > splx(s); > DPRINTF(("ipsec_common_input(): attempted to use uninitialized " > Index: usr.bin/netstat/inet.c > === > RCS file: /cvs/src/usr.bin/netstat/inet.c,v > retrieving revision 1.150 > diff -u -p -r1.150 inet.c > --- usr.bin/netstat/inet.c27 Aug 2016 04:13:43 - 1.150 > +++ usr.bin/netstat/inet.c1 Sep 2016 08:24:16 - > @@ -1073,6 +1073,7 @@ esp_stats(char *name) > p(esps_udpencin, "\t%u input UDP encapsulated ESP packet%s\n"); > p(esps_udpencout, "\t%u output UDP encapsulated ESP packet%s\n"); > p(esps_udpinval, "\t%u UDP packet%s for non-encapsulating TDB > received\n"); > + p(esps_udpneeded, "\t%u raw ESP packet%s for encapsulating TDB > received\n"); > p(esps_ibytes, "\t%llu input byte%s\n"); > p(esps_obytes, "\t%llu output byte%s\n"); > >
Patches for improving npppd with rdomain support [11-12/12]
Hello, Patches 11 & 12. # HG changeset patch # User MJP # Date 1452862954 -3600 # Fri Jan 15 14:02:34 2016 +0100 # Node ID 5c95b08cdd4fa9db47ced3b8b1a331dbdab41ec6 # Parent 842c1c22848e171f174cc45ba7b961883fc3c184 Feature: Configure interface with the specified rdomain. diff -r 842c1c22848e -r 5c95b08cdd4f usr.sbin/npppd/npppd/npppd_iface.c --- usr.sbin/npppd/npppd/npppd_iface.c Fri Jan 15 14:02:34 2016 +0100 +++ usr.sbin/npppd/npppd/npppd_iface.c Fri Jan 15 14:02:34 2016 +0100 @@ -87,6 +87,7 @@ #endif static void npppd_iface_network_input(npppd_iface *, u_char *, int); +static int npppd_iface_setup_rdomain(npppd_iface *); static int npppd_iface_setup_ip(npppd_iface *); static void npppd_iface_io_event_handler (int, short, void *); static int npppd_iface_log (npppd_iface *, int, const char *, ...) @@ -111,15 +112,28 @@ _this->using_pppx = iface->is_pppx; _this->set_ip4addr = 1; _this->ip4addr = iface->ip4addr; + _this->rdomain = iface->rdomain; _this->ipcpconf = iface->ipcpconf; _this->devf = -1; _this->initialized = 1; } static int +npppd_iface_setup_rdomain(npppd_iface *_this) +{ + if (priv_set_if_rdomain(_this->ifname, _this->rdomain) != 0) { + npppd_iface_log(_this, LOG_ERR, + "setting rdomain on %s failed: %m", _this->ifname); + return 1; + } + + return 0; +} + +static int npppd_iface_setup_ip(npppd_iface *_this) { - int sock, if_flags, changed; + int sock, if_flags, changed, old_rdomain; struct in_addr gw, assigned; struct sockaddr_in *sin0; struct ifreq ifr; @@ -152,6 +166,17 @@ if (assigned.s_addr != _this->ip4addr.s_addr) changed = 1; + /* get rdomain which was assigned to interface */ + if (priv_get_if_rdomain(_this->ifname, _rdomain) != 0) { + log_printf(LOG_ERR, "ioctl(,SIOCGIFRDOMAIN) failed: %m", __func__); + goto fail; + } + if (_this->rdomain != old_rdomain) { + changed = 1; + if (npppd_iface_setup_rdomain(_this) != 0) + goto fail; + } + if (priv_get_if_flags(_this->ifname, _flags) != 0) { npppd_iface_log(_this, LOG_ERR, "ioctl(,SIOCGIFFLAGS) failed: %m"); @@ -195,7 +220,7 @@ /* erase old route */ if (assigned.s_addr != 0) { gw.s_addr = htonl(INADDR_LOOPBACK); - in_host_route_delete(, , _this->rdomain); + in_host_route_delete(, , old_rdomain); } assigned.s_addr = _this->ip4addr.s_addr; @@ -252,9 +277,15 @@ _this->ipcpconf = iface->ipcpconf; backup = _this->ip4addr; _this->ip4addr = iface->ip4addr; + _this->rdomain = iface->rdomain; - if (_this->using_pppx) + if (_this->using_pppx) { + /* ifconfig tun1 rdomain X */ + if (npppd_iface_setup_rdomain(_this) != 0) + return 1; + return 0; + } if ((rval = npppd_iface_setup_ip(_this)) != 0) return rval; @@ -312,6 +343,9 @@ if (_this->using_pppx == 0) { if (npppd_iface_setup_ip(_this) != 0) goto fail; + } else { + if (npppd_iface_setup_rdomain(_this) != 0) + goto fail; } #ifdef USE_NPPPD_PIPEX # HG changeset patch # User MJP # Date 1452862954 -3600 # Fri Jan 15 14:02:34 2016 +0100 # Node ID 51e9ae42d8660dcf396d3781b01e70e837f57107 # Parent 5c95b08cdd4fa9db47ced3b8b1a331dbdab41ec6 Documentation: Update the manual page (interface [rdomain]). diff -r 5c95b08cdd4f -r 51e9ae42d866 usr.sbin/npppd/npppd/npppd.conf.5 --- usr.sbin/npppd/npppd/npppd.conf.5 Fri Jan 15 14:02:34 2016 +0100 +++ usr.sbin/npppd/npppd/npppd.conf.5 Fri Jan 15 14:02:34 2016 +0100 @@ -520,7 +520,7 @@ .Ic interface setting is described below: .Pp -.Ic interface Ar ifname Ic address Ar address Ic ipcp Ar ipcp +.Ic interface Ar ifname Ic address Ar address Ic ipcp Ar ipcp Op Ic rdomain Ar rdomainid .Pp Use .Xr tun 4
Patches for improving npppd with rdomain support [8/12]
Hello, Patch 8 # HG changeset patch # User MJP # Date 1452862954 -3600 # Fri Jan 15 14:02:34 2016 +0100 # Node ID 55eeedfb0cb54ed0d91c7de080b507fc79f64c30 # Parent 8d76f9f8cc873602c8593b896133648cdedb6afd Add: Introduce priv_get_if_rdomain() to get the rdomain of a device. diff -r 8d76f9f8cc87 -r 55eeedfb0cb5 usr.sbin/npppd/npppd/privsep.c --- usr.sbin/npppd/npppd/privsep.c Fri Jan 15 14:02:34 2016 +0100 +++ usr.sbin/npppd/npppd/privsep.c Fri Jan 15 14:02:34 2016 +0100 @@ -54,7 +54,8 @@ PRIVSEP_SET_IF_ADDR, PRIVSEP_DEL_IF_ADDR, PRIVSEP_GET_IF_FLAGS, - PRIVSEP_SET_IF_FLAGS + PRIVSEP_SET_IF_FLAGS, + PRIVSEP_GET_IF_RDOMAIN }; struct PRIVSEP_OPEN_ARG { @@ -126,6 +127,17 @@ int flags; }; +struct PRIVSEP_GET_IF_RDOMAIN_ARG { + char ifname[IFNAMSIZ]; + u_intrdomain; +}; + +struct PRIVSEP_GET_IF_RDOMAIN_RESP { + int retval; + int rerrno; + u_intrdomain; +}; + struct PRIVSEP_COMMON_RESP { int retval; int rerrno; @@ -164,6 +176,8 @@ struct PRIVSEP_GET_IF_FLAGS_ARG *); static int privsep_npppd_check_set_if_flags ( struct PRIVSEP_SET_IF_FLAGS_ARG *); +static int privsep_npppd_check_get_if_rdomain ( + struct PRIVSEP_GET_IF_RDOMAIN_ARG *); static int privsep_sock = -1; static struct imsgbuf privsep_ibuf; @@ -512,6 +526,37 @@ return (privsep_common_resp()); } +int +priv_get_if_rdomain(const char *ifname, int *prdomain) +{ + struct PRIVSEP_GET_IF_RDOMAIN_ARGa; + struct PRIVSEP_GET_IF_RDOMAIN_RESP *r; + struct imsg imsg; + int retval = -1; + + strlcpy(a.ifname, ifname, sizeof(a.ifname)); + a.rdomain = 0; + + (void)imsg_compose(_ibuf, PRIVSEP_GET_IF_RDOMAIN, 0, 0, -1, + , sizeof(a)); + imsg_flush(_ibuf); + + if (imsg_read_and_get(_ibuf, ) == -1) + return (-1); + if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(*r)) + errno = EACCES; + else { + r = imsg.data; + *prdomain = r->rdomain; + if (r->retval != 0) + errno = r->rerrno; + retval = r->retval; + } + imsg_free(); + + return (retval); +} + static int privsep_recvfd(void) { @@ -946,6 +991,41 @@ imsg_flush(ibuf); } break; + case PRIVSEP_GET_IF_RDOMAIN: { + int s; + struct ifreqifr; + struct PRIVSEP_GET_IF_RDOMAIN_ARG *a = imsg.data; + struct PRIVSEP_GET_IF_RDOMAIN_RESP r; + + memset(, 0, sizeof(r)); + r.retval = -1; + + if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(*a)) + r.rerrno = EINVAL; + else if (privsep_npppd_check_get_if_rdomain(a)) { + r.rerrno = EACCES; + } else { + memset(, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, a->ifname, + sizeof(ifr.ifr_name)); + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + r.retval = -1; + r.rerrno = errno; + } else { + r.retval = 0; + if (ioctl(s, SIOCGIFRDOMAIN, ) == -1) + r.rdomain = 0; + else + r.rdomain = ifr.ifr_rdomainid; + } + if (s >= 0) + close(s); + } + (void)imsg_compose(ibuf, PRIVSEP_OK, 0, 0, -1, + , sizeof(r)); + imsg_flush(ibuf); + } + break; } imsg_free(); } @@ -1114,3 +1194,12 @@ return (1); } + +static int +privsep_npppd_check_get_if_rdomain(struct PRIVSEP_GET_IF_RDOMAIN_ARG *arg) +{ + if (startswith(arg->ifname, "tun") || startswith(arg->ifname, "pppx") || startswith(arg->ifname, "lo")) + return (0); + + return (1); +} diff -r 8d76f9f8cc87 -r 55eeedfb0cb5 usr.sbin/npppd/npppd/privsep.h --- usr.sbin/npppd/npppd/privsep.h Fri Jan 15 14:02:34 2016 +0100 +++
Patches for improving npppd with rdomain support [9/12]
Hello, Patch 9 # HG changeset patch # User MJP # Date 1452862954 -3600 # Fri Jan 15 14:02:34 2016 +0100 # Node ID 97146d7e9ebbb07f93d734dbdd7afe942f5cc557 # Parent 55eeedfb0cb54ed0d91c7de080b507fc79f64c30 Add: Introduce priv_set_if_rdomain() to set the rdomain of a device. diff -r 55eeedfb0cb5 -r 97146d7e9ebb usr.sbin/npppd/npppd/privsep.c --- usr.sbin/npppd/npppd/privsep.c Fri Jan 15 14:02:34 2016 +0100 +++ usr.sbin/npppd/npppd/privsep.c Fri Jan 15 14:02:34 2016 +0100 @@ -55,7 +55,8 @@ PRIVSEP_DEL_IF_ADDR, PRIVSEP_GET_IF_FLAGS, PRIVSEP_SET_IF_FLAGS, - PRIVSEP_GET_IF_RDOMAIN + PRIVSEP_GET_IF_RDOMAIN, + PRIVSEP_SET_IF_RDOMAIN }; struct PRIVSEP_OPEN_ARG { @@ -138,6 +139,11 @@ u_intrdomain; }; +struct PRIVSEP_SET_IF_RDOMAIN_ARG { + char ifname[IFNAMSIZ]; + u_intrdomain; +}; + struct PRIVSEP_COMMON_RESP { int retval; int rerrno; @@ -178,6 +184,8 @@ struct PRIVSEP_SET_IF_FLAGS_ARG *); static int privsep_npppd_check_get_if_rdomain ( struct PRIVSEP_GET_IF_RDOMAIN_ARG *); +static int privsep_npppd_check_set_if_rdomain ( + struct PRIVSEP_SET_IF_RDOMAIN_ARG *); static int privsep_sock = -1; static struct imsgbuf privsep_ibuf; @@ -557,6 +565,21 @@ return (retval); } +int +priv_set_if_rdomain(const char *ifname, int rdomain) +{ + struct PRIVSEP_SET_IF_RDOMAIN_ARGa; + + strlcpy(a.ifname, ifname, sizeof(a.ifname)); + a.rdomain = rdomain; + + (void)imsg_compose(_ibuf, PRIVSEP_SET_IF_RDOMAIN, 0, 0, -1, + , sizeof(a)); + imsg_flush(_ibuf); + + return (privsep_common_resp()); +} + static int privsep_recvfd(void) { @@ -1026,6 +1049,35 @@ imsg_flush(ibuf); } break; + case PRIVSEP_SET_IF_RDOMAIN: { + int s; + struct ifreq ifr; + struct PRIVSEP_SET_IF_RDOMAIN_ARG *a = imsg.data; + struct PRIVSEP_COMMON_RESPr = { -1, 0 }; + + if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(*a)) + r.rerrno = EINVAL; + else if (privsep_npppd_check_set_if_rdomain(a)) + r.rerrno = EACCES; + else { + memset(, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, a->ifname, + sizeof(ifr.ifr_name)); + ifr.ifr_rdomainid = a->rdomain; + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0 || + ioctl(s, SIOCSIFRDOMAIN, ) != 0) { + r.retval = -1; + r.rerrno = errno; + } else + r.retval = 0; + if (s >= 0) + close(s); + } + (void)imsg_compose(ibuf, PRIVSEP_OK, 0, 0, -1, + , sizeof(r)); + imsg_flush(ibuf); + } + break; } imsg_free(); } @@ -1203,3 +1255,12 @@ return (1); } + +static int +privsep_npppd_check_set_if_rdomain(struct PRIVSEP_SET_IF_RDOMAIN_ARG *arg) +{ + if (startswith(arg->ifname, "tun") || startswith(arg->ifname, "pppx")) + return (0); + + return (1); +} diff -r 55eeedfb0cb5 -r 97146d7e9ebb usr.sbin/npppd/npppd/privsep.h --- usr.sbin/npppd/npppd/privsep.h Fri Jan 15 14:02:34 2016 +0100 +++ usr.sbin/npppd/npppd/privsep.h Fri Jan 15 14:02:34 2016 +0100 @@ -45,6 +45,7 @@ int priv_delete_if_addr(const char *); int priv_set_if_flags(const char *, int); int priv_get_if_flags(const char *, int *); +int priv_set_if_rdomain(const char *, int); int priv_get_if_rdomain(const char *, int *); #ifdef __cplusplus
Patches for improving npppd with rdomain support [10/12]
Hello, patch 10 # HG changeset patch # User MJP # Date 1452862954 -3600 # Fri Jan 15 14:02:34 2016 +0100 # Node ID 842c1c22848e171f174cc45ba7b961883fc3c184 # Parent 97146d7e9ebbb07f93d734dbdd7afe942f5cc557 Add: Route functions handle rdomain. diff -r 97146d7e9ebb -r 842c1c22848e usr.sbin/npppd/pppd/npppd.c --- usr.sbin/npppd/npppd/npppd.cFri Jan 15 14:02:34 2016 +0100 +++ usr.sbin/npppd/npppd/npppd.cFri Jan 15 14:02:34 2016 +0100 @@ -588,7 +588,8 @@ if (is_first) in_route_add(>snp_addr, >snp_mask, , - LOOPBACK_IFNAME, RTF_BLACKHOLE, 0); + LOOPBACK_IFNAME, RTF_BLACKHOLE, 0, + _this->iface[0].rdomain); break; case SNP_PPP: @@ -601,14 +602,16 @@ ppp_framed_ip_address, _iface(ppp)->ip4addr, ppp_iface(ppp)->ifname, - MRU_IPMTU(ppp->peer_mru)); + MRU_IPMTU(ppp->peer_mru), + ppp_iface(ppp)->rdomain); } else { in_route_add(> ppp_framed_ip_address, >ppp_framed_ip_netmask, _iface(ppp)->ip4addr, ppp_iface(ppp)->ifname, 0, - MRU_IPMTU(ppp->peer_mru)); + MRU_IPMTU(ppp->peer_mru), + ppp_iface(ppp)->rdomain); } break; } @@ -1392,19 +1395,21 @@ */ in_route_delete(>ppp_framed_ip_address, >ppp_framed_ip_netmask, , - RTF_BLACKHOLE); + RTF_BLACKHOLE, ppp_iface(ppp)->rdomain); /* See the comment for MRU_IPMTU() on ppp.h */ if (ppp->ppp_framed_ip_netmask.s_addr == 0xL) { in_host_route_add(>ppp_framed_ip_address, _iface(ppp)->ip4addr, ppp_iface(ppp)->ifname, - MRU_IPMTU(ppp->peer_mru)); + MRU_IPMTU(ppp->peer_mru), + ppp_iface(ppp)->rdomain); } else { in_route_add(>ppp_framed_ip_address, >ppp_framed_ip_netmask, _iface(ppp)->ip4addr, ppp_iface(ppp)->ifname, 0, - MRU_IPMTU(ppp->peer_mru)); + MRU_IPMTU(ppp->peer_mru), + ppp_iface(ppp)->rdomain); } } #endif @@ -1413,11 +1418,13 @@ if (_this->iface[ppp->ifidx].using_pppx == 0) { if (ppp->ppp_framed_ip_netmask.s_addr == 0xL) { in_host_route_delete(>ppp_framed_ip_address, - _iface(ppp)->ip4addr); + _iface(ppp)->ip4addr, + ppp_iface(ppp)->rdomain); } else { in_route_delete(>ppp_framed_ip_address, >ppp_framed_ip_netmask, - _iface(ppp)->ip4addr, 0); + _iface(ppp)->ip4addr, 0, + ppp_iface(ppp)->rdomain); } if (ppp->snp.snp_next != NULL) /* @@ -1426,7 +1433,8 @@ */ in_route_add(>snp.snp_addr, >snp.snp_mask, , LOOPBACK_IFNAME, - RTF_BLACKHOLE, 0); + RTF_BLACKHOLE, 0, + ppp_iface(ppp)->rdomain); } #endif if (ppp->username[0] != '\0') { @@ -1729,7 +1737,7 @@ radish = slist_itr_next(); in_route_delete((radish->rd_route)->sin_addr, (radish->rd_mask)->sin_addr, , -
Patches for improving npppd with rdomain support [7/12]
Hello, Patch 7 # HG changeset patch # User MJP # Date 1452862954 -3600 # Fri Jan 15 14:02:34 2016 +0100 # Node ID 8d76f9f8cc873602c8593b896133648cdedb6afd # Parent 90fa2a12bfaa8776e883c168aaf39be0b16fea4d Add: In the configuration file, define the rdomain of an interface. diff -r 90fa2a12bfaa -r 8d76f9f8cc87 usr.sbin/npppd/npppd/npppd.h --- usr.sbin/npppd/npppd/npppd.hFri Jan 15 14:02:05 2016 +0100 +++ usr.sbin/npppd/npppd/npppd.hFri Jan 15 14:02:34 2016 +0100 @@ -179,6 +179,7 @@ TAILQ_ENTRY(iface) entry; char name[IFNAMSIZ]; struct in_addr ip4addr; + intrdomain; struct ipcpconf *ipcpconf; bool is_pppx; }; diff -r 90fa2a12bfaa -r 8d76f9f8cc87 usr.sbin/npppd/npppd/parse.y --- usr.sbin/npppd/npppd/parse.yFri Jan 15 14:02:05 2016 +0100 +++ usr.sbin/npppd/npppd/parse.yFri Jan 15 14:02:34 2016 +0100 @@ -132,7 +132,7 @@ %token X_TIMEOUT MAX_TRIES MAX_FAILOVERS SECRET %token POOL_ADDRESS DNS_SERVERS NBNS_SERVERS FOR STATIC DYNAMIC %token RESOLVER ALLOW_USER_SELECTED_ADDRESS -%token INTERFACE ADDRESS IPCP +%token INTERFACE ADDRESS IPCP RDOMAIN %token BIND FROM AUTHENTICATED BY TO %token ERROR %token STRING @@ -154,6 +154,7 @@ %typeauthmethod %typeauthmethod_l %typeipcppooltype +%typeifrdomain %% @@ -853,7 +854,7 @@ /* * interface */ -interface : INTERFACE STRING ADDRESS in4_addr IPCP STRING { +interface : INTERFACE STRING ADDRESS in4_addr IPCP STRING ifrdomain { int cnt; struct iface*n; struct ipcpconf *ipcp; @@ -887,6 +888,7 @@ strlcpy(n->name, $2, sizeof(n->name)); free($2); n->ip4addr = $4; + n->rdomain = $7; if (strncmp(n->name, "pppx", 4) == 0) n->is_pppx = true; @@ -895,6 +897,10 @@ } ; +ifrdomain : /* empty */ { $$ = 0; } + | RDOMAIN NUMBER { $$ = $2; } + ; + /* * bind */ @@ -1079,6 +1085,7 @@ { "pptp-vendor-name", PPTP_VENDOR_NAME}, { "protocol", PROTOCOL}, { "radius", RADIUS}, + { "rdomain", RDOMAIN}, { "required", REQUIRED}, { "resolver", RESOLVER}, { "secret", SECRET},
Patches for improving npppd with rdomain support [6/12]
Hello, patch 6, # HG changeset patch # User MJP # Date 1452862925 -3600 # Fri Jan 15 14:02:05 2016 +0100 # Node ID 90fa2a12bfaa8776e883c168aaf39be0b16fea4d # Parent fd7f48f3955596de5fe098de0f4208106578c9db Feature: Can listen on an interface with a specific rdomain. diff -r fd7f48f39555 -r 90fa2a12bfaa usr.sbin/npppd/l2tp/l2tpd.c --- usr.sbin/npppd/l2tp/l2tpd.c Fri Jan 15 13:38:16 2016 +0100 +++ usr.sbin/npppd/l2tp/l2tpd.c Fri Jan 15 14:02:05 2016 +0100 @@ -60,6 +60,7 @@ #include "l2tp_local.h" #include "addr_range.h" #include "net_utils.h" +#include/* for IF_NAMESIZE */ #ifdef L2TPD_DEBUG #defineL2TPD_ASSERT(x) ASSERT(x) @@ -261,7 +262,8 @@ l2tpd_listener_start(l2tpd_listener *_this) { l2tpd *_l2tpd; - intaf, lvl, opt, sock, ival; + intaf, lvl, opt, sock, ival, rdomain; + char ifname[IF_NAMESIZE]; char hbuf[NI_MAXHOST + NI_MAXSERV + 16]; _l2tpd = _this->self; @@ -301,6 +303,23 @@ "setsockopt(,,SO_REUSEPORT) failed in %s(): %m", __func__); goto fail; } + rdomain = 0; + get_ifname_by_sockaddr((struct sockaddr *)&_this->bind, ifname); + if (strlen(ifname) > 0) { + if (ifname_get_rdomain(ifname, ) != 0) { + l2tpd_log(_l2tpd, LOG_ERR, + "ifname_get_rdomain(%s) failed in %s()", ifname, __func__); + goto fail; + } + } + if (rdomain != 0) { + if (setsockopt(sock, SOL_SOCKET, SO_RTABLE, , + sizeof(rdomain)) == -1) { + l2tpd_log(_l2tpd, LOG_ERR, + "setsockopt(,,SO_RTABLE) failed in %s(): %m", __func__); + goto fail; + } + } if (bind(sock, (struct sockaddr *)&_this->bind, _this->bind.sin6.sin6_len) != 0) { l2tpd_log(_l2tpd, LOG_ERR, "Binding %s/udp: %m", @@ -401,9 +420,11 @@ l2tpd_io_event, _this); event_add(&_this->ev_sock, NULL); - l2tpd_log(_l2tpd, LOG_INFO, "Listening %s/udp (L2TP LNS) [%s]", + l2tpd_log(_l2tpd, LOG_INFO, + "Listening %s/udp (rdomain %i) (L2TP LNS) [%s]", addrport_tostring((struct sockaddr *)&_this->bind, - _this->bind.sin6.sin6_len, hbuf, sizeof(hbuf)), _this->tun_name); + _this->bind.sin6.sin6_len, hbuf, sizeof(hbuf)), rdomain, + _this->tun_name); return 0; fail: diff -r fd7f48f39555 -r 90fa2a12bfaa usr.sbin/npppd/pptp/pptpd.c --- usr.sbin/npppd/pptp/pptpd.c Fri Jan 15 13:38:16 2016 +0100 +++ usr.sbin/npppd/pptp/pptpd.c Fri Jan 15 14:02:05 2016 +0100 @@ -290,7 +290,8 @@ static int pptpd_listener_start(pptpd_listener *_this) { - int sock, ival, sock_gre; + int sock, ival, sock_gre, rdomain; + char ifname[IF_NAMESIZE]; struct sockaddr_in bind_sin, bind_sin_gre; int wildcardbinding; @@ -327,6 +328,23 @@ "fcntl(F_SET_FL) failed at %s(): %m", __func__); goto fail; } + rdomain = 0; + get_ifname_by_sockaddr((struct sockaddr *)&_this->bind_sin, ifname); + if (strlen(ifname) > 0) { + if (ifname_get_rdomain(ifname, ) != 0) { + pptpd_log(_this->self, LOG_ERR, + "ifname_get_rdomain(%s) failed in %s()", ifname, __func__); + goto fail; + } + } + if (rdomain != 0) { + if (setsockopt(sock, SOL_SOCKET, SO_RTABLE, , + sizeof(rdomain)) == -1) { + pptpd_log(_this->self, LOG_ERR, + "setsockopt(,,SO_RTABLE) failed in %s(): %m", __func__); + goto fail; + } + } if (bind(sock, (struct sockaddr *)&_this->bind_sin, _this->bind_sin.sin_len) != 0) { pptpd_log(_this->self, LOG_ERR, @@ -376,6 +394,14 @@ "fcntl(F_SET_FL) failed at %s(): %m", __func__); goto fail; } + if (rdomain != 0) { + if (setsockopt(sock_gre, SOL_SOCKET, SO_RTABLE, , + sizeof(rdomain)) == -1) { + pptpd_log(_this->self, LOG_ERR, + "setsockopt(,,SO_RTABLE) failed in %s(): %m", __func__); + goto fail; + } + } if (bind(sock_gre, (struct sockaddr *)_sin_gre, bind_sin_gre.sin_len) != 0) { pptpd_log(_this->self, LOG_ERR,
Patches for improving npppd with rdomain support [1/12]
Hello, This patch fix an incorrect check. # HG changeset patch # User MJP # Date 1452429700 -3600 # Sun Jan 10 13:41:40 2016 +0100 # Node ID 5df6e3ec88c3933dd06ced5fd459921a8043cead # Parent e414626941ab329294b3d6c26657e1b2a509f5f0 Fix: "authconf.users_file_path" is a char[] but is checked as a char*. diff -r e414626941ab -r 5df6e3ec88c3 usr.sbin/npppd/npppd/npppd_auth.c --- usr.sbin/npppd/npppd/npppd_auth.c Thu Dec 17 14:39:03 2015 +0100 +++ usr.sbin/npppd/npppd/npppd_auth.c Sun Jan 10 13:41:40 2016 +0100 @@ -197,7 +197,7 @@ base->has_users_file = 0; base->radius_ready = 0; - if (auth->users_file_path != NULL) { + if (strlen(auth->users_file_path) > 0) { strlcpy(base->users_file_path, auth->users_file_path, sizeof(base->users_file_path)); base->has_users_file = 1;
Patches for improving npppd with rdomain support [5/12]
Hello, Patch 5 # HG changeset patch # User MJP # Date 1452861496 -3600 # Fri Jan 15 13:38:16 2016 +0100 # Node ID fd7f48f3955596de5fe098de0f4208106578c9db # Parent 52f96bbfc0cb83010e78d49b63a18bdc00a7 Add: Introduce common tools to get and set the rdomain of an interface. diff -r 52f96bbfc0cb -r fd7f48f39555 usr.sbin/npppd/common/net_utils.c --- usr.sbin/npppd/common/net_utils.c Sun Jan 10 15:40:46 2016 +0100 +++ usr.sbin/npppd/common/net_utils.c Fri Jan 15 13:38:16 2016 +0100 @@ -26,6 +26,7 @@ /* $Id: net_utils.c,v 1.4 2012/05/08 13:18:37 yasuoka Exp $ */ #include #include +#include #include #include #include @@ -206,3 +207,47 @@ } return -1; } + +/** Get the rdomain of a network interface */ +int +ifname_get_rdomain(char *ifname, int *rdomain) +{ + int s; + struct ifreq ifr; + + *rdomain = 0; + memset(, 0, sizeof(ifr)); + if (ifname) + strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s < 0) + return 1; + if (ioctl(s, SIOCGIFRDOMAIN, ) != -1) + *rdomain = ifr.ifr_rdomainid; + if (s >= 0) + close(s); + + return 0; +} + +/** Set the rdomain of a network interface */ +int +ifname_set_rdomain(char *ifname, int rdomain) +{ + int s, result = 0; + struct ifreq ifr; + + memset(, 0, sizeof(ifr)); + if (ifname) + strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + ifr.ifr_rdomainid = rdomain; + + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s < 0 || ioctl(s, SIOCSIFRDOMAIN, ) != 0) + result = 1; + if (s >= 0) + close(s); + + return result; +} diff -r 52f96bbfc0cb -r fd7f48f39555 usr.sbin/npppd/common/net_utils.h --- usr.sbin/npppd/common/net_utils.h Sun Jan 10 15:40:46 2016 +0100 +++ usr.sbin/npppd/common/net_utils.h Fri Jan 15 13:38:16 2016 +0100 @@ -33,6 +33,8 @@ int addrport_parse(const char *, int, struct addrinfo **); const char *addrport_tostring(struct sockaddr *, socklen_t, char *, int); int netmask2prefixlen(uint32_t); +int ifname_get_rdomain(char *, int *); +int ifname_set_rdomain(char *, int); #ifdef __cplusplus
Patches for improving npppd with rdomain support [2-4/12]
Hello, These patches add support for defining pid-file & control-socket from configuration file. Claer # HG changeset patch # User MJP # Date 1452430850 -3600 # Sun Jan 10 14:00:50 2016 +0100 # Node ID 12ffa641c5d987c3e1373f8a9156f4951faa54ed # Parent 5df6e3ec88c3933dd06ced5fd459921a8043cead Add: In the configuration file, define the PID file to use (set pid-file). diff -r 5df6e3ec88c3 -r 12ffa641c5d9 usr.sbin/npppd/npppd/npppd.c --- usr.sbin/npppd/npppd/npppd.cSun Jan 10 13:41:40 2016 +0100 +++ usr.sbin/npppd/npppd/npppd.cSun Jan 10 14:00:50 2016 +0100 @@ -310,6 +310,9 @@ } pidpath0 = DEFAULT_NPPPD_PIDFILE; + if (strlen(_this->conf.pid_file_path) > 0) { + pidpath0 = _this->conf.pid_file_path; + } /* initialize event(3) */ event_init(); diff -r 5df6e3ec88c3 -r 12ffa641c5d9 usr.sbin/npppd/npppd/npppd.h --- usr.sbin/npppd/npppd/npppd.hSun Jan 10 13:41:40 2016 +0100 +++ usr.sbin/npppd/npppd/npppd.hSun Jan 10 14:00:50 2016 +0100 @@ -193,6 +193,7 @@ struct npppd_conf { intmax_session; intuser_max_session; + char pid_file_path[PATH_MAX]; TAILQ_HEAD(tunnconfs, tunnconf)tunnconfs; TAILQ_HEAD(authconfs, authconf)authconfs; TAILQ_HEAD(ipcpconfs, ipcpconf)ipcpconfs; diff -r 5df6e3ec88c3 -r 12ffa641c5d9 usr.sbin/npppd/npppd/parse.y --- usr.sbin/npppd/npppd/parse.ySun Jan 10 13:41:40 2016 +0100 +++ usr.sbin/npppd/npppd/parse.ySun Jan 10 14:00:50 2016 +0100 @@ -102,7 +102,7 @@ %} -%token SET MAX_SESSION USER_MAX_SESSION +%token SET MAX_SESSION USER_MAX_SESSION PID_FILE %token TUNNEL LISTEN ON PROTOCOL %token MRU %token IP LCP PAP CHAP EAP MPPE CCP MSCHAPV2 STATEFUL STATELESS REQUIRED @@ -171,6 +171,10 @@ set: SET MAX_SESSION NUMBER{ conf->max_session = $3; } | SET USER_MAX_SESSION NUMBER { conf->user_max_session = $3; } + | SET PID_FILE STRING { + strlcpy(conf->pid_file_path, $3, sizeof(conf->pid_file_path)); + free($3); + } ; /* @@ -1047,6 +1051,7 @@ { "no", NO}, { "on", ON}, { "pap", PAP}, + { "pid-file", PID_FILE}, { "pipex",PIPEX}, { "pool-address", POOL_ADDRESS}, { "port", PORT}, # HG changeset patch # User MJP # Date 1452430858 -3600 # Sun Jan 10 14:00:58 2016 +0100 # Node ID 6e76b1f3b116537de0e91ab176f7681cb9c9daed # Parent 12ffa641c5d987c3e1373f8a9156f4951faa54ed Add: In the configuration file, define the control socket to use (set control-socket). diff -r 12ffa641c5d9 -r 6e76b1f3b116 usr.sbin/npppd/npppd/npppd.c --- usr.sbin/npppd/npppd/npppd.cSun Jan 10 14:00:50 2016 +0100 +++ usr.sbin/npppd/npppd/npppd.cSun Jan 10 14:00:58 2016 +0100 @@ -317,6 +317,9 @@ /* initialize event(3) */ event_init(); _this->ctl_sock.cs_name = NPPPD_SOCKET; + if (strlen(_this->conf.control_socket_path) > 0) { + _this->ctl_sock.cs_name = _this->conf.control_socket_path; + } _this->ctl_sock.cs_ctx = _this; if (control_init(&_this->ctl_sock) == -1) { log_printf(LOG_ERR, "control_init() failed %s(): %m", diff -r 12ffa641c5d9 -r 6e76b1f3b116 usr.sbin/npppd/npppd/npppd.h --- usr.sbin/npppd/npppd/npppd.hSun Jan 10 14:00:50 2016 +0100 +++ usr.sbin/npppd/npppd/npppd.hSun Jan 10 14:00:58 2016 +0100 @@ -194,6 +194,7 @@ intmax_session; intuser_max_session; char pid_file_path[PATH_MAX]; + char control_socket_path[PATH_MAX]; TAILQ_HEAD(tunnconfs, tunnconf)tunnconfs; TAILQ_HEAD(authconfs, authconf)authconfs; TAILQ_HEAD(ipcpconfs, ipcpconf)ipcpconfs; diff -r 12ffa641c5d9 -r 6e76b1f3b116 usr.sbin/npppd/npppd/parse.y --- usr.sbin/npppd/npppd/parse.ySun Jan 10 14:00:50 2016 +0100 +++ usr.sbin/npppd/npppd/parse.ySun Jan 10 14:00:58 2016 +0100 @@ -102,7 +102,7 @@ %} -%token SET MAX_SESSION USER_MAX_SESSION PID_FILE +%token SET MAX_SESSION USER_MAX_SESSION PID_FILE CONTROL_SOCKET %token TUNNEL LISTEN ON PROTOCOL %token MRU %token IP LCP PAP CHAP EAP MPPE CCP MSCHAPV2 STATEFUL STATELESS REQUIRED @@ -175,6 +175,10 @@ strlcpy(conf->pid_file_path, $3, sizeof(conf->pid_file_path));
Patches for improving npppd with rdomain support
Hello dear developers, I asked a friend, Mathieu Papineau, to help me with an issue I have with npppd. For a project here, I thought building multitenancy firewall with rdomain support. For remote access, I wanted to use npppd to be able to authenticate users in different domains in their respective domains using RADIUS. After some infructuous tests, it appears that npppd wasn't designed to support rdomains. Mathieu developed the following patches to support the functionnality I wished. Actually, due to the current limitation, it only works with tun devices. The pppx driver does not support rdomain ioctls yet. The serie contains 12 patches, I'll try to post one per mail for easier review. Thanks for review! Claer
Re: vmxnet3 panic
On Fri, May 22 2015 at 35:19, mxb wrote: Hey, Hello, got a panic as of todays ‘cvs up’ trace below I got nearly the same panic stopping a 5.7 host panic: vmxnet3_rxintr: NULL ring-m[44] Stopped at Debugger+0x9: leave RUN AT LEAST 'trace' AND 'ps' AND INCLUDE OUTPUT WHEN REPORTING THIS PANIC! IF RUNNING SMP, USE 'mach ddbcpu #' AND 'trace' ON OTHER PROCESSORS, TOO. DO NOT EVEN BOTHER REPORTING THIS WITHOUT INCLUDING THAT INFORMATION! ddb{0} Debugger() at Debugger+0x9 panic() at panic+0xfe vmxnet3_rxintr() at vmxnet3_rxintr+0x284 vmxnet3_intr() at vmxnet3_intr+0x4a intr_handler() at intr_handler+0x67 Xintr_ioapic_level10() at Xintr_ioapic_level10+0xcd --- interrupt --- Xspllower() at Xspllower+0xe if_downall() at if_downall+0x9b boot() at boot+0xe4 reboot() at reboot+0x26 sys_reboot() at sys_reboot+0x5e syscall() at syscall+0x297 --- syscall (number 55) --- end of kernel end trace frame: 0x7f7d5858, count: -12 0x184f48704eda: ddb{0} rebooting... OpenBSD 5.7-current (GENERIC.MP) #0: Fri May 22 16:30:54 CEST 2015 bsd1:/usr # reboot syncing discks... done panic: vmxnet3_rxintr: NULL ring-m[3] Stopped at Debugger+0x9: leave RUN AT LEAST 'trace' AND 'ps' AND INCLUDE OUTPUT WHEN REPORTING THIS PANIC! DO NOT EVEN BOTHER REPORTING THIS WITHOUT INCLUDING THAT INFORMATION! ddb trace Debugger() at Debugger+0x9 panic() at panic+0xfe vmxnet3_rxintr() at vmxnet3_rxintr+0x284 vmxnet4_intr() at vmxnet3_intr+0x4a intr_handler() at intr_handler+0x28 Xintrioapic_level10() at Xintr_ioapic_level10+0xe1 --- interrupt --- Bad frame pointer: 0x8e5e0cd8 end trace frame: 0x8e5e0cd8, count: -6 Xspllower+0xe: ddb bsd1:~ # uname -a OpenBSD bsd1.primaire-bench.local 5.7 GENERIC#825 amd64 I'll try the patch from mike and report. Claer