From patchwork Fri Jan 14 06:14:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Quartulli X-Patchwork-Id: 2222 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director13.mail.ord1d.rsapps.net ([172.31.255.6]) by backend41.mail.ord1d.rsapps.net with LMTP id p2Q3KRCw4WGSEQAAqwncew (envelope-from ) for ; Fri, 14 Jan 2022 12:17:04 -0500 Received: from proxy14.mail.iad3b.rsapps.net ([172.31.255.6]) by director13.mail.ord1d.rsapps.net with LMTP id EIyuNxCw4WERFgAA91zNiA (envelope-from ) for ; Fri, 14 Jan 2022 12:17:04 -0500 Received: from smtp40.gate.iad3b ([172.31.255.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy14.mail.iad3b.rsapps.net with LMTPS id mOX2MBCw4WEGBwAA+7ETDg (envelope-from ) for ; Fri, 14 Jan 2022 12:17:04 -0500 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.iad3b.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: ca9fff8e-755d-11ec-a3c4-5254000cc6d4-1-1 Received: from [216.105.38.7] ([216.105.38.7:60638] helo=lists.sourceforge.net) by smtp40.gate.iad3b.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id F9/CD-29055-F00B1E16; Fri, 14 Jan 2022 12:17:04 -0500 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.94.2) (envelope-from ) id 1n8QAH-0001FM-C8; Fri, 14 Jan 2022 17:15:01 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1n8QAG-0001F3-9r for openvpn-devel@lists.sourceforge.net; Fri, 14 Jan 2022 17:15:00 +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=ARODdRTFJy1eqLFJZKM9r4oPoMimFS0+X5bXnqbSeSw=; b=Q9TnYKY+wq1DGA8xUWnElxJHVC T7pxJj38MckWlC/qCTirN0cTc8HdFdVW/Ey1pbziGl6Ii8vZb1omyP4tWFGEr98u2ZkSy6Ww6wNM9 nuSBScO4mEskd8SQwiWHvPwuEghaYWsEdwL3Lmlz8Qm8kAwJxPz/BcZCJmoZk9og1KJw=; 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=ARODdRTFJy1eqLFJZKM9r4oPoMimFS0+X5bXnqbSeSw=; b=kCQbiQxdMAutvvOYeQyASfPUgX qMxyi+T16oqXgcpQ3U0IC5eHKIk6NPG61tU1icDgJQFcO53oOLGVh6oPvDEO7InZXN21lhdrN8Uox YWxw3+jGNCAOqcDNC1Tv7jkMlQ+mFmJxvDwFjmL0V6Dmia3wvOu7hb8PS+YM85Xs3TPM=; Received: from s2.neomailbox.net ([5.148.176.60]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLSv1.2:DHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.3) id 1n8QA8-00074c-Ak for openvpn-devel@lists.sourceforge.net; Fri, 14 Jan 2022 17:14:58 +0000 From: Antonio Quartulli To: openvpn-devel@lists.sourceforge.net Date: Fri, 14 Jan 2022 18:14:42 +0100 Message-Id: <20220114171446.26446-4-a@unstable.cc> In-Reply-To: <20220114171446.26446-1-a@unstable.cc> References: <20220114171446.26446-1-a@unstable.cc> MIME-Version: 1.0 X-Spam-Report: Spam detection software, running on the system "util-spamd-1.v13.lw.sourceforge.com", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: These two new methods can be used to create and delete a tun or an ovpn-dco interface via networking API. Implementations for SITNL and iproute2 are provided Signed-off-by: Arne Schwabe Signed-off-by: Antonio Quartulli --- src/openvpn/networking.h | 26 ++++++++++ src/openvpn/networking_iproute2.c | 34 ++++++++++++ src/ope [...] Content analysis details: (0.0 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record X-Headers-End: 1n8QA8-00074c-Ak Subject: [Openvpn-devel] [RFC v2 3/7] networking: implement net_iface_new and net_iface_del APIs 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 These two new methods can be used to create and delete a tun or an ovpn-dco interface via networking API. Implementations for SITNL and iproute2 are provided Signed-off-by: Arne Schwabe Signed-off-by: Antonio Quartulli --- src/openvpn/networking.h | 26 ++++++++++ src/openvpn/networking_iproute2.c | 34 ++++++++++++ src/openvpn/networking_sitnl.c | 60 ++++++++++++++++++++++ tests/unit_tests/openvpn/test_networking.c | 22 +++++++- 4 files changed, 141 insertions(+), 1 deletion(-) diff --git a/src/openvpn/networking.h b/src/openvpn/networking.h index 2f0ee160..a21d38f4 100644 --- a/src/openvpn/networking.h +++ b/src/openvpn/networking.h @@ -35,6 +35,12 @@ typedef void *openvpn_net_ctx_t; typedef void *openvpn_net_iface_t; #endif /* ifdef ENABLE_SITNL */ +enum iface_type { + IFACE_DUMMY, + IFACE_TUN, + IFACE_OVPN_DCO, +}; + /* Only the iproute2 backend implements these functions, * the rest can rely on these stubs */ @@ -87,6 +93,26 @@ void net_ctx_reset(openvpn_net_ctx_t *ctx); */ void net_ctx_free(openvpn_net_ctx_t *ctx); +/** + * Add a new interface + * + * @param ctx the implementation specific context + * @param iface interface to create + * @param type interface type (see enum iface_type declaration) + * @return int 0 on success, negative error code on error + */ +int net_iface_new(openvpn_net_ctx_t *ctx, const openvpn_net_iface_t *iface, + enum iface_type type); + +/** + * Remove an interface + * + * @param ctx the implementation specific context + * @param iface interface to delete + * @return int 0 on success, negative error code on error + */ +int net_iface_del(openvpn_net_ctx_t *ctx, const openvpn_net_iface_t *iface); + /** * Bring interface up or down. * diff --git a/src/openvpn/networking_iproute2.c b/src/openvpn/networking_iproute2.c index 67b8894b..f8bd6618 100644 --- a/src/openvpn/networking_iproute2.c +++ b/src/openvpn/networking_iproute2.c @@ -38,6 +38,12 @@ #include #include +static const char *iface_type_str[] = { + [IFACE_DUMMY] = "dummy", + [IFACE_TUN] = "tun", + [IFACE_OVPN_DCO] = "ovpn-dco", +}; + int net_ctx_init(struct context *c, openvpn_net_ctx_t *ctx) { @@ -63,6 +69,34 @@ net_ctx_free(openvpn_net_ctx_t *ctx) gc_free(&ctx->gc); } +int +net_iface_new(openvpn_net_ctx_t *ctx, const char *iface, enum iface_type type) +{ + struct argv argv = argv_new(); + + argv_printf(&argv, "%s link add %s type %s", iproute_path, iface, + iface_type_str[type]); + argv_msg(M_INFO, &argv); + openvpn_execve_check(&argv, ctx->es, S_FATAL, "Linux ip link add failed"); + + argv_free(&argv); + + return 0; +} + +int +net_iface_del(openvpn_net_ctx_t *ctx, const char *iface) +{ + struct argv argv = argv_new(); + + argv_printf(&argv, "%s link del %s", iproute_path, iface); + openvpn_execve_check(&argv, ctx->es, S_FATAL, "Linux ip link del failed"); + + argv_free(&argv); + + return 0; +} + int net_iface_up(openvpn_net_ctx_t *ctx, const char *iface, bool up) { diff --git a/src/openvpn/networking_sitnl.c b/src/openvpn/networking_sitnl.c index e0003f5c..550a0904 100644 --- a/src/openvpn/networking_sitnl.c +++ b/src/openvpn/networking_sitnl.c @@ -595,6 +595,13 @@ net_route_v6_best_gw(openvpn_net_ctx_t *ctx, const struct in6_addr *dst, } #ifdef ENABLE_SITNL + +static const char *iface_type_str[] = { + [IFACE_DUMMY] = "dummy", + [IFACE_TUN] = "tun", + [IFACE_OVPN_DCO] = "ovpn-dco", +}; + int net_route_v4_best_gw(openvpn_net_ctx_t *ctx, const in_addr_t *dst, in_addr_t *best_gw, char *best_iface) @@ -1312,6 +1319,59 @@ net_route_v6_del(openvpn_net_ctx_t *ctx, const struct in6_addr *dst, table, metric); } + +int +net_iface_new(openvpn_net_ctx_t *ctx, const char *iface, enum iface_type type) +{ + struct sitnl_link_req req = { }; + struct rtattr *tail = NULL; + int ret = -1; + + ASSERT(iface); + + req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.i)); + req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL ; + req.n.nlmsg_type = RTM_NEWLINK; + + SITNL_ADDATTR(&req.n, sizeof(req), IFLA_IFNAME, iface, strlen(iface) + 1); + + tail = NLMSG_TAIL(&req.n); + SITNL_ADDATTR(&req.n, sizeof(req), IFLA_LINKINFO, NULL, 0); + SITNL_ADDATTR(&req.n, sizeof(req), IFLA_INFO_KIND, iface_type_str[type], + strlen(iface_type_str[type]) + 1); + tail->rta_len = (uint8_t *)NLMSG_TAIL(&req.n) - (uint8_t *)tail; + + req.i.ifi_family = AF_PACKET; + req.i.ifi_change = 0xFFFFFFFF; + + msg(D_ROUTE, "%s: add %s type %s", __func__, iface, iface_type_str[type]); + + ret = sitnl_send(&req.n, 0, 0, NULL, NULL); +err: + return ret; +} + +int +net_iface_del(openvpn_net_ctx_t *ctx, const char *iface) +{ + struct sitnl_link_req req = { }; + int ifindex = if_nametoindex(iface); + + if (!ifindex) + return errno; + + req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.i)); + req.n.nlmsg_flags = NLM_F_REQUEST; + req.n.nlmsg_type = RTM_DELLINK; + + req.i.ifi_family = AF_PACKET; + req.i.ifi_index = ifindex; + + msg(D_ROUTE, "%s: delete %s", __func__, iface); + + return sitnl_send(&req.n, 0, 0, NULL, NULL); +} + #endif /* !ENABLE_SITNL */ #endif /* TARGET_LINUX */ diff --git a/tests/unit_tests/openvpn/test_networking.c b/tests/unit_tests/openvpn/test_networking.c index 9e9744f4..27b487bd 100644 --- a/tests/unit_tests/openvpn/test_networking.c +++ b/tests/unit_tests/openvpn/test_networking.c @@ -13,6 +13,20 @@ net__iface_up(bool up) return net_iface_up(NULL, iface, up); } +static int +net__iface_new(const char *name, enum iface_type type, char *type_str) +{ + printf("CMD: ip link add %s type %s\n", name, type_str); + return net_iface_new(NULL, name, type); +} + +static int +net__iface_del(const char *name) +{ + printf("CMD: ip link del %s\n", name); + return net_iface_del(NULL, name); +} + static int net__iface_mtu_set(int mtu) { @@ -191,7 +205,7 @@ net__route_v6_add_gw(const char *dst_str, int prefixlen, const char *gw_str, static void usage(char *name) { - printf("Usage: %s <0-7>\n", name); + printf("Usage: %s <0-9>\n", name); } int @@ -243,6 +257,12 @@ main(int argc, char *argv[]) case 7: return net__route_v6_add_gw("2001:cafe:babe::", 48, "2001::2", 600); + case 8: + return net__iface_new("dummy0815", IFACE_DUMMY, "dummy"); + + case 9: + return net__iface_del("dummy0815"); + default: printf("invalid test: %d\n", test); break;