diff options
author | Antonio Quartulli | 2022-04-07 11:41:46 +0200 |
---|---|---|
committer | Gert Doering | 2022-04-08 12:09:43 +0200 |
commit | c838a9f98fa2d8b6d7b2658e8399bc9d19ec60e0 (patch) | |
tree | d6faecf7655484017430daaf3a460e5e5841997d /src/openvpn/networking_sitnl.c | |
parent | 545f6bdea30e04a09b118c4e1faf6523544fd935 (diff) | |
download | openvpn-c838a9f98fa2d8b6d7b2658e8399bc9d19ec60e0.zip openvpn-c838a9f98fa2d8b6d7b2658e8399bc9d19ec60e0.tar.gz |
networking: implement net_iface_new and net_iface_del APIs
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 <arne@rfc2549.org>
Signed-off-by: Antonio Quartulli <a@unstable.cc>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <20220407094146.7684-1-a@unstable.cc>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg24088.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
Diffstat (limited to 'src/openvpn/networking_sitnl.c')
-rw-r--r-- | src/openvpn/networking_sitnl.c | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/src/openvpn/networking_sitnl.c b/src/openvpn/networking_sitnl.c index 9b2f58d..98e0685 100644 --- a/src/openvpn/networking_sitnl.c +++ b/src/openvpn/networking_sitnl.c @@ -56,6 +56,18 @@ #define NLMSG_TAIL(nmsg) \ ((struct rtattr *)(((uint8_t *)(nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) +#define SITNL_NEST(_msg, _max_size, _attr) \ + ({ \ + struct rtattr *_nest = NLMSG_TAIL(_msg); \ + SITNL_ADDATTR(_msg, _max_size, _attr, NULL, 0); \ + _nest; \ + }) + +#define SITNL_NEST_END(_msg, _nest) \ + { \ + _nest->rta_len = (void *)NLMSG_TAIL(_msg) - (void *)_nest; \ + } + /** * Generic address data structure used to pass addresses and prefixes as * argument to AF family agnostic functions @@ -596,6 +608,7 @@ net_route_v6_best_gw(openvpn_net_ctx_t *ctx, const struct in6_addr *dst, } #ifdef ENABLE_SITNL + int net_route_v4_best_gw(openvpn_net_ctx_t *ctx, const in_addr_t *dst, in_addr_t *best_gw, char *best_iface) @@ -1313,6 +1326,56 @@ 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, const char *type, + void *arg) +{ + struct sitnl_link_req req = { }; + 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); + + struct rtattr *linkinfo = SITNL_NEST(&req.n, sizeof(req), IFLA_LINKINFO); + SITNL_ADDATTR(&req.n, sizeof(req), IFLA_INFO_KIND, type, strlen(type) + 1); + SITNL_NEST_END(&req.n, linkinfo); + + req.i.ifi_family = AF_PACKET; + + msg(D_ROUTE, "%s: add %s type %s", __func__, iface, 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 */ |