summaryrefslogtreecommitdiff
path: root/src/openvpn/networking_sitnl.c
diff options
context:
space:
mode:
authorBernhard Schmidt <berni@debian.org>2020-10-28 19:46:08 +0100
committerBernhard Schmidt <berni@debian.org>2020-10-28 19:46:08 +0100
commit8231554c9f1ba25cb4e698ad5cfb3a56b258610a (patch)
tree029108888123856ca13e34c612d4dd4845c2b6c3 /src/openvpn/networking_sitnl.c
parent5bac5f7608a14e0989e95db1a1da2e65d9322127 (diff)
parent76fee93e6fe89e5575bae2840b585d2f025b9050 (diff)
Merge tag 'debian/2.5.0-1' into buster-backports
openvpn Debian release 2.5.0-1
Diffstat (limited to 'src/openvpn/networking_sitnl.c')
-rw-r--r--src/openvpn/networking_sitnl.c44
1 files changed, 40 insertions, 4 deletions
diff --git a/src/openvpn/networking_sitnl.c b/src/openvpn/networking_sitnl.c
index 713a213..2bc70a5 100644
--- a/src/openvpn/networking_sitnl.c
+++ b/src/openvpn/networking_sitnl.c
@@ -345,6 +345,13 @@ sitnl_send(struct nlmsghdr *payload, pid_t peer, unsigned int groups,
* continue;
* }
*/
+
+ if (h->nlmsg_type == NLMSG_DONE)
+ {
+ ret = 0;
+ goto out;
+ }
+
if (h->nlmsg_type == NLMSG_ERROR)
{
err = (struct nlmsgerr *)NLMSG_DATA(h);
@@ -360,7 +367,11 @@ sitnl_send(struct nlmsghdr *payload, pid_t peer, unsigned int groups,
ret = 0;
if (cb)
{
- ret = cb(h, arg_cb);
+ int r = cb(h, arg_cb);
+ if (r <= 0)
+ {
+ ret = r;
+ }
}
}
else
@@ -375,8 +386,12 @@ sitnl_send(struct nlmsghdr *payload, pid_t peer, unsigned int groups,
if (cb)
{
- ret = cb(h, arg_cb);
- goto out;
+ int r = cb(h, arg_cb);
+ if (r <= 0)
+ {
+ ret = r;
+ goto out;
+ }
}
else
{
@@ -410,6 +425,7 @@ typedef struct {
int addr_size;
inet_address_t gw;
char iface[IFNAMSIZ];
+ bool default_only;
} route_res_t;
static int
@@ -421,6 +437,12 @@ sitnl_route_save(struct nlmsghdr *n, void *arg)
int len = n->nlmsg_len - NLMSG_LENGTH(sizeof(*r));
unsigned int ifindex = 0;
+ /* filter-out non-zero dst prefixes */
+ if (res->default_only && r->rtm_dst_len != 0)
+ {
+ return 1;
+ }
+
while (RTA_OK(rta, len))
{
switch (rta->rta_type)
@@ -477,11 +499,25 @@ sitnl_route_best_gw(sa_family_t af_family, const inet_address_t *dst,
{
case AF_INET:
res.addr_size = sizeof(in_addr_t);
- req.n.nlmsg_flags |= NLM_F_DUMP;
+ /*
+ * kernel can't return 0.0.0.0/8 host route, dump all
+ * the routes and filter for 0.0.0.0/0 in cb()
+ */
+ if (!dst || !dst->ipv4)
+ {
+ req.n.nlmsg_flags |= NLM_F_DUMP;
+ res.default_only = true;
+ }
+ else
+ {
+ req.r.rtm_dst_len = 32;
+ }
break;
case AF_INET6:
res.addr_size = sizeof(struct in6_addr);
+ /* kernel can return ::/128 host route */
+ req.r.rtm_dst_len = 128;
break;
default: