summaryrefslogtreecommitdiffstats
path: root/usr.sbin/npppd/l2tp
diff options
context:
space:
mode:
authoryasuoka <yasuoka@openbsd.org>2012-09-18 13:14:08 +0000
committeryasuoka <yasuoka@openbsd.org>2012-09-18 13:14:08 +0000
commit821f7c5673b56ce7082633a67f8f8498f8f4faa2 (patch)
tree798092bb31b0c85298e91c7c3fc2cb5e2f6b4bd9 /usr.sbin/npppd/l2tp
parentthis structure is not useful and ill-named. remove it. (diff)
downloadwireguard-openbsd-821f7c5673b56ce7082633a67f8f8498f8f4faa2.tar.xz
wireguard-openbsd-821f7c5673b56ce7082633a67f8f8498f8f4faa2.zip
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
Diffstat (limited to 'usr.sbin/npppd/l2tp')
-rw-r--r--usr.sbin/npppd/l2tp/l2tp.h60
-rw-r--r--usr.sbin/npppd/l2tp/l2tp_call.c13
-rw-r--r--usr.sbin/npppd/l2tp/l2tp_conf.h50
-rw-r--r--usr.sbin/npppd/l2tp/l2tp_ctrl.c69
-rw-r--r--usr.sbin/npppd/l2tp/l2tpd.c381
5 files changed, 188 insertions, 385 deletions
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 <sys/types.h>
#include <sys/param.h>
@@ -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 <yasuoka@openbsd.org>
+ *
+ * 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 <sys/types.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+
+#include <stdbool.h>
+
+#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 <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
@@ -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 <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netinet/udp.h>
-#if 0
-#include <netinet6/ipsec.h>
-#endif
#include <stdlib.h>
#include <arpa/inet.h>
#include <stdio.h>
@@ -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,