[Openvpn-devel,v3,-1/7] implement platform generic networking API

Message ID 20190514081159.12192-1-a@unstable.cc
State Accepted
Headers show
Series
  • [Openvpn-devel,v3,-1/7] implement platform generic networking API
Related show

Commit Message

Antonio Quartulli May 14, 2019, 8:11 a.m.
tun.c and route.c contain all the code used by openvpn
to manage the tun interface and the routing table on all
the supported platforms.

Across the years, this resulted in a longer functions
and series of ifdefs.

This patch introduces a new "networking API" which aims at
creating a simple abstraction between the tun/route logic
and the platform dependent code.

The is API expected to be implemented outside of tun.c/route.c
by using platform specific functionalities.

Signed-off-by: Antonio Quartulli <a@unstable.cc>
---
 src/openvpn/Makefile.am  |   1 +
 src/openvpn/networking.h | 278 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 279 insertions(+)
 create mode 100644 src/openvpn/networking.h

Comments

Gert Doering May 14, 2019, 8:18 a.m. | #1
Hi,

On Tue, May 14, 2019 at 10:11:59AM +0200, Antonio Quartulli wrote:
> +#ifdef ENABLE_SITNL
> +#include "networking_sitnl.h"
> +#elif ENABLE_IPROUTE
> +#include "networking_ip.h"
> +#else

NAK, this patch breaks compilation - there is no "networking_ip.h" in
our tree, and this patch isn't introducing it either.

If we need this together with 1/7 of the v3 series, maybe we really
need to make this into a joint "1/7 v4"... but every single patch needs
to compile (on mainstream platforms).

gert
Gert Doering May 14, 2019, 8:20 a.m. | #2
Hi,

On Tue, May 14, 2019 at 10:18:48AM +0200, Gert Doering wrote:
> On Tue, May 14, 2019 at 10:11:59AM +0200, Antonio Quartulli wrote:
> > +#ifdef ENABLE_SITNL
> > +#include "networking_sitnl.h"
> > +#elif ENABLE_IPROUTE
> > +#include "networking_ip.h"
> > +#else
> 
> NAK, this patch breaks compilation - there is no "networking_ip.h" in
> our tree, and this patch isn't introducing it either.

Oh well.  It doesn't break compilation, as networking.h is not yet
included anywhere.  And "1/7 v3" fixes the include.

So while this is a slightly confusing commit, it won't *break* anything
and I'll merge it ASAP.

Acked-By: gert@greenie.muc.de (Gert Doering)

gert
Gert Doering May 15, 2019, 7:08 p.m. | #3
Acked-by: Gert Doering <gert@greenie.muc.de>

This patch does not actually *do* anything - it just brings in a
new file (networking.h) with the new API.  The file wouldn't compile
because it references not-yet-existing other .h files, so the patch
is a bit confusing - but since the rest of the series has ACKs and
needs this prequel, here we go.

Your patch has been applied to the master branch.

Note: I think "networking.h" and "networking_iproute2.h" are very
long file names (and are hurting my sense for aesthetics) so I suggest
we rename those to "net.h" and "net_<method>.h" afterwards - not the
most elegant approach but I do not want to hold up the series any
longer.

Note2: when this is in, I want us to drop support for ifconfig/route
on Linux, and get rid of --enable-iproute2 (this would become the
fallback if --enable-sitnl is not set).  Two options are enough.


commit 3d26593736982852fcf277b541da38b4c3cc7fc8
Author: Antonio Quartulli
Date:   Tue May 14 10:11:59 2019 +0200

     implement platform generic networking API

     Signed-off-by: Antonio Quartulli <a@unstable.cc>
     Acked-by: Gert Doering <gert@greenie.muc.de>
     Message-Id: <20190514081159.12192-1-a@unstable.cc>
     URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg18458.html
     Signed-off-by: Gert Doering <gert@greenie.muc.de>


--
kind regards,

Gert Doering

Patch

diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am
index 197e62ba..8afc4146 100644
--- a/src/openvpn/Makefile.am
+++ b/src/openvpn/Makefile.am
@@ -80,6 +80,7 @@  openvpn_SOURCES = \
 	mtu.c mtu.h \
 	mudp.c mudp.h \
 	multi.c multi.h \
+	networking.h \
 	ntlm.c ntlm.h \
 	occ.c occ.h \
 	openssl_compat.h \
diff --git a/src/openvpn/networking.h b/src/openvpn/networking.h
new file mode 100644
index 00000000..716e61a5
--- /dev/null
+++ b/src/openvpn/networking.h
@@ -0,0 +1,278 @@ 
+/*
+ *  Generic interface to platform specific networking code
+ *
+ *  Copyright (C) 2016-2018 Antonio Quartulli <a@unstable.cc>
+ *
+ *  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 (see the file COPYING included with this
+ *  distribution); if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef NETWORKING_H_
+#define NETWORKING_H_
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#include "syshead.h"
+
+struct context;
+
+#ifdef ENABLE_SITNL
+#include "networking_sitnl.h"
+#elif ENABLE_IPROUTE
+#include "networking_ip.h"
+#else
+/* define mock types to ensure code builds on any platform */
+typedef void * openvpn_net_ctx_t;
+typedef void * openvpn_net_iface_t;
+
+static inline int
+net_ctx_init(struct context *c, openvpn_net_ctx_t *ctx)
+{
+    return 0;
+}
+#endif
+
+#if defined(ENABLE_SITNL) || defined(ENABLE_IPROUTE)
+
+/**
+ * Initialize the platform specific context object
+ *
+ * @param c         openvpn generic context
+ * @param ctx       the implementation specific context to initialize
+ *
+ * @return          0 on success, a negative error code otherwise
+ */
+int net_ctx_init(struct context *c, openvpn_net_ctx_t *ctx);
+
+/**
+ * Bring interface up or down.
+ *
+ * @param ctx       the implementation specific context
+ * @param iface     the interface to modify
+ * @param up        true if the interface has to be brought up, false otherwise
+ *
+ * @return          0 on success, a negative error code otherwise
+ */
+int net_iface_up(openvpn_net_ctx_t *ctx, const openvpn_net_iface_t *iface,
+                 bool up);
+
+/**
+ * Set the MTU for an interface
+ *
+ * @param ctx       the implementation specific context
+ * @param iface     the interface to modify
+ * @param mtru      the new MTU
+ *
+ * @return          0 on success, a negative error code otherwise
+ */
+int net_iface_mtu_set(openvpn_net_ctx_t *ctx,
+                      const openvpn_net_iface_t *iface, uint32_t mtu);
+
+/**
+ * Add an IPv4 address to an interface
+ *
+ * @param ctx       the implementation specific context
+ * @param iface     the interface where the address has to be added
+ * @param addr      the address to add
+ * @param prefixlen the prefix length of the network associated with the address
+ * @param broadcast the broadcast address to configure on the interface
+ *
+ * @return          0 on success, a negative error code otherwise
+ */
+int net_addr_v4_add(openvpn_net_ctx_t *ctx, const openvpn_net_iface_t *iface,
+                    const in_addr_t *addr, int prefixlen,
+                    const in_addr_t *broadcast);
+
+/**
+ * Add an IPv6 address to an interface
+ *
+ * @param ctx       the implementation specific context
+ * @param iface     the interface where the address has to be added
+ * @param addr      the address to add
+ * @param prefixlen the prefix length of the network associated with the address
+ *
+ * @return          0 on success, a negative error code otherwise
+ */
+
+int net_addr_v6_add(openvpn_net_ctx_t *ctx, const openvpn_net_iface_t *iface,
+                    const struct in6_addr *addr, int prefixlen);
+
+/**
+ * Remove an IPv4 from an interface
+ *
+ * @param ctx       the implementation specific context
+ * @param iface     the interface to remove the address from
+ * @param prefixlen the prefix length of the network associated with the address
+ *
+ * @return          0 on success, a negative error code otherwise
+ */
+int net_addr_v4_del(openvpn_net_ctx_t *ctx, const openvpn_net_iface_t *iface,
+                    const in_addr_t *addr, int prefixlen);
+
+/**
+ * Remove an IPv6 from an interface
+ *
+ * @param ctx       the implementation specific context
+ * @param iface     the interface to remove the address from
+ * @param prefixlen the prefix length of the network associated with the address
+ *
+ * @return          0 on success, a negative error code otherwise
+ */
+int net_addr_v6_del(openvpn_net_ctx_t *ctx, const openvpn_net_iface_t *iface,
+                    const struct in6_addr *addr, int prefixlen);
+
+/**
+ * Add a point-to-point IPv4 address to an interface
+ *
+ * @param ctx       the implementation specific context
+ * @param iface     the interface where the address has to be added
+ * @param local     the address to add
+ * @param remote    the associated p-t-p remote address
+ *
+ * @return          0 on success, a negative error code otherwise
+ */
+int net_addr_ptp_v4_add(openvpn_net_ctx_t *ctx,
+                        const openvpn_net_iface_t *iface,
+                        const in_addr_t *local, const in_addr_t *remote);
+
+/**
+ * Remove a point-to-point IPv4 address from an interface
+ *
+ * @param ctx       the implementation specific context
+ * @param iface     the interface to remove the address from
+ * @param local     the address to remove
+ * @param remote    the associated p-t-p remote address
+ *
+ * @return          0 on success, a negative error code otherwise
+ */
+int net_addr_ptp_v4_del(openvpn_net_ctx_t *ctx,
+                        const openvpn_net_iface_t *iface,
+                        const in_addr_t *local, const in_addr_t *remote);
+
+
+/**
+ * Add a route for an IPv4 address/network
+ *
+ * @param ctx       the implementation specific context
+ * @param dst       the destination of the route
+ * @param prefixlen the length of the prefix of the destination
+ * @param gw        the gateway for this route
+ * @param iface     the interface for this route (can be NULL)
+ * @param table     the table to add this route to (if 0, will be added to the
+ *                  main table)
+ * @param metric    the metric associated with the route
+ *
+ * @return          0 on success, a negative error code otherwise
+ */
+int net_route_v4_add(openvpn_net_ctx_t *ctx, const in_addr_t *dst,
+                     int prefixlen, const in_addr_t *gw,
+                     const openvpn_net_iface_t *iface, uint32_t table,
+                     int metric);
+
+/**
+ * Add a route for an IPv6 address/network
+ *
+ * @param ctx       the implementation specific context
+ * @param dst       the destination of the route
+ * @param prefixlen the length of the prefix of the destination
+ * @param gw        the gateway for this route
+ * @param iface     the interface for this route (can be NULL)
+ * @param table     the table to add this route to (if 0, will be added to the
+ *                  main table)
+ * @param metric    the metric associated with the route
+ *
+ * @return          0 on success, a negative error code otherwise
+ */
+int net_route_v6_add(openvpn_net_ctx_t *ctx, const struct in6_addr *dst,
+                     int prefixlen, const struct in6_addr *gw,
+                     const openvpn_net_iface_t *iface,
+                     uint32_t table, int metric);
+
+/**
+ * Delete a route for an IPv4 address/network
+ *
+ * @param ctx       the implementation specific context
+ * @param dst       the destination of the route
+ * @param prefixlen the length of the prefix of the destination
+ * @param gw        the gateway for this route
+ * @param iface     the interface for this route (can be NULL)
+ * @param table     the table to add this route to (if 0, will be added to the
+ *                  main table)
+ * @param metric    the metric associated with the route
+ *
+ * @return          0 on success, a negative error code otherwise
+ */
+int net_route_v4_del(openvpn_net_ctx_t *ctx, const in_addr_t *dst,
+                     int prefixlen, const in_addr_t *gw,
+                     const openvpn_net_iface_t *iface, uint32_t table,
+                     int metric);
+
+/**
+ * Delete a route for an IPv4 address/network
+ *
+ * @param ctx       the implementation specific context
+ * @param dst       the destination of the route
+ * @param prefixlen the length of the prefix of the destination
+ * @param gw        the gateway for this route
+ * @param iface     the interface for this route (can be NULL)
+ * @param table     the table to add this route to (if 0, will be added to the
+ *                  main table)
+ * @param metric    the metric associated with the route
+ *
+ * @return          0 on success, a negative error code otherwise
+ */
+int net_route_v6_del(openvpn_net_ctx_t *ctx, const struct in6_addr *dst,
+                     int prefixlen, const struct in6_addr *gw,
+                     const openvpn_net_iface_t *iface,
+                     uint32_t table, int metric);
+
+/**
+ * Retrieve the gateway and outgoing interface for the specified IPv4
+ * address/network
+ *
+ * @param ctx           the implementation specific context
+ * @param dst           The destination to lookup
+ * @param prefixlen     The length of the prefix of the destination
+ * @param best_gw       Location where the retrieved GW has to be stored
+ * @param best_iface    Location where the retrieved interface has to be stored
+ *
+ * @return              0 on success, a negative error code otherwise
+ */
+int net_route_v4_best_gw(openvpn_net_ctx_t *ctx, const in_addr_t *dst,
+                         int prefixlen, in_addr_t *best_gw,
+                         openvpn_net_iface_t *best_iface);
+
+/**
+ * Retrieve the gateway and outgoing interface for the specified IPv6
+ * address/network
+ *
+ * @param ctx           the implementation specific context
+ * @param dst           The destination to lookup
+ * @param prefixlen     The length of the prefix of the destination
+ * @param best_gw       Location where the retrieved GW has to be stored
+ * @param best_iface    Location where the retrieved interface has to be stored
+ *
+ * @return              0 on success, a negative error code otherwise
+ */
+int net_route_v6_best_gw(openvpn_net_ctx_t *ctx, const struct in6_addr *dst,
+                         int prefixlen, struct in6_addr *best_gw,
+                         openvpn_net_iface_t *best_iface);
+
+#endif /* ENABLE_SITNL || ENABLE_IPROUTE */
+
+#endif /* NETWORKING_H_ */