aboutsummaryrefslogtreecommitdiff
path: root/src/openvpn/networking_sitnl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvpn/networking_sitnl.c')
-rw-r--r--src/openvpn/networking_sitnl.c63
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 */