From 821f7c5673b56ce7082633a67f8f8498f8f4faa2 Mon Sep 17 00:00:00 2001 From: yasuoka Date: Tue, 18 Sep 2012 13:14:08 +0000 Subject: New configuration syntax for npppd(8). `npppd.conf' will be based on parse.y and `npppd-users' will be based on getcap(3). Add man pages. feedback from giovanni --- usr.sbin/npppd/l2tp/l2tp.h | 60 ++----- usr.sbin/npppd/l2tp/l2tp_call.c | 13 +- usr.sbin/npppd/l2tp/l2tp_conf.h | 50 ++++++ usr.sbin/npppd/l2tp/l2tp_ctrl.c | 69 ++------ usr.sbin/npppd/l2tp/l2tpd.c | 381 +++++++++++----------------------------- 5 files changed, 188 insertions(+), 385 deletions(-) create mode 100644 usr.sbin/npppd/l2tp/l2tp_conf.h (limited to 'usr.sbin/npppd/l2tp') diff --git a/usr.sbin/npppd/l2tp/l2tp.h b/usr.sbin/npppd/l2tp/l2tp.h index cc3c8b36a2f..f676273e687 100644 --- a/usr.sbin/npppd/l2tp/l2tp.h +++ b/usr.sbin/npppd/l2tp/l2tp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: l2tp.h,v 1.8 2012/05/08 13:18:37 yasuoka Exp $ */ +/* $OpenBSD: l2tp.h,v 1.9 2012/09/18 13:14:08 yasuoka Exp $ */ /*- * Copyright (c) 2009 Internet Initiative Japan Inc. @@ -30,7 +30,7 @@ /*@file * header file for the L2TP module */ -/* $Id: l2tp.h,v 1.8 2012/05/08 13:18:37 yasuoka Exp $ */ +/* $Id: l2tp.h,v 1.9 2012/09/18 13:14:08 yasuoka Exp $ */ /************************************************************************ * Protocol Constants @@ -213,8 +213,8 @@ /************************************************************************ * Implementation Specific Constants ************************************************************************/ +#include "l2tp_conf.h" -#define L2TPD_BACKLOG 16 #define L2TPD_TUNNEL_HASH_SIZ 127 #define L2TPD_SND_BUFSIZ 2048 #define L2TPD_DEFAULT_SEND_WINSZ 4 @@ -223,7 +223,7 @@ #define L2TPD_CONFIG_BUFSIZ 65535 #define L2TP_CTRL_WINDOW_SIZE 8 #ifndef L2TPD_VENDOR_NAME -#define L2TPD_VENDOR_NAME "IIJ" +#define L2TPD_VENDOR_NAME "" #endif #define L2TPD_DEFAULT_UDP_PORT 1701 @@ -279,9 +279,13 @@ (((l2tpd)->state == L2TPD_STATE_SHUTTING_DOWN)? 1 : 0) /** macro to retrieve a physical layer label from l2tp_ctrl */ -#define L2TP_CTRL_LISTENER_LABEL(ctrl) \ +#define L2TP_CTRL_LISTENER_TUN_NAME(ctrl) \ ((l2tpd_listener *)slist_get(&(ctrl)->l2tpd->listener, \ - (ctrl)->listener_index))->phy_label + (ctrl)->listener_index))->tun_name + +#define L2TP_CTRL_CONF(ctrl) \ + ((l2tpd_listener *)slist_get(&(ctrl)->l2tpd->listener, \ + (ctrl)->listener_index))->conf #define L2TP_CALL_DELAY_LIMIT 64 @@ -289,6 +293,8 @@ struct _l2tpd; typedef struct _l2tpd_listener { + /* configuration */ + struct l2tp_conf *conf; /** event context */ struct event ev_sock; /** L2TPD itself */ @@ -304,8 +310,8 @@ typedef struct _l2tpd_listener { struct sockaddr_in sin4; struct sockaddr_in6 sin6; } bind; - /** physical layer label */ - char phy_label[16]; + /** tunnel name */ + char tun_name[L2TP_NAME_LEN]; } l2tpd_listener; /** datatype represents L2TP daemon */ @@ -323,24 +329,9 @@ typedef struct _l2tpd { /** unique and free Session-ID list */ slist free_session_id_list; - /** IPv4 network addresses allowed to connect */ - struct in_addr_range *ip4_allow; - - /** default hostname */ - char default_hostname[80]; - - /** configuration */ - struct properties *config; - /** flags */ uint32_t - require_ipsec:1, - purge_ipsec_sa:1, - ctrl_in_pktdump:1, - ctrl_out_pktdump:1, - data_in_pktdump:1, - data_out_pktdump:1, - phy_label_with_ifname:1; + purge_ipsec_sa:1; } l2tpd; /** datatype represents L2TP control connection */ @@ -374,8 +365,6 @@ typedef struct _l2tp_ctrl { struct sockaddr_storage sock; /** IPSEC NAT-T SA cookie */ void *sa_cookie; - /** physical layer label (copied) */ - char phy_label[16]; /** list of L2TP calls */ slist call_list; @@ -402,7 +391,6 @@ typedef struct _l2tp_ctrl { /** * delay between transition to idle state and sending HELLO in seconds. - * invalid if less than or equal to zero. */ int hello_interval; /** HELLO timeout */ @@ -412,8 +400,7 @@ typedef struct _l2tp_ctrl { /** number of calls established */ int ncalls; - int - /** use sequence number in L2TP Data Message? */ + int /** use sequence number in L2TP Data Message? */ data_use_seq:1, /** waiting to acknowledge HELLO? */ hello_wait_ack:1; @@ -479,19 +466,10 @@ l2tp_ctrl *l2tpd_get_ctrl (l2tpd *, u_int); void l2tpd_add_ctrl (l2tpd *, l2tp_ctrl *); void l2tpd_ctrl_finished_notify(l2tpd *); void l2tpd_remove_ctrl (l2tpd *, u_int); -int l2tpd_add_listener (l2tpd *, int, const char *, struct sockaddr *); +int l2tpd_add_listener (l2tpd *, int, struct l2tp_conf *); void l2tpd_log (l2tpd *, int, const char *, ...) __attribute__((__format__ (__printf__, 3, 4))); - -const char *l2tp_ctrl_config_str (l2tp_ctrl *, const char *); -int l2tp_ctrl_config_int (l2tp_ctrl *, const char *, int); -int l2tp_ctrl_config_str_equal (l2tp_ctrl *, const char *, const char *, int); -int l2tp_ctrl_config_str_equali (l2tp_ctrl *, const char *, const char *, int); -const char *l2tpd_config_str (l2tpd *, const char *); -int l2tpd_config_int (l2tpd *, const char *, int); -int l2tpd_config_str_equal (l2tpd *, const char *, const char *, int); -int l2tpd_config_str_equali (l2tpd *, const char *, const char *, int); -int l2tpd_reload(l2tpd *, struct properties *, const char *, int); -void l2tpd_log_access_deny(l2tpd *, const char *, struct sockaddr *); +int l2tpd_reload(l2tpd *, struct l2tp_confs *); +void l2tpd_log_access_deny(l2tpd *, const char *, struct sockaddr *); #ifdef __cplusplus } #endif diff --git a/usr.sbin/npppd/l2tp/l2tp_call.c b/usr.sbin/npppd/l2tp/l2tp_call.c index 990294709cc..562ca713840 100644 --- a/usr.sbin/npppd/l2tp/l2tp_call.c +++ b/usr.sbin/npppd/l2tp/l2tp_call.c @@ -1,4 +1,4 @@ -/* $OpenBSD: l2tp_call.c,v 1.13 2012/07/13 15:11:14 yasuoka Exp $ */ +/* $OpenBSD: l2tp_call.c,v 1.14 2012/09/18 13:14:08 yasuoka 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: l2tp_call.c,v 1.13 2012/07/13 15:11:14 yasuoka Exp $ */ +/* $Id: l2tp_call.c,v 1.14 2012/09/18 13:14:08 yasuoka Exp $ */ /**@file L2TP LNS call */ #include #include @@ -445,7 +445,7 @@ l2tp_call_send_data_packet(l2tp_call *_this, bytebuffer *buffer) hdr->nr = htons(_this->rcv_nxt); } - if (_this->ctrl->l2tpd->data_out_pktdump != 0) { + if (L2TP_CTRL_CONF(_this->ctrl)->data_out_pktdump != 0) { l2tpd_log(_this->ctrl->l2tpd, LOG_DEBUG, "ctrl=%u call=%u L2TP Data output packet dump", _this->ctrl->id, _this->id); @@ -998,12 +998,12 @@ l2tp_call_bind_ppp(l2tp_call *_this, dialin_proxy_info *dpi) _this->ppp = ppp; - ppp->tunnel_type = PPP_TUNNEL_L2TP; + ppp->tunnel_type = NPPPD_TUNNEL_L2TP; ppp->phy_context = _this; ppp->send_packet = l2tp_call_ppp_output; ppp->phy_close = l2tp_call_closed_by_ppp; - strlcpy(ppp->phy_label, _this->ctrl->phy_label, + strlcpy(ppp->phy_label, L2TP_CTRL_LISTENER_TUN_NAME(_this->ctrl), sizeof(ppp->phy_label)); L2TP_CALL_ASSERT(sizeof(ppp->phy_info) >= _this->ctrl->peer.ss_len); memcpy(&ppp->phy_info, &_this->ctrl->peer, @@ -1017,8 +1017,7 @@ l2tp_call_bind_ppp(l2tp_call *_this, dialin_proxy_info *dpi) l2tp_call_log(_this, LOG_NOTICE, "logtype=PPPBind ppp=%d", ppp->id); if (DIALIN_PROXY_IS_REQUESTED(dpi)) { - if (!l2tp_ctrl_config_str_equal(_this->ctrl, - "l2tp.accept_dialin", "true", 0)) { + if (!L2TP_CTRL_CONF(_this->ctrl)->accept_dialin) { l2tp_call_log(_this, LOG_ERR, "'accept_dialin' is 'false' in the setting."); code = L2TP_CDN_RCODE_ERROR_CODE; diff --git a/usr.sbin/npppd/l2tp/l2tp_conf.h b/usr.sbin/npppd/l2tp/l2tp_conf.h new file mode 100644 index 00000000000..4306f993c31 --- /dev/null +++ b/usr.sbin/npppd/l2tp/l2tp_conf.h @@ -0,0 +1,50 @@ +/* $OpenBSD: l2tp_conf.h,v 1.1 2012/09/18 13:14:08 yasuoka Exp $ */ + +/* + * Copyright (c) 2012 YASUOKA Masahiko + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef L2TP_CONF_H +#define L2TP_CONF_H 1 + +#include +#include +#include + +#include + +#define L2TP_NAME_LEN 16 + +TAILQ_HEAD(l2tp_confs, l2tp_conf); + +struct l2tp_conf { + TAILQ_ENTRY(l2tp_conf) entry; + char name[L2TP_NAME_LEN]; + char *hostname; + char *vendor_name; + struct sockaddr_storage address; + int hello_interval; + int hello_timeout; + bool data_use_seq; + bool require_ipsec; + bool accept_dialin; + bool lcp_renegotiation; + bool force_lcp_renegotiation; + bool ctrl_in_pktdump; + bool ctrl_out_pktdump; + bool data_in_pktdump; + bool data_out_pktdump; +}; + +#endif diff --git a/usr.sbin/npppd/l2tp/l2tp_ctrl.c b/usr.sbin/npppd/l2tp/l2tp_ctrl.c index a1f333e5fd5..1a980e51e27 100644 --- a/usr.sbin/npppd/l2tp/l2tp_ctrl.c +++ b/usr.sbin/npppd/l2tp/l2tp_ctrl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: l2tp_ctrl.c,v 1.12 2012/07/16 18:05:36 markus Exp $ */ +/* $OpenBSD: l2tp_ctrl.c,v 1.13 2012/09/18 13:14:08 yasuoka Exp $ */ /*- * Copyright (c) 2009 Internet Initiative Japan Inc. @@ -26,7 +26,7 @@ * SUCH DAMAGE. */ /**@file Control connection processing functions for L2TP LNS */ -/* $Id: l2tp_ctrl.c,v 1.12 2012/07/16 18:05:36 markus Exp $ */ +/* $Id: l2tp_ctrl.c,v 1.13 2012/09/18 13:14:08 yasuoka Exp $ */ #include #include #include @@ -61,7 +61,6 @@ #include "l2tp_local.h" #include "l2tp_subr.h" #include "net_utils.h" -#include "config_helper.h" #include "version.h" static int l2tp_ctrl_init (l2tp_ctrl *, l2tpd *, struct sockaddr *, struct sockaddr *, void *); @@ -215,17 +214,11 @@ fail: static void l2tp_ctrl_reload(l2tp_ctrl *_this) { - int ival; - - _this->data_use_seq = l2tp_ctrl_config_str_equal(_this, - "l2tp.data_use_seq", "true", 1); - - if ((ival = l2tp_ctrl_config_int(_this, "l2tp.hello_interval", 0))!= 0) - _this->hello_interval = ival; - if ((ival = l2tp_ctrl_config_int(_this, "l2tp.hello_timeout", 0)) != 0) - _this->hello_timeout = ival; - - return; + _this->data_use_seq = L2TP_CTRL_CONF(_this)->data_use_seq; + if (L2TP_CTRL_CONF(_this)->hello_interval != 0) + _this->hello_interval = L2TP_CTRL_CONF(_this)->hello_interval; + if (L2TP_CTRL_CONF(_this)->hello_timeout != 0) + _this->hello_timeout = L2TP_CTRL_CONF(_this)->hello_timeout; } /* @@ -332,7 +325,7 @@ cleanup: break; } #if 0 - if (_this->l2tpd->purge_ipsec_sa != 0) + if (L2TP_CTRL_CONF(_this)e_ipsec_sa != 0) l2tp_ctrl_purge_ipsec_sa(_this); #endif @@ -727,7 +720,6 @@ l2tp_ctrl_input(l2tpd *_this, int listener_index, struct sockaddr *peer, char buf[L2TP_AVP_MAXSIZ], errmsg[256]; time_t curr_time; u_char *pkt0; - char ifname[IF_NAMESIZE], phy_label[256]; struct l2tp_header hdr; char hbuf[NI_MAXHOST + NI_MAXSERV + 16]; @@ -826,43 +818,12 @@ l2tp_ctrl_input(l2tpd *_this, int listener_index, struct sockaddr *peer, goto bad_packet; } - strlcpy(phy_label, - ((l2tpd_listener *)slist_get(&_this->listener, - listener_index))->phy_label, sizeof(phy_label)); - if (_this->phy_label_with_ifname != 0) { - if (get_ifname_by_sockaddr(sock, ifname) == NULL) { - if (errno != ENOENT) - l2tp_ctrl_log(ctrl, LOG_ERR, - "get_ifname_by_sockaddr() " - "failed: %m"); - else - l2tpd_log_access_deny(_this, - "could not determine received " - "interface", peer); - goto fail; - } - if (l2tpd_config_str_equal(_this, - config_key_prefix("l2tpd.interface", ifname), - "accept", 0)){ - strlcat(phy_label, "%", sizeof(phy_label)); - strlcat(phy_label, ifname, sizeof(phy_label)); - } else if (l2tpd_config_str_equal(_this, - config_key_prefix("l2tpd.interface", "any"), - "accept", 0)){ - } else { - /* the interface is not permited */ - snprintf(errmsg, sizeof(errmsg), - "'%s' is not allowed by config.", ifname); - l2tpd_log_access_deny(_this, errmsg, peer); - goto fail; - } - } - if ((ctrl = l2tp_ctrl_create()) == NULL) { l2tp_ctrl_log(ctrl, LOG_ERR, "l2tp_ctrl_create() failed: %m"); goto fail; } + if (l2tp_ctrl_init(ctrl, _this, peer, sock, nat_t_ctx) != 0) { l2tp_ctrl_log(ctrl, LOG_ERR, "l2tp_ctrl_start() failed: %m"); @@ -870,7 +831,6 @@ l2tp_ctrl_input(l2tpd *_this, int listener_index, struct sockaddr *peer, } ctrl->listener_index = listener_index; - strlcpy(ctrl->phy_label, phy_label, sizeof(ctrl->phy_label)); l2tp_ctrl_reload(ctrl); } else { /* @@ -1211,7 +1171,7 @@ l2tp_ctrl_send_packet(l2tp_ctrl *_this, int call_id, bytebuffer *bytebuf) ntohs(hdr->ns), htons(hdr->nr), _this->snd_nxt, _this->snd_una, _this->rcv_nxt)); - if (_this->l2tpd->ctrl_out_pktdump != 0) { + if (L2TP_CTRL_CONF(_this)->ctrl_out_pktdump != 0) { l2tpd_log(_this->l2tpd, LOG_DEBUG, "L2TP Control output packet dump"); show_hd(debug_get_debugfp(), bytebuffer_pointer(bytebuf), @@ -1553,11 +1513,8 @@ l2tp_ctrl_send_SCCRP(l2tp_ctrl *_this) memset(avp, 0, sizeof(*avp)); avp->is_mandatory = 1; avp->attr_type = L2TP_AVP_TYPE_HOST_NAME; - - if ((val = l2tp_ctrl_config_str(_this, "l2tp.host_name")) == NULL) - val = _this->l2tpd->default_hostname; - if (val[0] == '\0') - val = "G"; /* XXX magic word, why? ask yasuoka */ + if ((val = L2TP_CTRL_CONF(_this)->hostname) == NULL) + val = ""; len = strlen(val); memcpy(avp->attr_value, val, len); bytebuf_add_avp(bytebuf, avp, len); @@ -1592,7 +1549,7 @@ l2tp_ctrl_send_SCCRP(l2tp_ctrl *_this) avp->is_mandatory = 1; avp->attr_type = L2TP_AVP_TYPE_VENDOR_NAME; - if ((val = l2tp_ctrl_config_str(_this, "l2tp.vendor_name")) == NULL) + if ((val = L2TP_CTRL_CONF(_this)->vendor_name) == NULL) val = L2TPD_VENDOR_NAME; len = strlen(val); diff --git a/usr.sbin/npppd/l2tp/l2tpd.c b/usr.sbin/npppd/l2tp/l2tpd.c index e5f739f8bc8..9a599fb0fe8 100644 --- a/usr.sbin/npppd/l2tp/l2tpd.c +++ b/usr.sbin/npppd/l2tp/l2tpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: l2tpd.c,v 1.10 2012/07/16 18:05:36 markus Exp $ */ +/* $OpenBSD: l2tpd.c,v 1.11 2012/09/18 13:14:08 yasuoka Exp $ */ /*- * Copyright (c) 2009 Internet Initiative Japan Inc. @@ -26,15 +26,12 @@ * SUCH DAMAGE. */ /**@file L2TP(Layer Two Tunneling Protocol "L2TP") / RFC2661 */ -/* $Id: l2tpd.c,v 1.10 2012/07/16 18:05:36 markus Exp $ */ +/* $Id: l2tpd.c,v 1.11 2012/09/18 13:14:08 yasuoka Exp $ */ #include #include #include #include #include -#if 0 -#include -#endif #include #include #include @@ -62,8 +59,6 @@ #include "l2tp_subr.h" #include "l2tp_local.h" #include "addr_range.h" -#include "properties.h" -#include "config_helper.h" #include "net_utils.h" #ifdef L2TPD_DEBUG @@ -96,8 +91,6 @@ l2tpd_init(l2tpd *_this) { int i, off; u_int id; - struct sockaddr_in sin4; - struct sockaddr_in6 sin6; L2TPD_ASSERT(_this != NULL); memset(_this, 0, sizeof(l2tpd)); @@ -105,20 +98,6 @@ l2tpd_init(l2tpd *_this) slist_init(&_this->listener); slist_init(&_this->free_session_id_list); - memset(&sin4, 0, sizeof(sin4)); - sin4.sin_len = sizeof(sin4); - sin4.sin_family = AF_INET; - if (l2tpd_add_listener(_this, 0, L2TPD_DEFAULT_LAYER2_LABEL, - (struct sockaddr *)&sin4) != 0) { - return 1; - } - memset(&sin6, 0, sizeof(sin6)); - sin6.sin6_len = sizeof(sin6); - sin6.sin6_family = AF_INET6; - if (l2tpd_add_listener(_this, 1, L2TPD_DEFAULT_LAYER2_LABEL, - (struct sockaddr *)&sin6) != 0) { - return 1; - } _this->id = l2tpd_id_seq++; if ((_this->ctrl_map = hash_create(short_cmp, short_hash, @@ -146,9 +125,6 @@ l2tpd_init(l2tpd *_this) return 1; } } - _this->ip4_allow = NULL; - - _this->require_ipsec = 1; _this->purge_ipsec_sa = 1; _this->state = L2TPD_STATE_INIT; @@ -159,12 +135,11 @@ l2tpd_init(l2tpd *_this) * Add a {@link :l2tpd_listener} to the {@link ::l2tpd L2TP daemon} * @param _this {@link ::l2tpd L2TP daemon} * @param idx index of the lisnter - * @param label physical layer label (ex. "L2TP") + * @param tun_name tunnel name (ex. "L2TP") * @param bindaddr bind address */ int -l2tpd_add_listener(l2tpd *_this, int idx, const char *label, - struct sockaddr *bindaddr) +l2tpd_add_listener(l2tpd *_this, int idx, struct l2tp_conf *conf) { l2tpd_listener *plistener, *plsnr; @@ -192,8 +167,8 @@ l2tpd_add_listener(l2tpd *_this, int idx, const char *label, goto fail; } memset(plistener, 0, sizeof(l2tpd_listener)); - L2TPD_ASSERT(sizeof(plistener->bind) >= bindaddr->sa_len); - memcpy(&plistener->bind, bindaddr, bindaddr->sa_len); + L2TPD_ASSERT(sizeof(plistener->bind) >= conf->address.ss_len); + memcpy(&plistener->bind, &conf->address, conf->address.ss_len); if (plistener->bind.sin6.sin6_port == 0) plistener->bind.sin6.sin6_port = htons(L2TPD_DEFAULT_UDP_PORT); @@ -201,7 +176,8 @@ l2tpd_add_listener(l2tpd *_this, int idx, const char *label, plistener->sock = -1; plistener->self = _this; plistener->index = idx; - strlcpy(plistener->phy_label, label, sizeof(plistener->phy_label)); + plistener->conf = conf; + strlcpy(plistener->tun_name, conf->name, sizeof(plistener->tun_name)); if (slist_add(&_this->listener, plistener) == NULL) { l2tpd_log(_this, LOG_ERR, "slist_add() failed in %s: %m", @@ -229,9 +205,6 @@ l2tpd_uninit(l2tpd *_this) _this->ctrl_map = NULL; } - if (_this->ip4_allow != NULL) - in_addr_range_list_remove_all(&_this->ip4_allow); - slist_itr_first(&_this->listener); while (slist_itr_has_next(&_this->listener)) { plsnr = slist_itr_next(&_this->listener); @@ -243,7 +216,6 @@ l2tpd_uninit(l2tpd *_this) event_del(&_this->ev_timeout); /* just in case */ _this->state = L2TPD_STATE_STOPPED; - _this->config = NULL; } /** assign the call to the l2tpd */ @@ -284,21 +256,22 @@ l2tpd_release_call(l2tpd *_this, l2tp_call *call) slist_add(&_this->free_session_id_list, (void *)(uintptr_t)call->id); } - /* start l2tpd listner */ static int -l2tpd_listener_start(l2tpd_listener *_this, char *ipsec_policy_in, - char *ipsec_policy_out) +l2tpd_listener_start(l2tpd_listener *_this) { - int sock, ival; l2tpd *_l2tpd; - char hbuf[NI_MAXHOST + NI_MAXSERV + 16]; - sock = -1; + int af, lvl, opt, sock, ival; + char hbuf[NI_MAXHOST + NI_MAXSERV + 16]; + _l2tpd = _this->self; + sock = -1; + af = _this->bind.sin6.sin6_family; + lvl = (af == AF_INET)? IPPROTO_IP : IPPROTO_IPV6; - if (_this->phy_label[0] == '\0') - strlcpy(_this->phy_label, L2TPD_DEFAULT_LAYER2_LABEL, - sizeof(_this->phy_label)); + if (_this->tun_name[0] == '\0') + strlcpy(_this->tun_name, L2TPD_DEFAULT_LAYER2_LABEL, + sizeof(_this->tun_name)); if ((sock = socket(_this->bind.sin6.sin6_family, SOCK_DGRAM, IPPROTO_UDP)) < 0) { l2tpd_log(_l2tpd, LOG_ERR, @@ -342,16 +315,17 @@ l2tpd_listener_start(l2tpd_listener *_this, char *ipsec_policy_in, goto fail; } #else - if (_this->bind.sin6.sin6_family == AF_INET) { - ival = 1; - if (setsockopt(sock, IPPROTO_IP, IP_RECVDSTADDR, &ival, - sizeof(ival)) != 0) { - l2tpd_log(_l2tpd, LOG_ERR, - "setsockopt(,,IP_RECVDSTADDR) failed in %s(): %m", - __func__); - goto fail; - } + opt = (af == AF_INET)? IP_RECVDSTADDR : IPV6_RECVPKTINFO; + ival = 1; + if (setsockopt(sock, lvl, opt, &ival, sizeof(ival)) != 0) { + l2tpd_log(_l2tpd, LOG_ERR, + "setsockopt(,,IP{,V6}_RECVDSTADDR) failed in %s(): %m", + __func__); + goto fail; + } +#endif #ifdef USE_SA_COOKIE + if (af == AF_INET) { ival = 1; if (setsockopt(sock, IPPROTO_IP, IP_IPSECFLOWINFO, &ival, sizeof(ival)) != 0) { @@ -360,72 +334,67 @@ l2tpd_listener_start(l2tpd_listener *_this, char *ipsec_policy_in, __func__); goto fail; } -#endif - } else { - ival = 1; - if (setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &ival, - sizeof(ival)) != 0) { - l2tpd_log(_l2tpd, LOG_ERR, - "setsockopt(,,IPV6_PKTINFO) failed in %s(): %m", - __func__); - goto fail; - } } #endif - if (_this->bind.sin6.sin6_family == AF_INET) { #ifdef IP_PIPEX - ival = 1; - if (setsockopt(sock, IPPROTO_IP, IP_PIPEX, &ival, - sizeof(ival)) != 0) - l2tpd_log(_l2tpd, LOG_WARNING, - "%s(): setsockopt(IP_PIPEX) failed: %m", __func__); + opt = (af == AF_INET)? IP_PIPEX : IPV6_PIPEX; + ival = 1; + if (setsockopt(sock, lvl, opt, &ival, sizeof(ival)) != 0) + l2tpd_log(_l2tpd, LOG_WARNING, + "%s(): setsockopt(IP{,V6}_PIPEX) failed: %m", __func__); #endif + if (_this->conf->require_ipsec) { #ifdef IP_IPSEC_POLICY - if (ipsec_policy_in != NULL && - setsockopt(sock, IPPROTO_IP, IP_IPSEC_POLICY, - ipsec_policy_in, ipsec_get_policylen(ipsec_policy_in)) - < 0) { + caddr_t ipsec_policy_in, ipsec_policy_out; + + opt = (af == AF_INET)? IP_IPSEC_POLICY : IPV6_IPSEC_POLICY; + /* + * Note: ipsec_set_policy() will assign the buffer for + * yacc parser stack, however it never free. + * it cause memory leak (-2000byte). + */ + if ((ipsec_policy_in = ipsec_set_policy(L2TPD_IPSEC_POLICY_IN, + strlen(L2TPD_IPSEC_POLICY_IN))) == NULL) { + l2tpd_log(_l2tpd, LOG_ERR, + "ipsec_set_policy(L2TPD_IPSEC_POLICY_IN) failed " + "at %s(): %s: %m", __func__, ipsec_strerror()); + } else if (setsockopt(sock, lvl, opt, ipsec_policy_in, + ipsec_get_policylen(ipsec_policy_in)) < 0) { l2tpd_log(_l2tpd, LOG_WARNING, "setsockopt(,,IP_IPSEC_POLICY(in)) failed " "in %s(): %m", __func__); } + if ((ipsec_policy_out = ipsec_set_policy(L2TPD_IPSEC_POLICY_OUT, + strlen(L2TPD_IPSEC_POLICY_OUT))) == NULL) { + l2tpd_log(_l2tpd, LOG_ERR, + "ipsec_set_policy(L2TPD_IPSEC_POLICY_OUT) failed " + "at %s(): %s: %m", __func__, ipsec_strerror()); + } if (ipsec_policy_out != NULL && - setsockopt(sock, IPPROTO_IP, IP_IPSEC_POLICY, - ipsec_policy_out, ipsec_get_policylen(ipsec_policy_out)) - < 0) { + setsockopt(sock, lvl, opt, ipsec_policy_out, + ipsec_get_policylen(ipsec_policy_out)) < 0) { l2tpd_log(_l2tpd, LOG_WARNING, "setsockopt(,,IP_IPSEC_POLICY(out)) failed " "in %s(): %m", __func__); } -#endif - } else { -#ifdef IPV6_PIPEX - ival = 1; - if (setsockopt(sock, IPPROTO_IPV6, IPV6_PIPEX, &ival, - sizeof(ival)) != 0) + if (ipsec_policy_in != NULL) + free(ipsec_policy_in); + if (ipsec_policy_out != NULL) + free(ipsec_policy_out); +#elif defined(IP_ESP_TRANS_LEVEL) + opt = (af == AF_INET) + ? IP_ESP_TRANS_LEVEL : IPV6_ESP_TRANS_LEVEL; + ival = IPSEC_LEVEL_REQUIRE; + if (setsockopt(sock, lvl, opt, &ival, sizeof(ival)) != 0) { l2tpd_log(_l2tpd, LOG_WARNING, - "%s(): setsockopt(IPV6_PIPEX) failed: %m", - __func__); -#endif -#ifdef IPV6_IPSEC_POLICY - if (ipsec_policy_in != NULL && - setsockopt(sock, IPPROTO_IPV6, IPV6_IPSEC_POLICY, - ipsec_policy_in, ipsec_get_policylen(ipsec_policy_in)) - < 0) { - l2tpd_log(_l2tpd, LOG_WARNING, - "setsockopt(,,IPV6_IPSEC_POLICY(in)) failed " - "in %s(): %m", __func__); - } - if (ipsec_policy_out != NULL && - setsockopt(sock, IPPROTO_IPV6, IPV6_IPSEC_POLICY, - ipsec_policy_out, ipsec_get_policylen(ipsec_policy_out)) - < 0) { - l2tpd_log(_l2tpd, LOG_WARNING, - "setsockopt(,,IPV6_IPSEC_POLICY(out)) failed " + "setsockopt(,,IP{,V6}_ESP_TRANS_LEVEL(out)) failed " "in %s(): %m", __func__); } +#else +#error IP_IPSEC_POLICY or IP_ESP_TRANS_LEVEL must be usable. #endif } + _this->sock = sock; event_set(&_this->ev_sock, _this->sock, EV_READ | EV_PERSIST, @@ -434,7 +403,7 @@ l2tpd_listener_start(l2tpd_listener *_this, char *ipsec_policy_in, l2tpd_log(_l2tpd, LOG_INFO, "Listening %s/udp (L2TP LNS) [%s]", addrport_tostring((struct sockaddr *)&_this->bind, - _this->bind.sin6.sin6_len, hbuf, sizeof(hbuf)), _this->phy_label); + _this->bind.sin6.sin6_len, hbuf, sizeof(hbuf)), _this->tun_name); return 0; fail: @@ -449,12 +418,9 @@ int l2tpd_start(l2tpd *_this) { int rval; - caddr_t ipsec_policy_in, ipsec_policy_out; l2tpd_listener *plsnr; rval = 0; - ipsec_policy_in = NULL; - ipsec_policy_out = NULL; L2TPD_ASSERT(_this->state == L2TPD_STATE_INIT); if (_this->state != L2TPD_STATE_INIT) { @@ -462,55 +428,17 @@ l2tpd_start(l2tpd *_this) "state."); return -1; } - if (_this->require_ipsec != 0) { -#if 0 - /* - * Note: ipsec_set_policy() will assign the buffer for - * yacc parser stack, however it never free. - * it cause memory leak (-2000byte). - */ - if ((ipsec_policy_in = ipsec_set_policy(L2TPD_IPSEC_POLICY_IN, - strlen(L2TPD_IPSEC_POLICY_IN))) == NULL) { - l2tpd_log(_this, LOG_ERR, - "ipsec_set_policy(L2TPD_IPSEC_POLICY_IN) failed " - "at %s(): %s: %m", __func__, ipsec_strerror()); - goto fail; - } - if ((ipsec_policy_out = ipsec_set_policy(L2TPD_IPSEC_POLICY_OUT, - strlen(L2TPD_IPSEC_POLICY_OUT))) == NULL) { - l2tpd_log(_this, LOG_ERR, - "ipsec_set_policy(L2TPD_IPSEC_POLICY_OUT) failed " - "at %s(): %s: %m", __func__, ipsec_strerror()); - goto fail; - } -#endif - } slist_itr_first(&_this->listener); while (slist_itr_has_next(&_this->listener)) { plsnr = slist_itr_next(&_this->listener); - rval |= l2tpd_listener_start(plsnr, ipsec_policy_in, - ipsec_policy_out); + rval |= l2tpd_listener_start(plsnr); } - if (ipsec_policy_in != NULL) - free(ipsec_policy_in); - if (ipsec_policy_out != NULL) - free(ipsec_policy_out); - if (rval == 0) _this->state = L2TPD_STATE_RUNNING; return rval; -#if 0 -fail: -#endif - if (ipsec_policy_in != NULL) - free(ipsec_policy_in); - if (ipsec_policy_out != NULL) - free(ipsec_policy_out); - - return 1; } /* stop l2tp lisnter */ @@ -619,138 +547,40 @@ l2tpd_stop(l2tpd *_this) /* * Configuration */ -#define CFG_KEY(p, s) config_key_prefix((p), (s)) -#define VAL_SEP " \t\r\n" - -CONFIG_FUNCTIONS(l2tpd_config, l2tpd, config); -PREFIXED_CONFIG_FUNCTIONS(l2tp_ctrl_config, l2tp_ctrl, l2tpd->config, - phy_label); - int -l2tpd_reload(l2tpd *_this, struct properties *config, const char *name, - int default_enabled) +l2tpd_reload(l2tpd *_this, struct l2tp_confs *l2tp_conf) { - int i, do_start, aierr; - const char *val; - char *tok, *cp, buf[L2TPD_CONFIG_BUFSIZ], *label; - struct addrinfo *ai; - - _this->config = config; - do_start = 0; - if (l2tpd_config_str_equal(_this, CFG_KEY(name, "enabled"), "true", - default_enabled)) { - /* care the case false-true flapping */ - if (l2tpd_is_shutting_down(_this)) - l2tpd_stop_immediatly(_this); - if (l2tpd_is_stopped(_this)) - do_start = 1; - } else { - if (!l2tpd_is_stopped(_this)) - l2tpd_stop(_this); - return 0; - } - if (do_start && l2tpd_init(_this) != 0) - return 1; - _this->config = config; - - /* default value */ - gethostname(_this->default_hostname, sizeof(_this->default_hostname)); - - _this->ctrl_in_pktdump = l2tpd_config_str_equal(_this, - "log.l2tp.ctrl.in.pktdump", "true", 0); - _this->data_in_pktdump = l2tpd_config_str_equal(_this, - "log.l2tp.data.in.pktdump", "true", 0); - _this->ctrl_out_pktdump = l2tpd_config_str_equal(_this, - "log.l2tp.ctrl.out.pktdump", "true", 0); - _this->data_out_pktdump = l2tpd_config_str_equal(_this, - "log.l2tp.data.out.pktdump", "true", 0); - _this->phy_label_with_ifname = l2tpd_config_str_equal(_this, - CFG_KEY(name, "label_with_ifname"), "true", 0); - - /* parse ip4_allow */ - in_addr_range_list_remove_all(&_this->ip4_allow); - val = l2tpd_config_str(_this, CFG_KEY(name, "ip4_allow")); - if (val != NULL) { - if (strlen(val) >= sizeof(buf)) { - l2tpd_log(_this, LOG_ERR, "configuration error at " - "l2tpd.ip4_allow: too long"); - return 1; - } - strlcpy(buf, val, sizeof(buf)); - for (cp = buf; (tok = strsep(&cp, VAL_SEP)) != NULL;) { - if (*tok == '\0') - continue; - if (in_addr_range_list_add(&_this->ip4_allow, tok) - != 0) { - l2tpd_log(_this, LOG_ERR, - "configuration error at " - "l2tpd.ip4_allow: %s", tok); - return 1; - } - } - } + int i; + struct l2tp_conf *conf; + l2tpd_listener *listener; - if (do_start) { - /* - * in the case of 1) cold-booted and 2) pptpd.enable - * toggled "false" to "true" do this, because we can - * assume that all pptpd listner are initialized. - */ - val = l2tpd_config_str(_this, CFG_KEY(name, "listener")); - if (val != NULL) { - if (strlen(val) >= sizeof(buf)) { - l2tpd_log(_this, LOG_ERR, - "configuration error at %s: too long", - CFG_KEY(name, "listener")); - return 1; - } - strlcpy(buf, val, sizeof(buf)); - - label = NULL; - /* it can accept multiple values with tab/space - * separation */ - for (i = 0, cp = buf; - (tok = strsep(&cp, VAL_SEP)) != NULL;) { - if (*tok == '\0') - continue; - if (label == NULL) { - label = tok; - continue; - } - if ((aierr = addrport_parse(tok, IPPROTO_UDP, - &ai)) != 0) { - l2tpd_log(_this, LOG_ERR, - "configuration error at " - "l2tpd.listener: %s: %s", label, - gai_strerror(aierr)); - label = NULL; - return 1; - } - if (l2tpd_add_listener(_this, i, label, - ai->ai_addr) != 0) { - freeaddrinfo(ai); - label = NULL; + if (slist_length(&_this->listener) > 0) { + /* + * TODO: add / remove / restart listener. + */ + slist_itr_first(&_this->listener); + while (slist_itr_has_next(&_this->listener)) { + listener = slist_itr_next(&_this->listener); + TAILQ_FOREACH(conf, l2tp_conf, entry) { + if (strcmp(listener->tun_name, + conf->name) == 0) { + listener->conf = conf; break; } - freeaddrinfo(ai); - label = NULL; - i++; - } - if (label != NULL) { - l2tpd_log(_this, LOG_ERR, "configuration " - "error at l2tpd.listener: %s", label); - return 1; } } - _this->purge_ipsec_sa = l2tpd_config_str_equal(_this, - CFG_KEY(name, "purge_ipsec_sa"), "true", 1); - _this->require_ipsec = l2tpd_config_str_equal(_this, - CFG_KEY(name, "require_ipsec"), "true", 1); - if (l2tpd_start(_this) != 0) - return 1; + return 0; } + if (l2tpd_init(_this) != 0) + return -1; + i = 0; + TAILQ_FOREACH(conf, l2tp_conf, entry) + l2tpd_add_listener(_this, i++, conf); + if (l2tpd_start(_this) != 0) + return -1; + return 0; } @@ -821,23 +651,12 @@ l2tpd_io_event(int fd, short evtype, void *ctx) #else nat_t = NULL; #endif - /* - * XXX check source address when NAT-T - */ - if (in_addr_range_list_includes( - &_l2tpd->ip4_allow, - &((struct sockaddr_in *)&peer)->sin_addr)) - l2tp_ctrl_input(_l2tpd, _this->index, - (struct sockaddr *)&peer, - (struct sockaddr *)&sock, nat_t, - buf, sz); - else - l2tpd_log_access_deny(_l2tpd, - "not allowed by acl.", - (struct sockaddr *)&peer); + l2tp_ctrl_input(_l2tpd, _this->index, + (struct sockaddr *)&peer, + (struct sockaddr *)&sock, nat_t, + buf, sz); break; case AF_INET6: - /* XXX source address restriction in IPv6? */ l2tp_ctrl_input(_l2tpd, _this->index, (struct sockaddr *)&peer, (struct sockaddr *)&sock, NULL, -- cgit v1.2.3-59-g8ed1b