diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2011-04-02 12:04:45 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2011-04-02 12:04:45 +0000 |
commit | 1f78efac1821c14469c471adc993a8948fdd373c (patch) | |
tree | 8958dd238e902a61bf753098986d1af3716c061d /usr.sbin | |
parent | 0591db5a284e642ef83c413ac836604457c04e7d (diff) |
add support for pppx interfaces instead of tun interfaces.
pppx mode will create a pppx interface for each ppp session in the kernel,
and will rely on the kernel to handle the routing rather than doing it
itself. as a bonus it will configure the interfaces description with the
username of the person connecting (which makes systat if pretty).
ok claudio@ yasuoka@ as part of a larger diff
from jonathan matthew
weve been running all this in production for a month now..
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/npppd/npppd/npppd.c | 137 | ||||
-rw-r--r-- | usr.sbin/npppd/npppd/npppd_config.c | 17 | ||||
-rw-r--r-- | usr.sbin/npppd/npppd/npppd_iface.c | 51 | ||||
-rw-r--r-- | usr.sbin/npppd/npppd/npppd_iface.h | 6 |
4 files changed, 134 insertions, 77 deletions
diff --git a/usr.sbin/npppd/npppd/npppd.c b/usr.sbin/npppd/npppd/npppd.c index 518f602e04f..87d874a24e7 100644 --- a/usr.sbin/npppd/npppd/npppd.c +++ b/usr.sbin/npppd/npppd/npppd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: npppd.c,v 1.8 2010/09/24 14:50:30 yasuoka Exp $ */ +/* $OpenBSD: npppd.c,v 1.9 2011/04/02 12:04:44 dlg Exp $ */ /*- * Copyright (c) 2009 Internet Initiative Japan Inc. @@ -29,7 +29,7 @@ * Next pppd(nppd). This file provides a npppd daemon process and operations * for npppd instance. * @author Yasuoka Masahiko - * $Id: npppd.c,v 1.8 2010/09/24 14:50:30 yasuoka Exp $ + * $Id: npppd.c,v 1.9 2011/04/02 12:04:44 dlg Exp $ */ #include <sys/cdefs.h> #include "version.h" @@ -255,7 +255,9 @@ npppd_init(npppd *_this, const char *config_file) long seed; memset(_this, 0, sizeof(npppd)); +#ifndef NO_ROUTE_FOR_POOLED_ADDRESS loop.s_addr = htonl(INADDR_LOOPBACK); +#endif NPPPD_ASSERT(config_file != NULL); @@ -565,6 +567,9 @@ npppd_reset_routing_table(npppd *_this, int pool_only) #ifndef NO_ROUTE_FOR_POOLED_ADDRESS slist rtlist0; + if (_this->iface[0].using_pppx) + return 0; + slist_init(&rtlist0); if (rd2slist(_this->rd, &rtlist0) != 0) return 1; @@ -925,6 +930,7 @@ pipex_setup_common(npppd_ppp *ppp, struct pipex_session_req *req) if (ppp->adjust_mss != 0) req->pr_ppp_flags |= PIPEX_PPP_ADJUST_TCPMSS; + req->pr_ip_srcaddr = ppp->pppd->iface[0].ip4addr; req->pr_ip_address = ppp->ppp_framed_ip_address; req->pr_ip_netmask = ppp->ppp_framed_ip_netmask; req->pr_peer_mru = ppp->peer_mru; @@ -1077,6 +1083,19 @@ npppd_ppp_pipex_enable(npppd *_this, npppd_ppp *ppp) return error; } + if (_this->iface[ppp->ifidx].using_pppx) { + struct pipex_session_descr_req descr_req; + + descr_req.pdr_protocol = req.pr_protocol; + descr_req.pdr_session_id = req.pr_session_id; + memset(descr_req.pdr_descr, 0, sizeof(descr_req.pdr_descr)); + strlcpy(descr_req.pdr_descr, ppp->username, sizeof(descr_req.pdr_descr)); + error = ioctl(_this->iface[ppp->ifidx].devf, PIPEXSIFDESCR, &descr_req); + if (error != 0) { + log_printf(LOG_WARNING, "PIPEXSIFDESCR(%s) failed: %d\n", ppp->username, error); + } + } + ppp->pipex_enabled = 1; if (ppp->timeout_sec > 0) { /* Stop the npppd's idle-timer. We use pipex's idle-timer */ @@ -1361,42 +1380,50 @@ npppd_set_ip_enabled(npppd *_this, npppd_ppp *ppp, int enabled) } #ifndef NO_ROUTE_FOR_POOLED_ADDRESS - if (ppp->snp.snp_next != NULL) - /* - * There is a blackhole route that has same - * address/mask. - */ - in_route_delete(&ppp->ppp_framed_ip_address, - &ppp->ppp_framed_ip_netmask, &loop, RTF_BLACKHOLE); - /* See the comment for MRU_IPMTU() on ppp.h */ - if (ppp->ppp_framed_ip_netmask.s_addr == 0xffffffffL) { - in_host_route_add(&ppp->ppp_framed_ip_address, - &ppp_iface(ppp)->ip4addr, ppp_iface(ppp)->ifname, - MRU_IPMTU(ppp->peer_mru)); - } else { - in_route_add(&ppp->ppp_framed_ip_address, - &ppp->ppp_framed_ip_netmask, - &ppp_iface(ppp)->ip4addr, ppp_iface(ppp)->ifname, 0, - MRU_IPMTU(ppp->peer_mru)); + if (_this->iface[ppp->ifidx].using_pppx == 0) { + if (ppp->snp.snp_next != NULL) + /* + * There is a blackhole route that has same + * address/mask. + */ + in_route_delete(&ppp->ppp_framed_ip_address, + &ppp->ppp_framed_ip_netmask, &loop, + RTF_BLACKHOLE); + /* See the comment for MRU_IPMTU() on ppp.h */ + if (ppp->ppp_framed_ip_netmask.s_addr == 0xffffffffL) { + in_host_route_add(&ppp->ppp_framed_ip_address, + &ppp_iface(ppp)->ip4addr, + ppp_iface(ppp)->ifname, + MRU_IPMTU(ppp->peer_mru)); + } else { + in_route_add(&ppp->ppp_framed_ip_address, + &ppp->ppp_framed_ip_netmask, + &ppp_iface(ppp)->ip4addr, + ppp_iface(ppp)->ifname, 0, + MRU_IPMTU(ppp->peer_mru)); + } } #endif } else { #ifndef NO_ROUTE_FOR_POOLED_ADDRESS - if (ppp->ppp_framed_ip_netmask.s_addr == 0xffffffffL) { - in_host_route_delete(&ppp->ppp_framed_ip_address, - &ppp_iface(ppp)->ip4addr); - } else { - in_route_delete(&ppp->ppp_framed_ip_address, - &ppp->ppp_framed_ip_netmask, - &ppp_iface(ppp)->ip4addr, 0); + if (_this->iface[ppp->ifidx].using_pppx == 0) { + if (ppp->ppp_framed_ip_netmask.s_addr == 0xffffffffL) { + in_host_route_delete(&ppp->ppp_framed_ip_address, + &ppp_iface(ppp)->ip4addr); + } else { + in_route_delete(&ppp->ppp_framed_ip_address, + &ppp->ppp_framed_ip_netmask, + &ppp_iface(ppp)->ip4addr, 0); + } + if (ppp->snp.snp_next != NULL) + /* + * There is a blackhole route that has same + * address/mask. + */ + in_route_add(&ppp->snp.snp_addr, + &ppp->snp.snp_mask, &loop, LOOPBACK_IFNAME, + RTF_BLACKHOLE, 0); } - if (ppp->snp.snp_next != NULL) - /* - * There is a blackhole route that has same - * address/mask. - */ - in_route_add(&ppp->snp.snp_addr, &ppp->snp.snp_mask, - &loop, LOOPBACK_IFNAME, RTF_BLACKHOLE, 0); #endif if (ppp->username[0] != '\0') { hl = hash_lookup(_this->map_user_ppp, ppp->username); @@ -1713,27 +1740,31 @@ npppd_set_radish(npppd *_this, void *radish_head) } count = 0; #ifndef NO_ROUTE_FOR_POOLED_ADDRESS - for (slist_itr_first(&rtlist0); slist_itr_has_next(&rtlist0);) { - radish = slist_itr_next(&rtlist0); - in_route_delete(&SIN(radish->rd_route)->sin_addr, - &SIN(radish->rd_mask)->sin_addr, &loop, RTF_BLACKHOLE); - count++; + if (_this->iface[0].using_pppx == 0) { + for (slist_itr_first(&rtlist0); slist_itr_has_next(&rtlist0);) { + radish = slist_itr_next(&rtlist0); + in_route_delete(&SIN(radish->rd_route)->sin_addr, + &SIN(radish->rd_mask)->sin_addr, &loop, + RTF_BLACKHOLE); + count++; + } + if (count > 0) + log_printf(LOG_INFO, + "Deleted %d routes for old pool addresses", count); + + count = 0; + for (slist_itr_first(&rtlist1); slist_itr_has_next(&rtlist1);) { + radish = slist_itr_next(&rtlist1); + in_route_add(&(SIN(radish->rd_route)->sin_addr), + &SIN(radish->rd_mask)->sin_addr, &loop, + LOOPBACK_IFNAME, RTF_BLACKHOLE, 0); + count++; + } + if (count > 0) + log_printf(LOG_INFO, + "Added %d routes for new pool addresses", + count); } - if (count > 0) - log_printf(LOG_INFO, - "Deleted %d routes for old pool addresses", count); - - count = 0; - for (slist_itr_first(&rtlist1); slist_itr_has_next(&rtlist1);) { - radish = slist_itr_next(&rtlist1); - in_route_add(&(SIN(radish->rd_route)->sin_addr), - &SIN(radish->rd_mask)->sin_addr, &loop, LOOPBACK_IFNAME, - RTF_BLACKHOLE, 0); - count++; - } - if (count > 0) - log_printf(LOG_INFO, - "Added %d routes for new pool addresses", count); #endif slist_fini(&rtlist0); slist_fini(&rtlist1); diff --git a/usr.sbin/npppd/npppd/npppd_config.c b/usr.sbin/npppd/npppd/npppd_config.c index de088480154..2ab792ad889 100644 --- a/usr.sbin/npppd/npppd/npppd_config.c +++ b/usr.sbin/npppd/npppd/npppd_config.c @@ -1,4 +1,4 @@ -/* $OpenBSD: npppd_config.c,v 1.5 2010/07/02 21:20:57 yasuoka Exp $ */ +/* $OpenBSD: npppd_config.c,v 1.6 2011/04/02 12:04:44 dlg Exp $ */ /*- * Copyright (c) 2009 Internet Initiative Japan Inc. @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -/* $Id: npppd_config.c,v 1.5 2010/07/02 21:20:57 yasuoka Exp $ */ +/* $Id: npppd_config.c,v 1.6 2011/04/02 12:04:44 dlg Exp $ */ /*@file * This file provides functions which operates configuration and so on. */ @@ -685,16 +685,21 @@ npppd_ifaces_load_config(npppd *_this) break; } + strlcpy(buf1, "interface.", sizeof(buf1)); + strlcat(buf1, tok, sizeof(buf1)); + if (_this->iface[n].initialized != 0) nsession = _this->iface[n].nsession; else { - npppd_iface_init(&_this->iface[n], tok); + int pppx; + + pppx = npppd_config_str_equal(_this, + config_key_prefix(buf1, "pppx_mode"), + "true", 0); + npppd_iface_init(&_this->iface[n], tok, pppx); nsession = 0; } - strlcpy(buf1, "interface.", sizeof(buf1)); - strlcat(buf1, tok, sizeof(buf1)); - _this->iface[n].set_ip4addr = 0; if ((val = npppd_config_str(_this, config_key_prefix(buf1, "ip4addr"))) != NULL){ diff --git a/usr.sbin/npppd/npppd/npppd_iface.c b/usr.sbin/npppd/npppd/npppd_iface.c index 0baa2f1fedc..59b5b2a0312 100644 --- a/usr.sbin/npppd/npppd/npppd_iface.c +++ b/usr.sbin/npppd/npppd/npppd_iface.c @@ -1,4 +1,4 @@ -/* $OpenBSD: npppd_iface.c,v 1.4 2010/07/02 21:20:57 yasuoka Exp $ */ +/* $OpenBSD: npppd_iface.c,v 1.5 2011/04/02 12:04:44 dlg Exp $ */ /*- * Copyright (c) 2009 Internet Initiative Japan Inc. @@ -25,10 +25,10 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -/* $Id: npppd_iface.c,v 1.4 2010/07/02 21:20:57 yasuoka Exp $ */ +/* $Id: npppd_iface.c,v 1.5 2011/04/02 12:04:44 dlg Exp $ */ /**@file * The interface of npppd and kernel. - * This is an implementation to use tun(4). + * This is an implementation to use tun(4) or pppx(4). */ #include <sys/types.h> #include <sys/param.h> @@ -100,13 +100,15 @@ static int npppd_iface_pipex_disable(npppd_iface *_this); /** initialize npppd_iface */ void -npppd_iface_init(npppd_iface *_this, const char *ifname) +npppd_iface_init(npppd_iface *_this, const char *ifname, int pppx_mode) { NPPPD_IFACE_ASSERT(_this != NULL); memset(_this, 0, sizeof(npppd_iface)); _this->devf = -1; strlcpy(_this->ifname, ifname, sizeof(_this->ifname)); + + _this->using_pppx = pppx_mode; } static int @@ -260,6 +262,9 @@ npppd_iface_reinit(npppd_iface *_this) struct in_addr backup; char buf0[128], buf1[128]; + if (_this->using_pppx) + return 0; + backup = _this->ip4addr; if ((rval = npppd_iface_setup_ip(_this)) != 0) return rval; @@ -301,32 +306,46 @@ npppd_iface_start(npppd_iface *_this) goto fail; } - x = IFF_BROADCAST; - if (ioctl(_this->devf, TUNSIFMODE, &x) != 0) { - npppd_iface_log(_this, LOG_ERR, - "ioctl(TUNSIFMODE=IFF_BROADCAST) failed in %s(): %m", - __func__); - goto fail; + if (_this->using_pppx == 0) { + x = IFF_BROADCAST; + if (ioctl(_this->devf, TUNSIFMODE, &x) != 0) { + npppd_iface_log(_this, LOG_ERR, + "ioctl(TUNSIFMODE=IFF_BROADCAST) failed in %s(): %m", + __func__); + goto fail; + } } event_set(&_this->ev, _this->devf, EV_READ | EV_PERSIST, npppd_iface_io_event_handler, _this); event_add(&_this->ev, NULL); - if (npppd_iface_setup_ip(_this) != 0) - goto fail; + if (_this->using_pppx == 0) { + if (npppd_iface_setup_ip(_this) != 0) + goto fail; + } #ifdef USE_NPPPD_PIPEX if (npppd_iface_pipex_enable(_this) != 0) { log_printf(LOG_WARNING, "npppd_iface_pipex_enable() failed: %m"); } +#else + if (_this->using_pppx) { + npppd_iface_log(_this, LOG_ERR, + "pipex is required when using pppx interface"); + goto fail; + } #endif /* USE_NPPPD_PIPEX */ - npppd_iface_log(_this, LOG_INFO, "Started ip4addr=%s", - (npppd_iface_ip_is_ready(_this))? - inet_ntop(AF_INET, &_this->ip4addr, buf, sizeof(buf)) - : "(not assigned)"); + if (_this->using_pppx) { + npppd_iface_log(_this, LOG_INFO, "Started pppx"); + } else { + npppd_iface_log(_this, LOG_INFO, "Started ip4addr=%s", + (npppd_iface_ip_is_ready(_this))? + inet_ntop(AF_INET, &_this->ip4addr, buf, sizeof(buf)) + : "(not assigned)"); + } return 0; fail: diff --git a/usr.sbin/npppd/npppd/npppd_iface.h b/usr.sbin/npppd/npppd/npppd_iface.h index bca65f6da64..25b419698fe 100644 --- a/usr.sbin/npppd/npppd/npppd_iface.h +++ b/usr.sbin/npppd/npppd/npppd_iface.h @@ -1,4 +1,4 @@ -/* $OpenBSD: npppd_iface.h,v 1.3 2010/07/02 21:20:57 yasuoka Exp $ */ +/* $OpenBSD: npppd_iface.h,v 1.4 2011/04/02 12:04:44 dlg Exp $ */ /*- * Copyright (c) 2009 Internet Initiative Japan Inc. @@ -54,6 +54,8 @@ typedef struct _npppd_iface { * <p>if 0, npppd_iface only refers IP address already set.</p> */ set_ip4addr:1, + /** set if using pppx(4) rather than tun(4) */ + using_pppx:1, /** initialized flag */ initialized:1; } npppd_iface; @@ -66,7 +68,7 @@ typedef struct _npppd_iface { extern "C" { #endif -void npppd_iface_init (npppd_iface *, const char *); +void npppd_iface_init (npppd_iface *, const char *, int); int npppd_iface_reinit (npppd_iface *); int npppd_iface_start (npppd_iface *); void npppd_iface_stop (npppd_iface *); |