From patchwork Wed Oct 9 03:34:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Quartulli X-Patchwork-Id: 861 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director9.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id aHm+BQrxnV2ncAAAIUCqbw for ; Wed, 09 Oct 2019 10:39:06 -0400 Received: from proxy4.mail.ord1d.rsapps.net ([172.30.191.6]) by director9.mail.ord1d.rsapps.net with LMTP id IF9xBQrxnV2HEAAAalYnBA ; Wed, 09 Oct 2019 10:39:06 -0400 Received: from smtp40.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy4.mail.ord1d.rsapps.net with LMTP id sPY/BQrxnV3DcgAAiYrejw ; Wed, 09 Oct 2019 10:39:06 -0400 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp40.gate.ord1d.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dmarc=none (p=nil; dis=none) header.from=unstable.cc X-Suspicious-Flag: YES X-Classification-ID: 8acd4134-eaa2-11e9-92dc-525400f204c2-1-1 Received: from [216.105.38.7] ([216.105.38.7:59494] helo=lists.sourceforge.net) by smtp40.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id E0/B3-15193-801FD9D5; Wed, 09 Oct 2019 10:39:05 -0400 Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1iID5o-0003QQ-Ag; Wed, 09 Oct 2019 14:37:32 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1iID5m-0003Q7-BN for openvpn-devel@lists.sourceforge.net; Wed, 09 Oct 2019 14:37:30 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=I22D6sSwuxfgupwfvKMwPnR30zq7oa7uwJk5d00tKcg=; b=Htx/t3gu3R0bNpEQKn/5iYb4iw Rv3ZeotSt3b7nLNYz4kMQ+hKJ8VYM/KDduRg/gZgs9gPXK4+xw63EWvAW41uid+ass7d940mbA4I5 lSW+wz6S3CWnLLXHEcEWzCh0JMK0wvJ8VHXikVIjPNA0inK52Cd1TE6gzIPnMhRLBmZs=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=I22D6sSwuxfgupwfvKMwPnR30zq7oa7uwJk5d00tKcg=; b=BPdGKS42dGgVyr8fFc24Ovqv/a xNTLbO9j9/LFE5KsRS+VoW6TBcYCY6iZKb4MZF4BcDiF/jaEuu/8GDZb/cygisVedybylezwUScw3 xOGT8VJ9plqCAofldpgMYdmKGBHNwHxtCwWW2HlOJbnCqa4DZE6nMie6UVYalAvXOFjs=; Received: from s2.neomailbox.net ([5.148.176.60]) by sfi-mx-4.v28.lw.sourceforge.com with esmtps (TLSv1.2:DHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1iID5k-00425O-Uj for openvpn-devel@lists.sourceforge.net; Wed, 09 Oct 2019 14:37:30 +0000 From: Antonio Quartulli To: openvpn-devel@lists.sourceforge.net Date: Wed, 9 Oct 2019 16:34:14 +0200 Message-Id: <20191009143422.9419-2-a@unstable.cc> In-Reply-To: <20191009143422.9419-1-a@unstable.cc> References: <20191009143422.9419-1-a@unstable.cc> MIME-Version: 1.0 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. 0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [URIs: unstable.cc] -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [5.148.176.60 listed in list.dnswl.org] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches SPF record 0.0 AWL AWL: Adjusted score from AWL reputation of From: address X-Headers-End: 1iID5k-00425O-Uj Subject: [Openvpn-devel] [PATCH 1/9] maddr: create helper function to populate maddr object from eth_addr X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Antonio Quartulli Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox Signed-off-by: Antonio Quartulli Acked-by: Gert Doering --- src/openvpn/mroute.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/openvpn/mroute.c b/src/openvpn/mroute.c index db8c9876..c52ef7b1 100644 --- a/src/openvpn/mroute.c +++ b/src/openvpn/mroute.c @@ -247,6 +247,16 @@ mroute_extract_addr_ip(struct mroute_addr *src, struct mroute_addr *dest, return ret; } +static void +mroute_copy_ether_to_addr(struct mroute_addr *maddr, + const uint8_t *ether_addr) +{ + maddr->type = MR_ADDR_ETHER; + maddr->netbits = 0; + maddr->len = OPENVPN_ETH_ALEN; + memcpy(maddr->eth_addr, ether_addr, OPENVPN_ETH_ALEN); +} + unsigned int mroute_extract_addr_ether(struct mroute_addr *src, struct mroute_addr *dest, @@ -260,17 +270,11 @@ mroute_extract_addr_ether(struct mroute_addr *src, const struct openvpn_ethhdr *eth = (const struct openvpn_ethhdr *) BPTR(buf); if (src) { - src->type = MR_ADDR_ETHER; - src->netbits = 0; - src->len = 6; - memcpy(src->eth_addr, eth->source, sizeof(dest->eth_addr)); + mroute_copy_ether_to_addr(src, eth->source); } if (dest) { - dest->type = MR_ADDR_ETHER; - dest->netbits = 0; - dest->len = 6; - memcpy(dest->eth_addr, eth->dest, sizeof(dest->eth_addr)); + mroute_copy_ether_to_addr(dest, eth->dest); /* ethernet broadcast/multicast packet? */ if (is_mac_mcast_addr(eth->dest)) From patchwork Wed Oct 9 03:34:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Quartulli X-Patchwork-Id: 856 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director8.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id yOdEAdbwnV0nEgAAIUCqbw for ; Wed, 09 Oct 2019 10:38:14 -0400 Received: from proxy3.mail.ord1d.rsapps.net ([172.30.191.6]) by director8.mail.ord1d.rsapps.net with LMTP id ID++ANbwnV3lEQAAfY0hYg ; Wed, 09 Oct 2019 10:38:14 -0400 Received: from smtp30.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy3.mail.ord1d.rsapps.net with LMTP id OBQJANbwnV1rfwAA7WKfLA ; Wed, 09 Oct 2019 10:38:14 -0400 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp30.gate.ord1d.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dmarc=none (p=nil; dis=none) header.from=unstable.cc X-Suspicious-Flag: YES X-Classification-ID: 6be96f68-eaa2-11e9-bd5c-5254001e8e38-1-1 Received: from [216.105.38.7] ([216.105.38.7:43464] helo=lists.sourceforge.net) by smtp30.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id AC/26-23160-5D0FD9D5; Wed, 09 Oct 2019 10:38:13 -0400 Received: from [127.0.0.1] (helo=sfs-ml-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1iID5t-0001tF-Qd; Wed, 09 Oct 2019 14:37:37 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1iID5p-0001rs-Lf for openvpn-devel@lists.sourceforge.net; Wed, 09 Oct 2019 14:37:33 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=ofbytL23KAw13oNg1uxnlVAAfeALUlb7qwXv6B4ZhK0=; b=HtSS4MBAjVO81x3HX3L+5SxvCj D9gDufiaS9OEvJ+y8+XTknhnyxWsSkcmbgt6mrrsq8zL8GgZSBDE1Uj4O61q1Kvs7+C41M9IBw2rz 2jhilysUZO7+DoisgTCdq5D+4vDLkScRk+OG+bVW6lSV+1RXIga3XJ9SGqRleZ9Eex/g=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=ofbytL23KAw13oNg1uxnlVAAfeALUlb7qwXv6B4ZhK0=; b=Abu4n0m7DuzD8eIXBO9OYQO3Wq HRVpeMJ9Pvh38JEqcw2NrqHS0ZuV3He9q3HcpHF0UafDdVha+gv/oN0JugnWwkLEVQdnU0k5qQCU1 oKiIZ8ufMkGPWSwE2BkDRK/mobw4ThmLkia7fmmcprGIzThU3FNpef2EI/eWQZ7kfVsI=; Received: from [5.148.176.60] (helo=s2.neomailbox.net) by sfi-mx-3.v28.lw.sourceforge.com with esmtps (TLSv1.2:DHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1iID5l-003zYo-Rp for openvpn-devel@lists.sourceforge.net; Wed, 09 Oct 2019 14:37:33 +0000 From: Antonio Quartulli To: openvpn-devel@lists.sourceforge.net Date: Wed, 9 Oct 2019 16:34:15 +0200 Message-Id: <20191009143422.9419-3-a@unstable.cc> In-Reply-To: <20191009143422.9419-1-a@unstable.cc> References: <20191009143422.9419-1-a@unstable.cc> MIME-Version: 1.0 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. 0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [URIs: openvpn.net] -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [5.148.176.60 listed in list.dnswl.org] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches SPF record 1.0 RDNS_NONE Delivered to internal network by a host with no rDNS -0.3 AWL AWL: Adjusted score from AWL reputation of From: address X-Headers-End: 1iID5l-003zYo-Rp Subject: [Openvpn-devel] [PATCH 2/9] VLAN: add basic VLAN tagging support X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Antonio Quartulli Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox This patch introduces basic support for VLAN tagging on the server side. The introduced functionality consists in allowing the user to assign a VID to the server TAP device and a VID to each client port. Client specific VID are assigned by means of files in CCD (like for other client specific settings). Once VIDs have been assigned, everything works as before, except that communications are allowed only between hosts having the same VID. With this patch all broadcast and client-to-client traffic is yet separated by VLAN: only client-to-server unicasts are affected. Signed-off-by: Fabian Knittel Signed-off-by: Antonio Quartulli Acked-by: Gert Doering --- src/openvpn/Makefile.am | 1 + src/openvpn/errlevel.h | 2 + src/openvpn/multi.c | 27 +++++++--- src/openvpn/multi.h | 2 + src/openvpn/options.c | 54 ++++++++++++++++++++ src/openvpn/options.h | 9 ++++ src/openvpn/proto.h | 25 +++++++++ src/openvpn/vlan.c | 110 ++++++++++++++++++++++++++++++++++++++++ src/openvpn/vlan.h | 44 ++++++++++++++++ 9 files changed, 268 insertions(+), 6 deletions(-) create mode 100644 src/openvpn/vlan.c create mode 100644 src/openvpn/vlan.h diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am index 30caa01f..bc976019 100644 --- a/src/openvpn/Makefile.am +++ b/src/openvpn/Makefile.am @@ -123,6 +123,7 @@ openvpn_SOURCES = \ syshead.h \ tls_crypt.c tls_crypt.h \ tun.c tun.h \ + vlan.c vlan.h \ win32.h win32.c \ cryptoapi.h cryptoapi.c openvpn_LDADD = \ diff --git a/src/openvpn/errlevel.h b/src/openvpn/errlevel.h index 60896c1f..e448fc37 100644 --- a/src/openvpn/errlevel.h +++ b/src/openvpn/errlevel.h @@ -148,6 +148,8 @@ #define D_PF_DEBUG LOGLEV(7, 72, M_DEBUG) /* packet filter debugging, must also define PF_DEBUG in pf.h */ #define D_PUSH_DEBUG LOGLEV(7, 73, M_DEBUG) /* show push/pull debugging info */ +#define D_VLAN_DEBUG LOGLEV(7, 74, M_DEBUG) /* show VLAN tagging/untagging debug info */ + #define D_HANDSHAKE_VERBOSE LOGLEV(8, 70, M_DEBUG) /* show detailed description of each handshake */ #define D_TLS_DEBUG_MED LOGLEV(8, 70, M_DEBUG) /* limited info from tls_session routines */ #define D_INTERVAL LOGLEV(8, 70, M_DEBUG) /* show interval.h debugging info */ diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c index d1f9c72e..8caaa868 100644 --- a/src/openvpn/multi.c +++ b/src/openvpn/multi.c @@ -45,6 +45,7 @@ #include "gremlin.h" #include "mstats.h" #include "ssl_verify.h" +#include "vlan.h" #include #include "memdbg.h" @@ -2208,7 +2209,8 @@ static void multi_bcast(struct multi_context *m, const struct buffer *buf, const struct multi_instance *sender_instance, - const struct mroute_addr *sender_addr) + const struct mroute_addr *sender_addr, + uint16_t vid) { struct hash_iterator hi; struct hash_element *he; @@ -2258,6 +2260,10 @@ multi_bcast(struct multi_context *m, } } #endif /* ifdef ENABLE_PF */ + if (vid != 0 && vid != mi->context.options.vlan_pvid) + { + continue; + } multi_add_mbuf(m, mi, mb); } } @@ -2595,7 +2601,7 @@ multi_process_incoming_link(struct multi_context *m, struct multi_instance *inst if (mroute_flags & MROUTE_EXTRACT_MCAST) { /* for now, treat multicast as broadcast */ - multi_bcast(m, &c->c2.to_tun, m->pending, NULL); + multi_bcast(m, &c->c2.to_tun, m->pending, NULL, 0); } else /* possible client to client routing */ { @@ -2640,6 +2646,15 @@ multi_process_incoming_link(struct multi_context *m, struct multi_instance *inst struct mroute_addr edest; mroute_addr_reset(&edest); #endif + if (m->top.options.vlan_tagging) + { + if (vlan_is_tagged(&c->c2.to_tun)) + { + /* Drop VLAN-tagged frame. */ + msg(D_VLAN_DEBUG, "dropping incoming VLAN-tagged frame"); + c->c2.to_tun.len = 0; + } + } /* extract packet source and dest addresses */ mroute_flags = mroute_extract_addr_from_packet(&src, &dest, @@ -2661,7 +2676,7 @@ multi_process_incoming_link(struct multi_context *m, struct multi_instance *inst { if (mroute_flags & (MROUTE_EXTRACT_BCAST|MROUTE_EXTRACT_MCAST)) { - multi_bcast(m, &c->c2.to_tun, m->pending, NULL); + multi_bcast(m, &c->c2.to_tun, m->pending, NULL, 0); } else /* try client-to-client routing */ { @@ -2788,9 +2803,9 @@ multi_process_incoming_tun(struct multi_context *m, const unsigned int mpp_flags { /* for now, treat multicast as broadcast */ #ifdef ENABLE_PF - multi_bcast(m, &m->top.c2.buf, NULL, e2); + multi_bcast(m, &m->top.c2.buf, NULL, e2, 0); #else - multi_bcast(m, &m->top.c2.buf, NULL, NULL); + multi_bcast(m, &m->top.c2.buf, NULL, NULL, 0); #endif } else @@ -2972,7 +2987,7 @@ gremlin_flood_clients(struct multi_context *m) for (i = 0; i < parm.n_packets; ++i) { - multi_bcast(m, &buf, NULL, NULL); + multi_bcast(m, &buf, NULL, NULL, 0); } gc_free(&gc); diff --git a/src/openvpn/multi.h b/src/openvpn/multi.h index d87f21b9..cfd86bbe 100644 --- a/src/openvpn/multi.h +++ b/src/openvpn/multi.h @@ -40,6 +40,7 @@ #include "mudp.h" #include "mtcp.h" #include "perf.h" +#include "vlan.h" #define MULTI_PREFIX_MAX_LENGTH 256 @@ -620,6 +621,7 @@ multi_process_outgoing_tun(struct multi_context *m, const unsigned int mpp_flags mi->context.c2.to_tun.len); #endif set_prefix(mi); + vlan_process_outgoing_tun(m, mi); process_outgoing_tun(&mi->context); ret = multi_process_post(m, mi, mpp_flags); clear_prefix(); diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 2d3865a6..caba6494 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -53,6 +53,7 @@ #include "win32.h" #include "push.h" #include "pool.h" +#include "proto.h" #include "helper.h" #include "manage.h" #include "forward.h" @@ -404,6 +405,8 @@ static const char usage_message[] = "--plugin m [str]: Load plug-in module m passing str as an argument\n" " to its initialization function.\n" #endif + "--vlan-tagging : Enable 802.1Q-based VLAN tagging.\n" + "--vlan-pvid v : Sets the Port VLAN Identifier. Defaults to 1.\n" #if P2MP #if P2MP_SERVER "\n" @@ -849,6 +852,8 @@ init_options(struct options *o, const bool init_gc) o->route_method = ROUTE_METHOD_ADAPTIVE; o->block_outside_dns = false; #endif + o->vlan_accept = VLAN_ONLY_UNTAGGED_OR_PRIORITY; + o->vlan_pvid = 1; #if P2MP_SERVER o->real_hash_size = 256; o->virtual_hash_size = 256; @@ -1224,6 +1229,17 @@ dhcp_option_address_parse(const char *name, const char *parm, in_addr_t *array, #endif /* if defined(_WIN32) || defined(TARGET_ANDROID) */ +static const char * +print_vlan_accept(enum vlan_acceptable_frames mode) +{ + switch (mode) + { + case VLAN_ONLY_UNTAGGED_OR_PRIORITY: + return "untagged"; + } + return NULL; +} + #if P2MP #ifndef ENABLE_SMALL @@ -1293,6 +1309,9 @@ show_p2mp_parms(const struct options *o) SHOW_STR(port_share_host); SHOW_STR(port_share_port); #endif + SHOW_BOOL(vlan_tagging); + msg(D_SHOW_PARMS, " vlan_accept = %s", print_vlan_accept (o->vlan_accept)); + SHOW_INT(vlan_pvid); #endif /* P2MP_SERVER */ SHOW_BOOL(client); @@ -2355,6 +2374,18 @@ options_postprocess_verify_ce(const struct options *options, const struct connec msg(M_USAGE, "--auth-user-pass-optional %s", postfix); } } + + if (options->vlan_tagging && dev != DEV_TYPE_TAP) + { + msg(M_USAGE, "--vlan-tagging must be used with --dev tap"); + } + if (!options->vlan_tagging) + { + if (options->vlan_pvid != defaults.vlan_pvid) + { + msg(M_USAGE, "--vlan-pvid requires --vlan-tagging"); + } + } } else { @@ -2444,6 +2475,11 @@ options_postprocess_verify_ce(const struct options *options, const struct connec { msg(M_USAGE, "--stale-routes-check requires --mode server"); } + + if (options->vlan_tagging) + { + msg(M_USAGE, "--vlan-tagging requires --mode server"); + } } #endif /* P2MP_SERVER */ @@ -8359,6 +8395,24 @@ add_option(struct options *options, VERIFY_PERMISSION(OPT_P_GENERAL); options->allow_recursive_routing = true; } + else if (streq(p[0], "vlan-tagging") && !p[1]) + { + VERIFY_PERMISSION(OPT_P_GENERAL); + options->vlan_tagging = true; + } + else if (streq(p[0], "vlan-pvid") && p[1] && !p[2]) + { + VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_INSTANCE); + options->vlan_pvid = positive_atoi(p[1]); + if (options->vlan_pvid < OPENVPN_8021Q_MIN_VID + || options->vlan_pvid > OPENVPN_8021Q_MAX_VID) + { + msg(msglevel, + "the parameter of --vlan-pvid parameters must be >= %u and <= %u", + OPENVPN_8021Q_MIN_VID, OPENVPN_8021Q_MAX_VID); + goto err; + } + } else { int i; diff --git a/src/openvpn/options.h b/src/openvpn/options.h index 63f0f4cb..3f5c5465 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -169,6 +169,11 @@ struct remote_list struct remote_entry *array[CONNECTION_LIST_SIZE]; }; +enum vlan_acceptable_frames +{ + VLAN_ONLY_UNTAGGED_OR_PRIORITY, +}; + struct remote_host_store { #define RH_HOST_LEN 80 @@ -632,6 +637,10 @@ struct options int keying_material_exporter_length; #endif + bool vlan_tagging; + enum vlan_acceptable_frames vlan_accept; + uint16_t vlan_pvid; + struct pull_filter_list *pull_filter_list; /* Useful when packets sent by openvpn itself are not subject diff --git a/src/openvpn/proto.h b/src/openvpn/proto.h index 4ddffc7d..c1ff3e14 100644 --- a/src/openvpn/proto.h +++ b/src/openvpn/proto.h @@ -60,9 +60,31 @@ struct openvpn_ethhdr #define OPENVPN_ETH_P_IPV4 0x0800 /* IPv4 protocol */ #define OPENVPN_ETH_P_IPV6 0x86DD /* IPv6 protocol */ #define OPENVPN_ETH_P_ARP 0x0806 /* ARP protocol */ +#define OPENVPN_ETH_P_8021Q 0x8100 /* 802.1Q protocol */ uint16_t proto; /* packet type ID field */ }; +struct openvpn_8021qhdr +{ + uint8_t dest[OPENVPN_ETH_ALEN]; /* destination ethernet addr */ + uint8_t source[OPENVPN_ETH_ALEN]; /* source ethernet addr */ + + uint16_t tpid; /* 802.1Q Tag Protocol Identifier */ +#define OPENVPN_8021Q_MASK_PCP htons(0xE000) /* mask PCP out of pcp_cfi_vid */ +#define OPENVPN_8021Q_MASK_CFI htons(0x1000) /* mask CFI out of pcp_cfi_vid */ +#define OPENVPN_8021Q_MASK_VID htons(0x0FFF) /* mask VID out of pcp_cfi_vid */ + uint16_t pcp_cfi_vid; /* bit fields, see IEEE 802.1Q */ + uint16_t proto; /* contained packet type ID field */ +}; + +/* + * Size difference between a regular Ethernet II header and an Ethernet II + * header with additional IEEE 802.1Q tagging. + */ +#define SIZE_ETH_TO_8021Q_HDR (sizeof(struct openvpn_8021qhdr) \ + - sizeof(struct openvpn_ethhdr)) + + struct openvpn_arp { #define ARP_MAC_ADDR_TYPE 0x0001 uint16_t mac_addr_type; /* 0x0001 */ @@ -311,4 +333,7 @@ void ipv4_packet_size_verify(const uint8_t *data, #endif +#define OPENVPN_8021Q_MIN_VID 1 +#define OPENVPN_8021Q_MAX_VID 4094 + #endif /* ifndef PROTO_H */ diff --git a/src/openvpn/vlan.c b/src/openvpn/vlan.c new file mode 100644 index 00000000..8e987277 --- /dev/null +++ b/src/openvpn/vlan.c @@ -0,0 +1,110 @@ +/* + * OpenVPN -- An application to securely tunnel IP networks + * over a single TCP/UDP port, with support for SSL/TLS-based + * session authentication and key exchange, + * packet encryption, packet authentication, and + * packet compression. + * + * Copyright (C) 2002-2019 OpenVPN Technologies, Inc. + * Copyright (C) 2010 Fabian Knittel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + +#include "syshead.h" + +#if P2MP_SERVER + +#include "multi.h" +#include "options.h" +#include "vlan.h" + +/* + * Retrieve the VLAN Identifier (VID) from the IEEE 802.1Q header. + * + * @param hdr Pointer to the Ethernet header with IEEE 802.1Q tagging. + * @return Returns the VID in host byte order. + */ +static uint16_t +vlanhdr_get_vid(const struct openvpn_8021qhdr *hdr) +{ + return ntohs(hdr->pcp_cfi_vid & OPENVPN_8021Q_MASK_VID); +} + +/* + * vlan_is_tagged - check if a packet is VLAN-tagged + * + * Checks whether ethernet frame is VLAN-tagged. + * + * @param buf The ethernet frame. + * @return Returns true if the frame is VLAN-tagged, false otherwise. + */ +bool +vlan_is_tagged(const struct buffer *buf) +{ + const struct openvpn_8021qhdr *vlanhdr; + uint16_t vid; + + if (BLEN(buf) < sizeof(struct openvpn_8021qhdr)) + { + /* frame too small to be VLAN-tagged */ + return false; + } + + vlanhdr = (const struct openvpn_8021qhdr *)BPTR(buf); + + if (ntohs(vlanhdr->tpid) != OPENVPN_ETH_P_8021Q) + { + /* non tagged frame */ + return false; + } + + vid = vlanhdr_get_vid(vlanhdr); + if (vid == 0) + { + /* no vid: piority tagged only */ + return false; + } + + return true; +} + +void +vlan_process_outgoing_tun(struct multi_context *m, struct multi_instance *mi) +{ + if (!m->top.options.vlan_tagging) + { + return; + } + + if (m->top.options.vlan_accept == VLAN_ONLY_UNTAGGED_OR_PRIORITY) + { + /* Packets forwarded to the TAP devices aren't VLAN-tagged. Only packets + * matching the PVID configured globally are allowed to be received + */ + if (m->top.options.vlan_pvid != mi->context.options.vlan_pvid) + { + /* Packet is coming from the wrong VID, drop it. */ + mi->context.c2.to_tun.len = 0; + } + } +} + +#endif /* P2MP_SERVER */ diff --git a/src/openvpn/vlan.h b/src/openvpn/vlan.h new file mode 100644 index 00000000..1ef68813 --- /dev/null +++ b/src/openvpn/vlan.h @@ -0,0 +1,44 @@ +/* + * OpenVPN -- An application to securely tunnel IP networks + * over a single TCP/UDP port, with support for SSL/TLS-based + * session authentication and key exchange, + * packet encryption, packet authentication, and + * packet compression. + * + * Copyright (C) 2002-2019 OpenVPN Technologies, Inc. + * Copyright (C) 2010 Fabian Knittel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef VLAN_H +#define VLAN_H + +#if P2MP_SERVER + +#include "buffer.h" +#include "mroute.h" + +struct multi_context; +struct multi_instance; + +bool +vlan_is_tagged(const struct buffer *buf); + +void +vlan_process_outgoing_tun(struct multi_context *m, struct multi_instance *mi); + +#endif /* P2MP_SERVER */ + +#endif /* VLAN_H */ From patchwork Wed Oct 9 03:34:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Quartulli X-Patchwork-Id: 862 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director8.mail.ord1d.rsapps.net ([172.27.255.53]) by backend30.mail.ord1d.rsapps.net with LMTP id GEwmLw3xnV23IAAAIUCqbw for ; Wed, 09 Oct 2019 10:39:09 -0400 Received: from proxy2.mail.iad3a.rsapps.net ([172.27.255.53]) by director8.mail.ord1d.rsapps.net with LMTP id wEg0LA3xnV1zEgAAfY0hYg ; Wed, 09 Oct 2019 10:39:09 -0400 Received: from smtp8.gate.iad3a ([172.27.255.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy2.mail.iad3a.rsapps.net with LMTP id OBxxJg3xnV2fagAABcWvHw ; Wed, 09 Oct 2019 10:39:09 -0400 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp8.gate.iad3a.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dmarc=none (p=nil; dis=none) header.from=unstable.cc X-Suspicious-Flag: YES X-Classification-ID: 8d1bde14-eaa2-11e9-91bb-525400b8fe03-1-1 Received: from [216.105.38.7] ([216.105.38.7:38262] helo=lists.sourceforge.net) by smtp8.gate.iad3a.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 50/B3-29775-C01FD9D5; Wed, 09 Oct 2019 10:39:09 -0400 Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1iID5m-0003QF-Qv; Wed, 09 Oct 2019 14:37:31 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1iID5l-0003Q0-Br for openvpn-devel@lists.sourceforge.net; Wed, 09 Oct 2019 14:37:29 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=P9LyT1+hVRl2g7uGXVtfeyRe5pxV64Jiz7GTcmkpLBg=; b=KKquYrUJmuhqc6G1Y637xoUoIE ASBQU2TqzzpKvDClsA9Kzy8ndM33mlhTqVzvjcM45L3ImIUb0zx3DaXz1yptKSIKUPs2j1eSOqb1X /ZJx1xZfMM3wbmLSUCcgVHqskSoObd3CNZGUSsR3OAKLdpP6OJcbRwqimNJh2sK/zntg=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=P9LyT1+hVRl2g7uGXVtfeyRe5pxV64Jiz7GTcmkpLBg=; b=W3FV6JRPdIh0a9FBnJpUh21Iw5 FdVHLsfFUlPh9qc9Lf8YPNnpHnB2Nz45h2L8U8Nh/D8knHKun+WcTnYtVwbQ7wkj1QEmlj18rpy8f uzVtcmUVTwGoKWabRUH2PNPUYOTvgjBQUJybdmYMZp2H0EfKUcT5CJ9Q8Ov6PbUP+SqY=; Received: from s2.neomailbox.net ([5.148.176.60]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLSv1.2:DHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1iID5i-00BOLl-V0 for openvpn-devel@lists.sourceforge.net; Wed, 09 Oct 2019 14:37:29 +0000 From: Antonio Quartulli To: openvpn-devel@lists.sourceforge.net Date: Wed, 9 Oct 2019 16:34:16 +0200 Message-Id: <20191009143422.9419-4-a@unstable.cc> In-Reply-To: <20191009143422.9419-1-a@unstable.cc> References: <20191009143422.9419-1-a@unstable.cc> MIME-Version: 1.0 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. 0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [URIs: unstable.cc] -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [5.148.176.60 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 AWL AWL: Adjusted score from AWL reputation of From: address X-Headers-End: 1iID5i-00BOLl-V0 Subject: [Openvpn-devel] [PATCH 3/9] maddr: export VLAN ID from client context to maddr object X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Antonio Quartulli Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox When receiving a packet from a client, the associated maddr needs to carry also the VID associated with that client. This way the VID can be appended to the packet later, if needed. This patch adds support for exporting the VID from the client context to the related per-packet maddr object. Signed-off-by: Fabian Knittel Signed-off-by: Antonio Quartulli Acked-by: Gert Doering --- src/openvpn/mroute.c | 54 +++++++++++++++++++++++++++++++------------- src/openvpn/mroute.h | 11 ++++++--- src/openvpn/multi.c | 3 +++ 3 files changed, 49 insertions(+), 19 deletions(-) diff --git a/src/openvpn/mroute.c b/src/openvpn/mroute.c index c52ef7b1..bdb1b0c0 100644 --- a/src/openvpn/mroute.c +++ b/src/openvpn/mroute.c @@ -58,7 +58,7 @@ static inline bool is_mac_mcast_maddr(const struct mroute_addr *addr) { return (addr->type & MR_ADDR_MASK) == MR_ADDR_ETHER - && is_mac_mcast_addr(addr->eth_addr); + && is_mac_mcast_addr(addr->ether.addr); } /* @@ -249,12 +249,15 @@ mroute_extract_addr_ip(struct mroute_addr *src, struct mroute_addr *dest, static void mroute_copy_ether_to_addr(struct mroute_addr *maddr, - const uint8_t *ether_addr) + const uint8_t *ether_addr, + uint16_t vid) { maddr->type = MR_ADDR_ETHER; maddr->netbits = 0; maddr->len = OPENVPN_ETH_ALEN; - memcpy(maddr->eth_addr, ether_addr, OPENVPN_ETH_ALEN); + memcpy(maddr->ether.addr, ether_addr, OPENVPN_ETH_ALEN); + maddr->len += sizeof(vid); + maddr->ether.vid = vid; } unsigned int @@ -262,6 +265,7 @@ mroute_extract_addr_ether(struct mroute_addr *src, struct mroute_addr *dest, struct mroute_addr *esrc, struct mroute_addr *edest, + uint16_t vid, const struct buffer *buf) { unsigned int ret = 0; @@ -270,11 +274,11 @@ mroute_extract_addr_ether(struct mroute_addr *src, const struct openvpn_ethhdr *eth = (const struct openvpn_ethhdr *) BPTR(buf); if (src) { - mroute_copy_ether_to_addr(src, eth->source); + mroute_copy_ether_to_addr(src, eth->source, vid); } if (dest) { - mroute_copy_ether_to_addr(dest, eth->dest); + mroute_copy_ether_to_addr(dest, eth->dest, vid); /* ethernet broadcast/multicast packet? */ if (is_mac_mcast_addr(eth->dest)) @@ -289,18 +293,35 @@ mroute_extract_addr_ether(struct mroute_addr *src, if (esrc || edest) { struct buffer b = *buf; - if (buf_advance(&b, sizeof(struct openvpn_ethhdr))) + if (!buf_advance(&b, sizeof(struct openvpn_ethhdr))) { - switch (ntohs(eth->proto)) - { - case OPENVPN_ETH_P_IPV4: - ret |= (mroute_extract_addr_ip(esrc, edest, &b) << MROUTE_SEC_SHIFT); - break; + return 0; + } - case OPENVPN_ETH_P_ARP: - ret |= (mroute_extract_addr_arp(esrc, edest, &b) << MROUTE_SEC_SHIFT); - break; + uint16_t proto = eth->proto; + if (proto == htons(OPENVPN_ETH_P_8021Q)) + { + if (!buf_advance(&b, SIZE_ETH_TO_8021Q_HDR)) + { + /* It's an 802.1Q packet, but doesn't have a full header, + * so something went wrong */ + return 0; } + + const struct openvpn_8021qhdr *tag; + tag = (const struct openvpn_8021qhdr *)BPTR(buf); + proto = tag->proto; + } + + switch (ntohs(proto)) + { + case OPENVPN_ETH_P_IPV4: + ret |= (mroute_extract_addr_ip(esrc, edest, &b) << MROUTE_SEC_SHIFT); + break; + + case OPENVPN_ETH_P_ARP: + ret |= (mroute_extract_addr_arp(esrc, edest, &b) << MROUTE_SEC_SHIFT); + break; } } #endif @@ -444,8 +465,9 @@ mroute_addr_print_ex(const struct mroute_addr *ma, switch (maddr.type & MR_ADDR_MASK) { case MR_ADDR_ETHER: - buf_printf(&out, "%s", format_hex_ex(ma->eth_addr, - sizeof(ma->eth_addr), 0, 1, ":", gc)); + buf_printf(&out, "%s", format_hex_ex(ma->ether.addr, + sizeof(ma->ether.addr), 0, 1, ":", gc)); + buf_printf(&out, "@%hu", ma->ether.vid); break; case MR_ADDR_IPV4: diff --git a/src/openvpn/mroute.h b/src/openvpn/mroute.h index 7fcd9956..113aa8c5 100644 --- a/src/openvpn/mroute.h +++ b/src/openvpn/mroute.h @@ -82,7 +82,10 @@ struct mroute_addr { * valid if MR_WITH_NETBITS is set */ union { uint8_t raw_addr[MR_MAX_ADDR_LEN]; /* actual address */ - uint8_t eth_addr[OPENVPN_ETH_ALEN]; + struct { + uint8_t addr[OPENVPN_ETH_ALEN]; + uint16_t vid; + } ether; struct { in_addr_t addr; /* _network order_ IPv4 address */ in_port_t port; /* _network order_ TCP/UDP port */ @@ -100,7 +103,7 @@ struct mroute_addr { /* Wrappers to support compilers that do not grok anonymous unions */ mroute_union #define raw_addr mroute_union.raw_addr -#define eth_addr mroute_union.eth_addr +#define ether mroute_union.ether #define v4 mroute_union.v4 #define v6 mroute_union.v6 #define v4mappedv6 mroute_union.v4mappedv6 @@ -178,6 +181,7 @@ unsigned int mroute_extract_addr_ether(struct mroute_addr *src, struct mroute_addr *dest, struct mroute_addr *esrc, struct mroute_addr *edest, + uint16_t vid, const struct buffer *buf); /* @@ -189,6 +193,7 @@ mroute_extract_addr_from_packet(struct mroute_addr *src, struct mroute_addr *dest, struct mroute_addr *esrc, struct mroute_addr *edest, + uint16_t vid, const struct buffer *buf, int tunnel_type) { @@ -200,7 +205,7 @@ mroute_extract_addr_from_packet(struct mroute_addr *src, } else if (tunnel_type == DEV_TYPE_TAP) { - ret = mroute_extract_addr_ether(src, dest, esrc, edest, buf); + ret = mroute_extract_addr_ether(src, dest, esrc, edest, vid, buf); } return ret; } diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c index 8caaa868..95b33e7a 100644 --- a/src/openvpn/multi.c +++ b/src/openvpn/multi.c @@ -2570,6 +2570,7 @@ multi_process_incoming_link(struct multi_context *m, struct multi_instance *inst &dest, NULL, NULL, + 0, &c->c2.to_tun, DEV_TYPE_TUN); @@ -2664,6 +2665,7 @@ multi_process_incoming_link(struct multi_context *m, struct multi_instance *inst #else NULL, #endif + 0, &c->c2.to_tun, DEV_TYPE_TAP); @@ -2791,6 +2793,7 @@ multi_process_incoming_tun(struct multi_context *m, const unsigned int mpp_flags NULL, #endif NULL, + 0, &m->top.c2.buf, dev_type); From patchwork Wed Oct 9 03:34:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Quartulli X-Patchwork-Id: 857 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director11.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id kL9oAePwnV1qMQAAIUCqbw for ; Wed, 09 Oct 2019 10:38:27 -0400 Received: from proxy4.mail.ord1d.rsapps.net ([172.30.191.6]) by director11.mail.ord1d.rsapps.net with LMTP id wOQiAePwnV3+DQAAvGGmqA ; Wed, 09 Oct 2019 10:38:27 -0400 Received: from smtp19.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy4.mail.ord1d.rsapps.net with LMTP id YBXfAOPwnV2BcQAAiYrejw ; Wed, 09 Oct 2019 10:38:27 -0400 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp19.gate.ord1d.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dmarc=none (p=nil; dis=none) header.from=unstable.cc X-Suspicious-Flag: YES X-Classification-ID: 73ab462c-eaa2-11e9-9e24-525400d67fa8-1-1 Received: from [216.105.38.7] ([216.105.38.7:49732] helo=lists.sourceforge.net) by smtp19.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id F8/B5-07025-2E0FD9D5; Wed, 09 Oct 2019 10:38:26 -0400 Received: from [127.0.0.1] (helo=sfs-ml-2.v29.lw.sourceforge.com) by sfs-ml-2.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1iID5m-0004VB-E0; Wed, 09 Oct 2019 14:37:30 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1iID5l-0004V4-7l for openvpn-devel@lists.sourceforge.net; Wed, 09 Oct 2019 14:37:29 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=s8gRI18mOoO8758PZ0okRLkaObl1FWfuqoJhMgkzGkU=; b=Dy4oKFJY7PgrUVOKkkYoDLNDZ7 QPJEbedyqGFNMJdmNgdcCB0lbQlYzFuYGuAQYavxhQbvNomTvpcNMsXdnX+f5PeyBiMVa7K6wuEz5 dH7lKvD9f742Aibk3CsPujyuKqeRqmOAj6Stcr3OGKQqCBvVyO86LRm65d6CVXrvCe3E=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=s8gRI18mOoO8758PZ0okRLkaObl1FWfuqoJhMgkzGkU=; b=cE6SnJs6j29QUwxnLNyiKWD3ga mv7QMEy9cert+yPC6z8RbrVD9MoPK1atqVr81beRhYiY3i6ji07IH9PGSuTQCZikPMyYbZonx+LOs FHHJ4dlduDgcw/32/rnEb2o+ChBvqUBIyDNmZ4wfBCJh4rWQW6Adh3GQJSnnVYf+2+/w=; Received: from s2.neomailbox.net ([5.148.176.60]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLSv1.2:DHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1iID5j-00BOLp-8v for openvpn-devel@lists.sourceforge.net; Wed, 09 Oct 2019 14:37:29 +0000 From: Antonio Quartulli To: openvpn-devel@lists.sourceforge.net Date: Wed, 9 Oct 2019 16:34:17 +0200 Message-Id: <20191009143422.9419-5-a@unstable.cc> In-Reply-To: <20191009143422.9419-1-a@unstable.cc> References: <20191009143422.9419-1-a@unstable.cc> MIME-Version: 1.0 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. 0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [URIs: lettink.de] -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [5.148.176.60 listed in list.dnswl.org] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches SPF record 0.0 AWL AWL: Adjusted score from AWL reputation of From: address X-Headers-End: 1iID5j-00BOLp-8v Subject: [Openvpn-devel] [PATCH 4/9] VLAN: filter multicast and client-to-client unicast traffic X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Antonio Quartulli Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox With this change, client-to-client communications are possible only if clients were configured with the same PVID. At the same time also broadcast packets are now forwarded only to hosts belonging to the originator VLAN. Signed-off-by: Fabian Knittel Signed-off-by: Antonio Quartulli Acked-by: Gert Doering --- src/openvpn/multi.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c index 95b33e7a..e733ca9a 100644 --- a/src/openvpn/multi.c +++ b/src/openvpn/multi.c @@ -2643,10 +2643,12 @@ multi_process_incoming_link(struct multi_context *m, struct multi_instance *inst } else if (TUNNEL_TYPE(m->top.c1.tuntap) == DEV_TYPE_TAP) { + uint16_t vid = 0; #ifdef ENABLE_PF struct mroute_addr edest; mroute_addr_reset(&edest); #endif + if (m->top.options.vlan_tagging) { if (vlan_is_tagged(&c->c2.to_tun)) @@ -2655,6 +2657,10 @@ multi_process_incoming_link(struct multi_context *m, struct multi_instance *inst msg(D_VLAN_DEBUG, "dropping incoming VLAN-tagged frame"); c->c2.to_tun.len = 0; } + else + { + vid = c->options.vlan_pvid; + } } /* extract packet source and dest addresses */ mroute_flags = mroute_extract_addr_from_packet(&src, @@ -2665,7 +2671,7 @@ multi_process_incoming_link(struct multi_context *m, struct multi_instance *inst #else NULL, #endif - 0, + vid, &c->c2.to_tun, DEV_TYPE_TAP); @@ -2678,7 +2684,8 @@ multi_process_incoming_link(struct multi_context *m, struct multi_instance *inst { if (mroute_flags & (MROUTE_EXTRACT_BCAST|MROUTE_EXTRACT_MCAST)) { - multi_bcast(m, &c->c2.to_tun, m->pending, NULL, 0); + multi_bcast(m, &c->c2.to_tun, m->pending, NULL, + vid); } else /* try client-to-client routing */ { From patchwork Wed Oct 9 03:34:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Quartulli X-Patchwork-Id: 853 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director11.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id kPdcOdTwnV29FQAAIUCqbw for ; Wed, 09 Oct 2019 10:38:12 -0400 Received: from proxy3.mail.ord1d.rsapps.net ([172.30.191.6]) by director11.mail.ord1d.rsapps.net with LMTP id wDQTOdTwnV35DQAAvGGmqA ; Wed, 09 Oct 2019 10:38:12 -0400 Received: from smtp4.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy3.mail.ord1d.rsapps.net with LMTP id yFNgONTwnV06AQAA7WKfLA ; Wed, 09 Oct 2019 10:38:12 -0400 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp4.gate.ord1d.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dmarc=none (p=nil; dis=none) header.from=unstable.cc X-Suspicious-Flag: YES X-Classification-ID: 6b8038cc-eaa2-11e9-b0e5-525400760ffc-1-1 Received: from [216.105.38.7] ([216.105.38.7:43434] helo=lists.sourceforge.net) by smtp4.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 07/BD-31218-4D0FD9D5; Wed, 09 Oct 2019 10:38:12 -0400 Received: from [127.0.0.1] (helo=sfs-ml-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1iID5p-0001rf-HA; Wed, 09 Oct 2019 14:37:33 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1iID5n-0001rC-LA for openvpn-devel@lists.sourceforge.net; Wed, 09 Oct 2019 14:37:31 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=GJ3HXHMXYojvPscuomNc2nKyV97fm2TOOuEGZgsvWGY=; b=Irq5rrHfKRrEntZQeZ9MDzRvwU OJvAuao322J6EBcvJdCAza83rhsVaXmc3yMlWexrvT4gSjQJW0OuSRnkQmig5eoU7+XUOK3hBBgtc 5laXePEJcCNiJvT9+OVTZJZcdqHKQDG+1zElet6diOEGU6aByMrI3v/9OhrwJAEb1PTk=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=GJ3HXHMXYojvPscuomNc2nKyV97fm2TOOuEGZgsvWGY=; b=SOt1Km/CiwNph9Ge2OUlqdo64A +koRWo6JhO+4N4UeUsnNk+eXA82eu+0fIunyOi8XDXkuj/ksKTnKaRa3lrqq6RiHZm7XTWiPYpLKk Iqvx7eI/kLx9s6lR9MoCIookdl3cNHC8Vg8VpVpWyjMQGjFzLlOzzh/J+gXp62wmOUOw=; Received: from [5.148.176.60] (helo=s2.neomailbox.net) by sfi-mx-3.v28.lw.sourceforge.com with esmtps (TLSv1.2:DHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1iID5m-003zZ3-6Q for openvpn-devel@lists.sourceforge.net; Wed, 09 Oct 2019 14:37:31 +0000 From: Antonio Quartulli To: openvpn-devel@lists.sourceforge.net Date: Wed, 9 Oct 2019 16:34:18 +0200 Message-Id: <20191009143422.9419-6-a@unstable.cc> In-Reply-To: <20191009143422.9419-1-a@unstable.cc> References: <20191009143422.9419-1-a@unstable.cc> MIME-Version: 1.0 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. 0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [URIs: unstable.cc] -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [5.148.176.60 listed in list.dnswl.org] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches SPF record 1.0 RDNS_NONE Delivered to internal network by a host with no rDNS -0.5 AWL AWL: Adjusted score from AWL reputation of From: address X-Headers-End: 1iID5m-003zZ3-6Q Subject: [Openvpn-devel] [PATCH 5/9] is_ipv_X: add support for parsing IP header inside a 802.1q frame X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Antonio Quartulli Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox Extend is_ipv_X() routine by properly parsing 802.1q frame rather than dropping them. This change is required in order to allow OpenVPN to accept VLAN tagged frames, which otherwise would be dropped when trying to access the inner IP header. While at it, slightly fix the function style. Signed-off-by: Fabian Knittel Signed-off-by: Antonio Quartulli Acked-by: Gert Doering --- src/openvpn/proto.c | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/src/openvpn/proto.c b/src/openvpn/proto.c index 3bf22174..6f4d9294 100644 --- a/src/openvpn/proto.c +++ b/src/openvpn/proto.c @@ -38,17 +38,17 @@ * If raw tunnel packet is IPv, return true and increment * buffer offset to start of IP header. */ -static -bool -is_ipv_X( int tunnel_type, struct buffer *buf, int ip_ver ) +static bool +is_ipv_X(int tunnel_type, struct buffer *buf, int ip_ver) { int offset; + uint16_t proto; const struct openvpn_iphdr *ih; verify_align_4(buf); if (tunnel_type == DEV_TYPE_TUN) { - if (BLEN(buf) < (int) sizeof(struct openvpn_iphdr)) + if (BLEN(buf) < sizeof(struct openvpn_iphdr)) { return false; } @@ -57,24 +57,46 @@ is_ipv_X( int tunnel_type, struct buffer *buf, int ip_ver ) else if (tunnel_type == DEV_TYPE_TAP) { const struct openvpn_ethhdr *eh; - if (BLEN(buf) < (int)(sizeof(struct openvpn_ethhdr) - + sizeof(struct openvpn_iphdr))) + if (BLEN(buf) < (sizeof(struct openvpn_ethhdr) + + sizeof(struct openvpn_iphdr))) { return false; } - eh = (const struct openvpn_ethhdr *) BPTR(buf); - if (ntohs(eh->proto) != (ip_ver == 6 ? OPENVPN_ETH_P_IPV6 : OPENVPN_ETH_P_IPV4)) + eh = (const struct openvpn_ethhdr *)BPTR(buf); + + /* start by assuming this is a standard Eth fram */ + proto = eh->proto; + offset = sizeof(struct openvpn_ethhdr); + + /* if this is a 802.1q frame, parse the header using the according + * format + */ + if (proto == htons(OPENVPN_ETH_P_8021Q)) + { + const struct openvpn_8021qhdr *evh; + if (BLEN(buf) < (sizeof(struct openvpn_ethhdr) + + sizeof(struct openvpn_iphdr))) + { + return false; + } + + evh = (const struct openvpn_8021qhdr *)BPTR(buf); + + proto = evh->proto; + offset = sizeof(struct openvpn_8021qhdr); + } + + if (ntohs(proto) != (ip_ver == 6 ? OPENVPN_ETH_P_IPV6 : OPENVPN_ETH_P_IPV4)) { return false; } - offset = sizeof(struct openvpn_ethhdr); } else { return false; } - ih = (const struct openvpn_iphdr *) (BPTR(buf) + offset); + ih = (const struct openvpn_iphdr *)(BPTR(buf) + offset); /* IP version is stored in the same bits for IPv4 or IPv6 header */ if (OPENVPN_IPH_GET_VER(ih->version_len) == ip_ver) From patchwork Wed Oct 9 03:34:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Quartulli X-Patchwork-Id: 855 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director10.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id +KELKNXwnV0nEgAAIUCqbw for ; Wed, 09 Oct 2019 10:38:13 -0400 Received: from proxy18.mail.ord1d.rsapps.net ([172.30.191.6]) by director10.mail.ord1d.rsapps.net with LMTP id oExuJ9XwnV30CwAApN4f7A ; Wed, 09 Oct 2019 10:38:13 -0400 Received: from smtp32.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy18.mail.ord1d.rsapps.net with LMTP id 4D43J9XwnV3VbgAATCaURg ; Wed, 09 Oct 2019 10:38:13 -0400 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp32.gate.ord1d.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dmarc=none (p=nil; dis=none) header.from=unstable.cc X-Suspicious-Flag: YES X-Classification-ID: 6b8d8de2-eaa2-11e9-bb4c-52540099eaf5-1-1 Received: from [216.105.38.7] ([216.105.38.7:49572] helo=lists.sourceforge.net) by smtp32.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 33/87-21661-4D0FD9D5; Wed, 09 Oct 2019 10:38:12 -0400 Received: from [127.0.0.1] (helo=sfs-ml-2.v29.lw.sourceforge.com) by sfs-ml-2.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1iID5q-0004Vd-GL; Wed, 09 Oct 2019 14:37:34 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1iID5p-0004VQ-Cc for openvpn-devel@lists.sourceforge.net; Wed, 09 Oct 2019 14:37:33 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=tNyXxXmwe+NUViAWYE4dtMkb/KOJlIYzvzJEzthQ1ek=; b=kI492xZyvblAJVbtOrzxZtRb1I nu81e+D8F4wJGSY+e5H9FdwSKmAoRvm728X/crqbWE/pwlTnwKnWMN0wzcMjBM00YmgpD8dWUgZLQ 5VvDyxeDHNLW2zKFdA2vMMype8HInOozpFnbC9W3GlKrQ6vdOFBmvp/XcbcT2HQZ7tmw=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=tNyXxXmwe+NUViAWYE4dtMkb/KOJlIYzvzJEzthQ1ek=; b=ZE2+/Ut0lemS0epzSbchdu5D6v DOJTiEcRfWkQSQsq8AA66Xz9/FxIKMJwDXLcHBWQOXG2mfF9qm3lmrw/BJkuSbT72ewBBxIpOotKy JNa7KzL6aT4vpuZUnZ41sQc78i1TgASGoyZIrkHMizy5ahqn4q1L5/UPmOiuqskbfB8c=; Received: from [5.148.176.60] (helo=s2.neomailbox.net) by sfi-mx-3.v28.lw.sourceforge.com with esmtps (TLSv1.2:DHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1iID5m-003zZ4-0j for openvpn-devel@lists.sourceforge.net; Wed, 09 Oct 2019 14:37:33 +0000 From: Antonio Quartulli To: openvpn-devel@lists.sourceforge.net Date: Wed, 9 Oct 2019 16:34:19 +0200 Message-Id: <20191009143422.9419-7-a@unstable.cc> In-Reply-To: <20191009143422.9419-1-a@unstable.cc> References: <20191009143422.9419-1-a@unstable.cc> MIME-Version: 1.0 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. 0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [URIs: unstable.cc] -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [5.148.176.60 listed in list.dnswl.org] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches SPF record 1.0 RDNS_NONE Delivered to internal network by a host with no rDNS -0.4 AWL AWL: Adjusted score from AWL reputation of From: address X-Headers-End: 1iID5m-003zZ4-0j Subject: [Openvpn-devel] [PATCH 6/9] VLAN: implement support for forwarding only pre-tagged VLAN packets X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Antonio Quartulli Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox By building on top of the VLAN basic support, allow the user to configure the server in VLAN_TAGGED-only mode. This way, only packets that reach the TAP interface with an 802.1Q header are considered for forwarding - untagged packets are all dropped. A VLAN-tagged packet is then treated like any other packet by the OpenVPN routing engine, with the exception of being allowed to reach only clients configured with the same VID. The logic applies to all server-to-client and client-to-client traffic. Signed-off-by: Fabian Knittel Signed-off-by: Antonio Quartulli Acked-by: Gert Doering --- src/openvpn/multi.c | 16 +++- src/openvpn/options.c | 24 +++++ src/openvpn/options.h | 1 + src/openvpn/vlan.c | 210 ++++++++++++++++++++++++++++++++++++++++++ src/openvpn/vlan.h | 4 + 5 files changed, 252 insertions(+), 3 deletions(-) diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c index e733ca9a..d594dd25 100644 --- a/src/openvpn/multi.c +++ b/src/openvpn/multi.c @@ -2763,6 +2763,7 @@ multi_process_incoming_tun(struct multi_context *m, const unsigned int mpp_flags unsigned int mroute_flags; struct mroute_addr src, dest; const int dev_type = TUNNEL_TYPE(m->top.c1.tuntap); + int16_t vid = 0; #ifdef ENABLE_PF struct mroute_addr esrc, *e1, *e2; @@ -2787,6 +2788,15 @@ multi_process_incoming_tun(struct multi_context *m, const unsigned int mpp_flags return true; } + if (dev_type == DEV_TYPE_TAP && m->top.options.vlan_tagging) + { + vid = vlan_decapsulate(&m->top, &m->top.c2.buf); + if (vid < 0) + { + return false; + } + } + /* * Route an incoming tun/tap packet to * the appropriate multi_instance object. @@ -2800,7 +2810,7 @@ multi_process_incoming_tun(struct multi_context *m, const unsigned int mpp_flags NULL, #endif NULL, - 0, + vid, &m->top.c2.buf, dev_type); @@ -2813,9 +2823,9 @@ multi_process_incoming_tun(struct multi_context *m, const unsigned int mpp_flags { /* for now, treat multicast as broadcast */ #ifdef ENABLE_PF - multi_bcast(m, &m->top.c2.buf, NULL, e2, 0); + multi_bcast(m, &m->top.c2.buf, NULL, e2, vid); #else - multi_bcast(m, &m->top.c2.buf, NULL, NULL, 0); + multi_bcast(m, &m->top.c2.buf, NULL, NULL, vid); #endif } else diff --git a/src/openvpn/options.c b/src/openvpn/options.c index caba6494..5be6a6a8 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -406,6 +406,7 @@ static const char usage_message[] = " to its initialization function.\n" #endif "--vlan-tagging : Enable 802.1Q-based VLAN tagging.\n" + "--vlan-accept tagged|untagged : Set VLAN tagging mode.\n" "--vlan-pvid v : Sets the Port VLAN Identifier. Defaults to 1.\n" #if P2MP #if P2MP_SERVER @@ -1234,6 +1235,8 @@ print_vlan_accept(enum vlan_acceptable_frames mode) { switch (mode) { + case VLAN_ONLY_TAGGED: + return "tagged"; case VLAN_ONLY_UNTAGGED_OR_PRIORITY: return "untagged"; } @@ -2381,6 +2384,10 @@ options_postprocess_verify_ce(const struct options *options, const struct connec } if (!options->vlan_tagging) { + if (options->vlan_accept != defaults.vlan_accept) + { + msg(M_USAGE, "--vlan-accept requires --vlan-tagging"); + } if (options->vlan_pvid != defaults.vlan_pvid) { msg(M_USAGE, "--vlan-pvid requires --vlan-tagging"); @@ -8400,6 +8407,23 @@ add_option(struct options *options, VERIFY_PERMISSION(OPT_P_GENERAL); options->vlan_tagging = true; } + else if (streq(p[0], "vlan-accept") && p[1] && !p[2]) + { + VERIFY_PERMISSION(OPT_P_GENERAL); + if (streq(p[1], "tagged")) + { + options->vlan_accept = VLAN_ONLY_TAGGED; + } + else if (streq(p[1], "untagged")) + { + options->vlan_accept = VLAN_ONLY_UNTAGGED_OR_PRIORITY; + } + else + { + msg(msglevel, "--vlan-accept must be 'tagged', 'untagged'"); + goto err; + } + } else if (streq(p[0], "vlan-pvid") && p[1] && !p[2]) { VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_INSTANCE); diff --git a/src/openvpn/options.h b/src/openvpn/options.h index 3f5c5465..3447b7e2 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -171,6 +171,7 @@ struct remote_list enum vlan_acceptable_frames { + VLAN_ONLY_TAGGED, VLAN_ONLY_UNTAGGED_OR_PRIORITY, }; diff --git a/src/openvpn/vlan.c b/src/openvpn/vlan.c index 8e987277..88c90574 100644 --- a/src/openvpn/vlan.c +++ b/src/openvpn/vlan.c @@ -48,6 +48,211 @@ vlanhdr_get_vid(const struct openvpn_8021qhdr *hdr) return ntohs(hdr->pcp_cfi_vid & OPENVPN_8021Q_MASK_VID); } +/* + * Set the VLAN Identifier (VID) in an IEEE 802.1Q header. + * + * @param hdr Pointer to the Ethernet header with IEEE 802.1Q tagging. + * @param vid The VID to set (in host byte order). + */ +static void +vlanhdr_set_vid(struct openvpn_8021qhdr *hdr, const uint16_t vid) +{ + hdr->pcp_cfi_vid = (hdr->pcp_cfi_vid & ~OPENVPN_8021Q_MASK_VID) + | (htons(vid) & OPENVPN_8021Q_MASK_VID); +} + +/* + * vlan_decapsulate - remove 802.1q header and return VID + * + * For vlan_accept == VLAN_ONLY_UNTAGGED_OR_PRIORITY: + * Only untagged frames and frames that are priority-tagged (VID == 0) are + * accepted. (This means that VLAN-tagged frames are dropped.) For frames + * that aren't dropped, the global vlan_pvid is returned as VID. + * + * For vlan_accept == VLAN_ONLY_TAGGED: + * If a frame is VLAN-tagged the tagging is removed and the embedded VID is + * returned. Any included priority information is lost. + * If a frame isn't VLAN-tagged, the frame is dropped. + * + * @param c The global context. + * @param buf The ethernet frame. + * @return Returns -1 if the frame is dropped or the VID if it is accepted. + */ +int16_t +vlan_decapsulate(const struct context *c, struct buffer *buf) +{ + const struct openvpn_8021qhdr *vlanhdr; + struct openvpn_ethhdr *ethhdr; + uint16_t vid; + + /* assume untagged frame */ + if (BLEN(buf) < sizeof(*ethhdr)) + { + goto drop; + } + + ethhdr = (struct openvpn_ethhdr *)BPTR(buf); + if (ethhdr->proto != htons(OPENVPN_ETH_P_8021Q)) + { + /* reject untagged frame */ + if (c->options.vlan_accept == VLAN_ONLY_TAGGED) + { + msg(D_VLAN_DEBUG, + "dropping frame without vlan-tag (proto/len 0x%04x)", + ntohs(ethhdr->proto)); + goto drop; + } + + /* untagged frame is accepted and associated with the global VID */ + msg(D_VLAN_DEBUG, + "assuming pvid for frame without vlan-tag, pvid: %u (proto/len 0x%04x)", + c->options.vlan_pvid, ntohs(ethhdr->proto)); + + return c->options.vlan_pvid; + } + + /* tagged frame */ + if (BLEN(buf) < sizeof(*vlanhdr)) + { + goto drop; + } + + vlanhdr = (const struct openvpn_8021qhdr *)BPTR(buf); + vid = vlanhdr_get_vid(vlanhdr); + + switch (c->options.vlan_accept) + { + case VLAN_ONLY_UNTAGGED_OR_PRIORITY: + /* VLAN-tagged frame: drop packet */ + if (vid != 0) + { + msg(D_VLAN_DEBUG, "dropping frame with vlan-tag, vid: %u (proto/len 0x%04x)", + vid, ntohs(vlanhdr->proto)); + goto drop; + } + + /* vid == 0 means prio-tagged packet: don't drop and fall-through */ + case VLAN_ONLY_TAGGED: + /* tagged frame can be accepted: extract vid and strip encapsulation */ + + /* in case of prio-tagged frame (vid == 0), assume the sender + * knows what he is doing and forward the packet as it is, so to + * keep the priority information intact. + */ + if (vid == 0) + { + /* return the global VID for priority-tagged frames */ + return c->options.vlan_pvid; + } + + /* here we have a proper VLAN tagged frame: perform decapsulation + * and return embedded VID + */ + msg(D_VLAN_DEBUG, + "removing vlan-tag from frame: vid: %u, wrapped proto/len: 0x%04x", + vid, ntohs(vlanhdr->proto)); + + /* save inner protocol to be restored later after decapsulation */ + uint16_t proto = vlanhdr->proto; + /* move the buffer head forward to adjust the headroom to a + * non-tagged frame + */ + buf_advance(buf, SIZE_ETH_TO_8021Q_HDR); + /* move the content of the 802.1q header to the new head, so that + * src/dst addresses are copied over + */ + ethhdr = memmove(BPTR(buf), vlanhdr, sizeof(*ethhdr)); + /* restore the inner protocol value */ + ethhdr->proto = proto; + + return vid; + } + +drop: + buf->len = 0; + return -1; +} + +/* + * vlan_encapsulate - add 802.1q header and set the context related VID + * + * Assumes vlan_accept == VLAN_ONLY_TAGGED + * + * @param c The current context. + * @param buf The ethernet frame to encapsulate. + */ +void +vlan_encapsulate(const struct context *c, struct buffer *buf) +{ + const struct openvpn_ethhdr *ethhdr; + struct openvpn_8021qhdr *vlanhdr; + + if (BLEN(buf) < sizeof(*ethhdr)) + { + goto drop; + } + + ethhdr = (const struct openvpn_ethhdr *)BPTR(buf); + if (ethhdr->proto == htons(OPENVPN_ETH_P_8021Q)) + { + /* Priority-tagged frame. (VLAN-tagged frames have been dropped before + * getting to this point) + */ + + /* Frame too small for header type? */ + if (BLEN(buf) < sizeof(*vlanhdr)) + { + goto drop; + } + + vlanhdr = (struct openvpn_8021qhdr *)BPTR(buf); + + /* sanity check: ensure this packet is really just prio-tagged */ + uint16_t vid = vlanhdr_get_vid(vlanhdr); + if (vid != 0) + { + goto drop; + } + } + else + { + /* Untagged frame. */ + + /* Not enough head room for VLAN tag? */ + if (buf_reverse_capacity(buf) < SIZE_ETH_TO_8021Q_HDR) + { + goto drop; + } + + vlanhdr = (struct openvpn_8021qhdr *)buf_prepend(buf, + SIZE_ETH_TO_8021Q_HDR); + + /* Initialise VLAN/802.1q header. + * Move the Eth header so to keep dst/src addresses the same and then + * assign the other fields. + * + * Also, save the inner protocol first, so that it can be restored later + * after the memmove() + */ + uint16_t proto = ethhdr->proto; + memmove(vlanhdr, ethhdr, sizeof(*ethhdr)); + vlanhdr->tpid = htons(OPENVPN_ETH_P_8021Q); + vlanhdr->pcp_cfi_vid = 0; + vlanhdr->proto = proto; + } + + /* set the VID corresponding to the current context (client) */ + vlanhdr_set_vid(vlanhdr, c->options.vlan_pvid); + + msg(D_VLAN_DEBUG, "tagging frame: vid %u (wrapping proto/len: %04x)", + c->options.vlan_pvid, vlanhdr->proto); + return; + +drop: + /* Drop the frame. */ + buf->len = 0; +} + /* * vlan_is_tagged - check if a packet is VLAN-tagged * @@ -105,6 +310,11 @@ vlan_process_outgoing_tun(struct multi_context *m, struct multi_instance *mi) mi->context.c2.to_tun.len = 0; } } + else if (m->top.options.vlan_accept == VLAN_ONLY_TAGGED) + { + /* All packets on the port (the tap device) need to be VLAN-tagged. */ + vlan_encapsulate(&mi->context, &mi->context.c2.to_tun); + } } #endif /* P2MP_SERVER */ diff --git a/src/openvpn/vlan.h b/src/openvpn/vlan.h index 1ef68813..a67ad0e1 100644 --- a/src/openvpn/vlan.h +++ b/src/openvpn/vlan.h @@ -29,10 +29,14 @@ #include "buffer.h" #include "mroute.h" +#include "openvpn.h" struct multi_context; struct multi_instance; +int16_t +vlan_decapsulate(const struct context *c, struct buffer *buf); + bool vlan_is_tagged(const struct buffer *buf); From patchwork Wed Oct 9 03:34:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Quartulli X-Patchwork-Id: 854 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director8.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id WIWVANXwnV2ncAAAIUCqbw for ; Wed, 09 Oct 2019 10:38:13 -0400 Received: from proxy18.mail.ord1d.rsapps.net ([172.30.191.6]) by director8.mail.ord1d.rsapps.net with LMTP id QBBBANXwnV2bEgAAfY0hYg ; Wed, 09 Oct 2019 10:38:13 -0400 Received: from smtp23.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy18.mail.ord1d.rsapps.net with LMTP id QER3O9TwnV2GbgAATCaURg ; Wed, 09 Oct 2019 10:38:13 -0400 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp23.gate.ord1d.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dmarc=none (p=nil; dis=none) header.from=unstable.cc X-Suspicious-Flag: YES X-Classification-ID: 6b442102-eaa2-11e9-9d9a-525400bfb165-1-1 Received: from [216.105.38.7] ([216.105.38.7:59120] helo=lists.sourceforge.net) by smtp23.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id F8/00-12366-4D0FD9D5; Wed, 09 Oct 2019 10:38:12 -0400 Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1iID5r-0003Qm-B4; Wed, 09 Oct 2019 14:37:36 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1iID5p-0003Qd-KI for openvpn-devel@lists.sourceforge.net; Wed, 09 Oct 2019 14:37:33 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=LA4Pie6a/UB4lIs9UF+xM4+WTDGdkR3GDrr9Z4sDId0=; b=Tx7FeaTIWgmjOOIrqgKowoI4th sM8DoFfUPi9ENc0caHeN3jcKrneQTughSupDGGOGHmkxF3z6oUWOeAJ8l/+vv1TchuxsJcddMLJ4Y EBINzwWpwIuhjm8G4qLfPo1q1BpTDeQbCn9nZZ5QfbJLAvzReAp91IQ44fKXN+oH2Jgo=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=LA4Pie6a/UB4lIs9UF+xM4+WTDGdkR3GDrr9Z4sDId0=; b=dgQYXjhFOA8z0s3MYWHt+KDvX7 DMRikAAIY1o09/Y1Ey7BI1H98dkn+JiC6YVhXXzBP65RDrtdMe/eUzvRqbg70eUMX9ZT2uat8qdLh A1I8+jNRTnDq6/eWYJtwfIffTZldTPF+Hvq2C3TvBEMicyHiI9JU5nkgYTES3CZrZr3Q=; Received: from [5.148.176.60] (helo=s2.neomailbox.net) by sfi-mx-3.v28.lw.sourceforge.com with esmtps (TLSv1.2:DHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1iID5m-003zZ5-7d for openvpn-devel@lists.sourceforge.net; Wed, 09 Oct 2019 14:37:33 +0000 From: Antonio Quartulli To: openvpn-devel@lists.sourceforge.net Date: Wed, 9 Oct 2019 16:34:20 +0200 Message-Id: <20191009143422.9419-8-a@unstable.cc> In-Reply-To: <20191009143422.9419-1-a@unstable.cc> References: <20191009143422.9419-1-a@unstable.cc> MIME-Version: 1.0 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. 0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [URIs: unstable.cc] -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [5.148.176.60 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 1.0 RDNS_NONE Delivered to internal network by a host with no rDNS -0.4 AWL AWL: Adjusted score from AWL reputation of From: address X-Headers-End: 1iID5m-003zZ5-7d Subject: [Openvpn-devel] [PATCH 7/9] VLAN: allow forwarding tagged and untagged packets on the server TAP device X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Antonio Quartulli Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox This changes allows the user to configure the server TAP interface to forward both VLAN tagged and untagged packets (i.e. vlan_accept == VLAN_ALL). Untagged packets are marked with the VID configured in the server configuration file, while tagged packets will keep their header as it is. Forwarding is then performed following the standard rules, while ensuring that pakcets do not leave the VLAN they belong to. Signed-off-by: Fabian Knittel Signed-off-by: Antonio Quartulli Acked-by: Gert Doering --- src/openvpn/options.c | 12 +++++++++--- src/openvpn/options.h | 1 + src/openvpn/vlan.c | 17 +++++++++++++++++ 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 5be6a6a8..3bcb9063 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -406,7 +406,7 @@ static const char usage_message[] = " to its initialization function.\n" #endif "--vlan-tagging : Enable 802.1Q-based VLAN tagging.\n" - "--vlan-accept tagged|untagged : Set VLAN tagging mode.\n" + "--vlan-accept tagged|untagged|all : Set VLAN tagging mode. Default is 'all'.\n" "--vlan-pvid v : Sets the Port VLAN Identifier. Defaults to 1.\n" #if P2MP #if P2MP_SERVER @@ -853,7 +853,7 @@ init_options(struct options *o, const bool init_gc) o->route_method = ROUTE_METHOD_ADAPTIVE; o->block_outside_dns = false; #endif - o->vlan_accept = VLAN_ONLY_UNTAGGED_OR_PRIORITY; + o->vlan_accept = VLAN_ALL; o->vlan_pvid = 1; #if P2MP_SERVER o->real_hash_size = 256; @@ -1239,6 +1239,8 @@ print_vlan_accept(enum vlan_acceptable_frames mode) return "tagged"; case VLAN_ONLY_UNTAGGED_OR_PRIORITY: return "untagged"; + case VLAN_ALL: + return "all"; } return NULL; } @@ -8418,9 +8420,13 @@ add_option(struct options *options, { options->vlan_accept = VLAN_ONLY_UNTAGGED_OR_PRIORITY; } + else if (streq(p[1], "all")) + { + options->vlan_accept = VLAN_ALL; + } else { - msg(msglevel, "--vlan-accept must be 'tagged', 'untagged'"); + msg(msglevel, "--vlan-accept must be 'tagged', 'untagged' or 'all'"); goto err; } } diff --git a/src/openvpn/options.h b/src/openvpn/options.h index 3447b7e2..6f5e1f53 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -173,6 +173,7 @@ enum vlan_acceptable_frames { VLAN_ONLY_TAGGED, VLAN_ONLY_UNTAGGED_OR_PRIORITY, + VLAN_ALL, }; struct remote_host_store diff --git a/src/openvpn/vlan.c b/src/openvpn/vlan.c index 88c90574..a5885de2 100644 --- a/src/openvpn/vlan.c +++ b/src/openvpn/vlan.c @@ -74,6 +74,10 @@ vlanhdr_set_vid(struct openvpn_8021qhdr *hdr, const uint16_t vid) * returned. Any included priority information is lost. * If a frame isn't VLAN-tagged, the frame is dropped. * + * For vlan_accept == VLAN_ALL: + * Accepts both VLAN-tagged and untagged (or priority-tagged) frames and + * and handles them as described above. + * * @param c The global context. * @param buf The ethernet frame. * @return Returns -1 if the frame is dropped or the VID if it is accepted. @@ -133,6 +137,7 @@ vlan_decapsulate(const struct context *c, struct buffer *buf) /* vid == 0 means prio-tagged packet: don't drop and fall-through */ case VLAN_ONLY_TAGGED: + case VLAN_ALL: /* tagged frame can be accepted: extract vid and strip encapsulation */ /* in case of prio-tagged frame (vid == 0), assume the sender @@ -310,6 +315,18 @@ vlan_process_outgoing_tun(struct multi_context *m, struct multi_instance *mi) mi->context.c2.to_tun.len = 0; } } + else if (m->top.options.vlan_accept == VLAN_ALL) + { + /* Packets either need to be VLAN-tagged or not, depending on the + * packet's originating VID and the port's native VID (PVID). */ + + if (m->top.options.vlan_pvid != mi->context.options.vlan_pvid) + { + /* Packets need to be VLAN-tagged, because the packet's VID does not + * match the port's PVID. */ + vlan_encapsulate(&mi->context, &mi->context.c2.to_tun); + } + } else if (m->top.options.vlan_accept == VLAN_ONLY_TAGGED) { /* All packets on the port (the tap device) need to be VLAN-tagged. */ From patchwork Wed Oct 9 03:34:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Quartulli X-Patchwork-Id: 860 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director9.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id KHFkAgjxnV1qMQAAIUCqbw for ; Wed, 09 Oct 2019 10:39:04 -0400 Received: from proxy4.mail.ord1d.rsapps.net ([172.30.191.6]) by director9.mail.ord1d.rsapps.net with LMTP id QBILAgjxnV1EEAAAalYnBA ; Wed, 09 Oct 2019 10:39:04 -0400 Received: from smtp2.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy4.mail.ord1d.rsapps.net with LMTP id AH5iAQjxnV09cQAAiYrejw ; Wed, 09 Oct 2019 10:39:04 -0400 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp2.gate.ord1d.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dmarc=none (p=nil; dis=none) header.from=unstable.cc X-Suspicious-Flag: YES X-Classification-ID: 89fb5cd2-eaa2-11e9-ac60-5254004a0287-1-1 Received: from [216.105.38.7] ([216.105.38.7:59486] helo=lists.sourceforge.net) by smtp2.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 68/2D-21294-701FD9D5; Wed, 09 Oct 2019 10:39:03 -0400 Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1iID5u-0003Rn-Mi; Wed, 09 Oct 2019 14:37:38 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1iID5q-0003Qj-0J for openvpn-devel@lists.sourceforge.net; Wed, 09 Oct 2019 14:37:34 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=YyVV+j/DdoGa10LkUs8wlf9rGGNxff+RWdfyQNLiISc=; b=DQjlqPoMo8JtHuL3m6fE2brXSm xdHyP+j7Ui956xlekC5gpRAvoI/k2DBpmhXB+PSmgOUhMf7Qjq4VMczvsL69KrfBqLPPW6xMAxqCa aZkTLPBTfrihvh7D3eFKi7DZKpNQ3GciAo7teeMpwD5H+G2vU+9WSlX0lHAX+yJsW/aY=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=YyVV+j/DdoGa10LkUs8wlf9rGGNxff+RWdfyQNLiISc=; b=FF5+rX1ktZ7zoW2wD2rSo4D/l8 BGh305xCvJl+kTc56pv0ezHDp1MJSYJ5aJmjW6bk6c6WMMKHz0O8apOXUIVQwZD0lIaeyZlKvekwm 5xHZATqvTEVCF+P4x11CaxFmwR+W1SE3R6Y0anTwWwaMSTWJ/RLEVuZ85dbJQa4777PM=; Received: from s2.neomailbox.net ([5.148.176.60]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLSv1.2:DHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1iID5m-00BOM1-Ky for openvpn-devel@lists.sourceforge.net; Wed, 09 Oct 2019 14:37:33 +0000 From: Antonio Quartulli To: openvpn-devel@lists.sourceforge.net Date: Wed, 9 Oct 2019 16:34:21 +0200 Message-Id: <20191009143422.9419-9-a@unstable.cc> In-Reply-To: <20191009143422.9419-1-a@unstable.cc> References: <20191009143422.9419-1-a@unstable.cc> MIME-Version: 1.0 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. 0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [URIs: unstable.cc] -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [5.148.176.60 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.2 AWL AWL: Adjusted score from AWL reputation of From: address X-Headers-End: 1iID5m-00BOM1-Ky Subject: [Openvpn-devel] [PATCH 8/9] VLAN: add documentation to manpage X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Antonio Quartulli Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox This patch adds documentation for all the VLAN related knobs. Signed-off-by: Fabian Knittel Signed-off-by: Antonio Quartulli --- doc/openvpn.8 | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 98 insertions(+), 1 deletion(-) diff --git a/doc/openvpn.8 b/doc/openvpn.8 index 4185ffed..4b08ac18 100644 --- a/doc/openvpn.8 +++ b/doc/openvpn.8 @@ -3440,7 +3440,8 @@ without needing to restart the server. The following options are legal in a client\-specific context: -.B \-\-push, \-\-push\-reset, \-\-push\-remove, \-\-iroute, \-\-ifconfig\-push, +.B \-\-push, \-\-push\-reset, \-\-push\-remove, \-\-iroute, +.B \-\-ifconfig\-push, \-\-vlan\-pvid and .B \-\-config. .\"********************************************************* @@ -3860,6 +3861,102 @@ connection is torn down. Not implemented on Windows. .\"********************************************************* +.TP +.B \-\-vlan\-tagging +Server-only option. Turns the OpenVPN server instance into a switch that +understands VLAN\-tagging, based on IEEE 802.1Q. + +The server TAP device and each of the connecting clients is seen as a port of the +switch. All client ports are in untagged mode and the server TAP device is +VLAN-tagged, untagged or accepts both, depending on the +.B \-\-vlan\-accept setting. + +Ethernet frames with a prepended 802.1Q tag are called "tagged". If the VLAN +Identifier (VID) field in such a tag is non-zero, the frame is called +"VLAN\-tagged". If the VID is zero, but the Priority Control Point (PCP) field +is non\-zero, the frame is called "prio\-tagged". If there is no 802.1Q tag, the +frame is "untagged". + +Using the +.B \-\-vlan\-pvid v +option once per client (see \-\-client\-config\-dir), each port can be associated +with a certain VID. Packets +can only be forwarded between ports having the same VID. Therefore, clients +with differing VIDs are completely separated from one\-another, even if +.B \-\-client\-to\-client +is activated. + +The packet filtering takes place in the OpenVPN server. Clients do not +need to have any VLAN tagging configuration. + +The +.B \-\-vlan\-tagging +option is off by default. While turned off, OpenVPN +accepts any Ethernet frame and does not perform any special processing +for VLAN\-tagged packets. + +The option can only be activated in +.B \-\-dev tap mode. + +.\"********************************************************* +.TP +.B \-\-vlan\-accept all | tagged | untagged +Configure the VLAN tagging policy for the server TAP device. The following modes +are available: + +.B tagged +\-\- Admit only VLAN\-tagged frames. +Only VLAN\-tagged packets are accepted, while untagged or priority\-tagged +packets are dropped when entering the server TAP device. + +.br +.B untagged +\-\- Admit only untagged and prio\-tagged frames. +.br +VLAN\-tagged packets are not accepted, while untagged or priority\-tagged +packets entering the server TAP device are tagged with the value configured +for the global +.B \-\-vlan\-pvid +setting. +.br +.B all +(default) \-\- Admit all frames. +.br +All packets are admitted and then treated like untagged or tagged mode +respectively. + +(Note: Some vendors refer to switch ports running in +.B tagged +mode as "trunk ports" and switch ports running in +.B untagged +mode as "access ports".) + +Packets forwarded from clients to the server are VLAN\-tagged +with the originating client's PVID, unless the VID matches the +global \-\-vlan\-pvid, in which case the tag is removed. + +If no PVID is configured for a given client (see \-\-vlan\-pvid) packets +are tagged with 1 by default. +.\"********************************************************* +.TP +.B \-\-vlan\-pvid v +Specifies which VLAN identifier a "port" is associated with. Only valid when +\fB\-\-vlan\-tagging\fR is speficied. + +In the client context, the setting specifies which VLAN ID a client is +associated with. In the global context, the VLAN ID of the server TAP device is set. +The latter only makes sense for +.B \-\-vlan\-accept untagged +and +.B \-\-vlan\-accept all +modes. + +Valid values for +.B v +go from 1 through to 4094. Defaults to 1. + +In some switch implementations, the PVID is also referred to as "Native VLAN". +.\"********************************************************* .SS Client Mode Use client mode when connecting to an OpenVPN server which has From patchwork Wed Oct 9 03:34:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Quartulli X-Patchwork-Id: 859 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director9.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id qHU4BOnwnV3yUAAAIUCqbw for ; Wed, 09 Oct 2019 10:38:33 -0400 Received: from proxy12.mail.ord1d.rsapps.net ([172.30.191.6]) by director9.mail.ord1d.rsapps.net with LMTP id 0D3fA+nwnV3KDwAAalYnBA ; Wed, 09 Oct 2019 10:38:33 -0400 Received: from smtp37.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy12.mail.ord1d.rsapps.net with LMTP id 2CedA+nwnV3sZwAA7PHxkg ; Wed, 09 Oct 2019 10:38:33 -0400 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp37.gate.ord1d.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dmarc=none (p=nil; dis=none) header.from=unstable.cc X-Suspicious-Flag: YES X-Classification-ID: 77853550-eaa2-11e9-a7fd-525400a11cf3-1-1 Received: from [216.105.38.7] ([216.105.38.7:44052] helo=lists.sourceforge.net) by smtp37.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 04/64-09610-8E0FD9D5; Wed, 09 Oct 2019 10:38:32 -0400 Received: from [127.0.0.1] (helo=sfs-ml-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1iID5t-0001tV-VI; Wed, 09 Oct 2019 14:37:37 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1iID5p-0001s2-UM for openvpn-devel@lists.sourceforge.net; Wed, 09 Oct 2019 14:37:33 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=SXLCP4866x72R1l+SIssg8CrkJFRe6hjVId8m4SESUE=; b=JrYAbIlIH1W7o/hJ2iN8TRo+H1 d+uygdJBCBHpJqskQa46QM8P3yWncxjfj0+rOkDFC3AqB+fhN4szY9ZbAbSSP4/nEScs56T5tk3kt vVYtNN8kElJvtGeDojBU/dClQY7DPav5MkA3a2Bda4cbUsKnS5OjkdKKhTGh/K1w5c+M=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=SXLCP4866x72R1l+SIssg8CrkJFRe6hjVId8m4SESUE=; b=Q3bCv2p5LcJGxZqak/WwUi4o3r wtrsZ7ET3G1fpxB7JZcVR4LKPpvC5Nl6vx3TRsgqY7sdWq3enLrzl0IaEL/wicrFqUD8a5kx2U/fO IKU5ljydilMAKm8Hy9RS+xYd388iO2AdM00djlGUne2gKSVH8AQ3+JgJrd9Me2h6653U=; Received: from s2.neomailbox.net ([5.148.176.60]) by sfi-mx-4.v28.lw.sourceforge.com with esmtps (TLSv1.2:DHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1iID5m-00425j-13 for openvpn-devel@lists.sourceforge.net; Wed, 09 Oct 2019 14:37:33 +0000 From: Antonio Quartulli To: openvpn-devel@lists.sourceforge.net Date: Wed, 9 Oct 2019 16:34:22 +0200 Message-Id: <20191009143422.9419-10-a@unstable.cc> In-Reply-To: <20191009143422.9419-1-a@unstable.cc> References: <20191009143422.9419-1-a@unstable.cc> MIME-Version: 1.0 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. 0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [URIs: makefile.am] -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [5.148.176.60 listed in list.dnswl.org] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches SPF record 0.2 AWL AWL: Adjusted score from AWL reputation of From: address X-Headers-End: 1iID5m-00425j-13 Subject: [Openvpn-devel] [PATCH 9/9] VLAN: allow user to avoid compiling VLAN handling code X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Antonio Quartulli Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox To handle VLANs a whole lot of code has been introduced. However, there are a number of users who may not need this feature and would rather preserve disk space. Implement a configure knob (--disable-vlan-tagging) to conditionally take the entire VLAN code out. This patch introduces the conditional by keeping all the logic/ifdefs in vlan.h and avoid polluting the rest of code (exception made for options.h/c which is really troublesome to deal with). Signed-off-by: Antonio Quartulli --- configure.ac | 12 ++++++ src/openvpn/Makefile.am | 5 ++- src/openvpn/mroute.c | 6 +-- src/openvpn/mroute.h | 2 + src/openvpn/multi.c | 10 ++--- src/openvpn/options.c | 15 ++++++++ src/openvpn/options.h | 2 + src/openvpn/vlan.h | 83 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 126 insertions(+), 9 deletions(-) diff --git a/configure.ac b/configure.ac index c7fd7a84..66d58b91 100644 --- a/configure.ac +++ b/configure.ac @@ -256,6 +256,13 @@ AC_ARG_ENABLE( [enable_async_push="no"] ) +AC_ARG_ENABLE( + [vlan-tagging], + [AS_HELP_STRING([--disable-vlan-tagging], [Disble support for 802.1Q-based VLAN tagging])], + , + [enable_vlan="yes"] +) + AC_ARG_WITH( [special-build], [AS_HELP_STRING([--with-special-build=STRING], [specify special build string])], @@ -1321,6 +1328,10 @@ if test "${enable_async_push}" = "yes"; then ) fi +if test "${enable_vlan}" = "yes"; then + AC_DEFINE(ENABLE_VLAN_TAGGING, 1, [Enable 802.1Q-based VLAN tagging/untagging]) +fi + CONFIGURE_DEFINES="`set | grep '^enable_.*=' ; set | grep '^with_.*='`" AC_DEFINE_UNQUOTED([CONFIGURE_DEFINES], ["`echo ${CONFIGURE_DEFINES}`"], [Configuration settings]) @@ -1349,6 +1360,7 @@ AC_SUBST([OPTIONAL_PKCS11_HELPER_LIBS]) AC_SUBST([PLUGIN_AUTH_PAM_CFLAGS]) AC_SUBST([PLUGIN_AUTH_PAM_LIBS]) +AM_CONDITIONAL([VLAN_TAGGING], [test "${enable_vlan}" = "yes"]) AM_CONDITIONAL([WIN32], [test "${WIN32}" = "yes"]) AM_CONDITIONAL([GIT_CHECKOUT], [test "${GIT_CHECKOUT}" = "yes"]) AM_CONDITIONAL([ENABLE_PLUGIN_AUTH_PAM], [test "${enable_plugin_auth_pam}" = "yes"]) diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am index bc976019..64df1df4 100644 --- a/src/openvpn/Makefile.am +++ b/src/openvpn/Makefile.am @@ -123,7 +123,7 @@ openvpn_SOURCES = \ syshead.h \ tls_crypt.c tls_crypt.h \ tun.c tun.h \ - vlan.c vlan.h \ + vlan.h \ win32.h win32.c \ cryptoapi.h cryptoapi.c openvpn_LDADD = \ @@ -136,6 +136,9 @@ openvpn_LDADD = \ $(OPTIONAL_SELINUX_LIBS) \ $(OPTIONAL_SYSTEMD_LIBS) \ $(OPTIONAL_DL_LIBS) +if VLAN_TAGGING +openvpn_SOURCES += vlan.c +endif if WIN32 openvpn_SOURCES += openvpn_win32_resources.rc block_dns.c block_dns.h openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm -lfwpuclnt -lrpcrt4 -lncrypt diff --git a/src/openvpn/mroute.c b/src/openvpn/mroute.c index bdb1b0c0..d6dc8d22 100644 --- a/src/openvpn/mroute.c +++ b/src/openvpn/mroute.c @@ -35,6 +35,7 @@ #include "proto.h" #include "error.h" #include "socket.h" +#include "vlan.h" #include "memdbg.h" @@ -256,8 +257,7 @@ mroute_copy_ether_to_addr(struct mroute_addr *maddr, maddr->netbits = 0; maddr->len = OPENVPN_ETH_ALEN; memcpy(maddr->ether.addr, ether_addr, OPENVPN_ETH_ALEN); - maddr->len += sizeof(vid); - maddr->ether.vid = vid; + vlan_maddr_copy_vid(maddr, vid); } unsigned int @@ -467,7 +467,7 @@ mroute_addr_print_ex(const struct mroute_addr *ma, case MR_ADDR_ETHER: buf_printf(&out, "%s", format_hex_ex(ma->ether.addr, sizeof(ma->ether.addr), 0, 1, ":", gc)); - buf_printf(&out, "@%hu", ma->ether.vid); + vlan_maddr_print_vid(&out, ma); break; case MR_ADDR_IPV4: diff --git a/src/openvpn/mroute.h b/src/openvpn/mroute.h index 113aa8c5..4bbcd61d 100644 --- a/src/openvpn/mroute.h +++ b/src/openvpn/mroute.h @@ -84,7 +84,9 @@ struct mroute_addr { uint8_t raw_addr[MR_MAX_ADDR_LEN]; /* actual address */ struct { uint8_t addr[OPENVPN_ETH_ALEN]; +#ifdef ENABLE_VLAN_TAGGING uint16_t vid; +#endif } ether; struct { in_addr_t addr; /* _network order_ IPv4 address */ diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c index d594dd25..13e81315 100644 --- a/src/openvpn/multi.c +++ b/src/openvpn/multi.c @@ -2260,11 +2260,12 @@ multi_bcast(struct multi_context *m, } } #endif /* ifdef ENABLE_PF */ - if (vid != 0 && vid != mi->context.options.vlan_pvid) + if (!vlan_match_pvid(vid, &mi->context.options)) { continue; } multi_add_mbuf(m, mi, mb); + } } @@ -2648,8 +2649,7 @@ multi_process_incoming_link(struct multi_context *m, struct multi_instance *inst struct mroute_addr edest; mroute_addr_reset(&edest); #endif - - if (m->top.options.vlan_tagging) + if (vlan_is_enabled(&m->top.options)) { if (vlan_is_tagged(&c->c2.to_tun)) { @@ -2659,7 +2659,7 @@ multi_process_incoming_link(struct multi_context *m, struct multi_instance *inst } else { - vid = c->options.vlan_pvid; + vid = vlan_get_pvid(&c->options); } } /* extract packet source and dest addresses */ @@ -2788,7 +2788,7 @@ multi_process_incoming_tun(struct multi_context *m, const unsigned int mpp_flags return true; } - if (dev_type == DEV_TYPE_TAP && m->top.options.vlan_tagging) + if (dev_type == DEV_TYPE_TAP && vlan_is_enabled(&m->top.options)) { vid = vlan_decapsulate(&m->top, &m->top.c2.buf); if (vid < 0) diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 3bcb9063..2c41eeda 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -405,9 +405,11 @@ static const char usage_message[] = "--plugin m [str]: Load plug-in module m passing str as an argument\n" " to its initialization function.\n" #endif +#ifdef ENABLE_VLAN_TAGGING "--vlan-tagging : Enable 802.1Q-based VLAN tagging.\n" "--vlan-accept tagged|untagged|all : Set VLAN tagging mode. Default is 'all'.\n" "--vlan-pvid v : Sets the Port VLAN Identifier. Defaults to 1.\n" +#endif /* ifdef ENABLE_VLAN_TAGGING */ #if P2MP #if P2MP_SERVER "\n" @@ -853,8 +855,10 @@ init_options(struct options *o, const bool init_gc) o->route_method = ROUTE_METHOD_ADAPTIVE; o->block_outside_dns = false; #endif +#ifdef ENABLE_VLAN_TAGGING o->vlan_accept = VLAN_ALL; o->vlan_pvid = 1; +#endif /* ifdef ENABLE_VLAN_TAGGING */ #if P2MP_SERVER o->real_hash_size = 256; o->virtual_hash_size = 256; @@ -1230,6 +1234,7 @@ dhcp_option_address_parse(const char *name, const char *parm, in_addr_t *array, #endif /* if defined(_WIN32) || defined(TARGET_ANDROID) */ +#ifdef ENABLE_VLAN_TAGGING static const char * print_vlan_accept(enum vlan_acceptable_frames mode) { @@ -1244,6 +1249,7 @@ print_vlan_accept(enum vlan_acceptable_frames mode) } return NULL; } +#endif /* ifdef ENABLE_VLAN_TAGGING */ #if P2MP @@ -1314,9 +1320,11 @@ show_p2mp_parms(const struct options *o) SHOW_STR(port_share_host); SHOW_STR(port_share_port); #endif +#ifdef ENABLE_VLAN_TAGGING SHOW_BOOL(vlan_tagging); msg(D_SHOW_PARMS, " vlan_accept = %s", print_vlan_accept (o->vlan_accept)); SHOW_INT(vlan_pvid); +#endif /* ifdef ENABLE_VLAN_TAGGING */ #endif /* P2MP_SERVER */ SHOW_BOOL(client); @@ -2380,6 +2388,7 @@ options_postprocess_verify_ce(const struct options *options, const struct connec } } +#ifdef ENABLE_VLAN_TAGGING if (options->vlan_tagging && dev != DEV_TYPE_TAP) { msg(M_USAGE, "--vlan-tagging must be used with --dev tap"); @@ -2395,6 +2404,8 @@ options_postprocess_verify_ce(const struct options *options, const struct connec msg(M_USAGE, "--vlan-pvid requires --vlan-tagging"); } } +#endif /* ifdef ENABLE_VLAN_TAGGING */ + } else { @@ -2485,10 +2496,12 @@ options_postprocess_verify_ce(const struct options *options, const struct connec msg(M_USAGE, "--stale-routes-check requires --mode server"); } +#ifdef ENABLE_VLAN_TAGGING if (options->vlan_tagging) { msg(M_USAGE, "--vlan-tagging requires --mode server"); } +#endif /* ifdef ENABLE_VLAN_TAGGING */ } #endif /* P2MP_SERVER */ @@ -8404,6 +8417,7 @@ add_option(struct options *options, VERIFY_PERMISSION(OPT_P_GENERAL); options->allow_recursive_routing = true; } +#ifdef ENABLE_VLAN_TAGGING else if (streq(p[0], "vlan-tagging") && !p[1]) { VERIFY_PERMISSION(OPT_P_GENERAL); @@ -8443,6 +8457,7 @@ add_option(struct options *options, goto err; } } +#endif /* ifdef ENABLE_VLAN_TAGGING */ else { int i; diff --git a/src/openvpn/options.h b/src/openvpn/options.h index 6f5e1f53..0192bfb0 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -639,9 +639,11 @@ struct options int keying_material_exporter_length; #endif +#ifdef ENABLE_VLAN_TAGGING bool vlan_tagging; enum vlan_acceptable_frames vlan_accept; uint16_t vlan_pvid; +#endif /* ifdef ENABLE_VLAN_TAGGING */ struct pull_filter_list *pull_filter_list; diff --git a/src/openvpn/vlan.h b/src/openvpn/vlan.h index a67ad0e1..44b3193b 100644 --- a/src/openvpn/vlan.h +++ b/src/openvpn/vlan.h @@ -29,11 +29,14 @@ #include "buffer.h" #include "mroute.h" +#include "options.h" #include "openvpn.h" struct multi_context; struct multi_instance; +#ifdef ENABLE_VLAN_TAGGING + int16_t vlan_decapsulate(const struct context *c, struct buffer *buf); @@ -43,6 +46,86 @@ vlan_is_tagged(const struct buffer *buf); void vlan_process_outgoing_tun(struct multi_context *m, struct multi_instance *mi); +static inline bool +vlan_is_enabled(struct options *opt) +{ + return opt->vlan_tagging; +} + +static inline bool +vlan_match_pvid(uint16_t vid, struct options *opt) +{ + return vid != 0 && vid == opt->vlan_pvid; +} + +static inline uint16_t +vlan_get_pvid(struct options *opt) +{ + return opt->vlan_pvid; +} + +static inline void +vlan_maddr_copy_vid(struct mroute_addr *maddr, uint16_t vid) +{ + maddr->len += sizeof(vid); + maddr->ether.vid = vid; +} + +static inline void +vlan_maddr_print_vid(struct buffer *out, const struct mroute_addr *maddr) +{ + buf_printf(out, "@%hu", maddr->ether.vid); +} + +#else + +static inline int16_t +vlan_decapsulate(const struct context *c, struct buffer *buf) +{ + return 1; +} + +static inline bool +vlan_tagged_drop(const struct buffer *buf) +{ + return false; +} + +static inline void +vlan_process_outgoing_tun(struct multi_context *m, struct multi_instance *mi) +{ +} + +static inline bool +vlan_is_enabled(struct options *opt) +{ + return false; +} + +static inline bool +vlan_match_pvid(uint16_t vid, struct options *opt) +{ + return true; +} + +static inline uint16_t +vlan_get_pvid(struct options *opt) +{ + return 0; +} + +static inline void +vlan_maddr_copy_vid(struct mroute_addr *maddr, uint16_t vid) +{ +} + +static inline void +vlan_maddr_print_vid(struct buffer *out, const struct mroute_addr *maddr) +{ +} + +#endif + #endif /* P2MP_SERVER */ #endif /* VLAN_H */