aboutgitcodebugslistschat
diff options
context:
space:
mode:
-rw-r--r--ip.h9
-rw-r--r--netlink.c15
2 files changed, 23 insertions, 1 deletions
diff --git a/ip.h b/ip.h
index b9aedf6..b8d4a5b 100644
--- a/ip.h
+++ b/ip.h
@@ -24,6 +24,11 @@
#define IN4ADDR_ANY_INIT \
{ .s_addr = htonl_constant(INADDR_ANY) }
+#define IN4_IS_ADDR_LINKLOCAL(a) \
+ ((ntohl(((struct in_addr *)(a))->s_addr) >> 16) == 0xa9fe)
+#define IN4_IS_PREFIX_LINKLOCAL(a, len) \
+ ((len) >= 16 && IN4_IS_ADDR_LINKLOCAL(a))
+
#define L2_BUF_IP4_INIT(proto) \
{ \
.version = 4, \
@@ -40,6 +45,10 @@
#define L2_BUF_IP4_PSUM(proto) ((uint32_t)htons_constant(0x4500) + \
(uint32_t)htons(0xff00 | (proto)))
+
+#define IN6_IS_PREFIX_LINKLOCAL(a, len) \
+ ((len) >= 10 && IN6_IS_ADDR_LINKLOCAL(a))
+
#define L2_BUF_IP6_INIT(proto) \
{ \
.priority = 0, \
diff --git a/netlink.c b/netlink.c
index 0549237..89c0641 100644
--- a/netlink.c
+++ b/netlink.c
@@ -33,6 +33,7 @@
#include "util.h"
#include "passt.h"
#include "log.h"
+#include "ip.h"
#include "netlink.h"
/* Netlink expects a buffer of at least 8kiB or the system page size,
@@ -270,6 +271,7 @@ unsigned int nl_get_ext_if(int s, sa_family_t af)
seq = nl_send(s, &req, RTM_GETROUTE, NLM_F_DUMP, sizeof(req));
nl_foreach_oftype(nh, status, s, buf, seq, RTM_NEWROUTE) {
struct rtmsg *rtm = (struct rtmsg *)NLMSG_DATA(nh);
+ const void *dst = NULL;
unsigned thisifi = 0;
if (rtm->rtm_family != af)
@@ -284,12 +286,23 @@ unsigned int nl_get_ext_if(int s, sa_family_t af)
rtnh = (struct rtnexthop *)RTA_DATA(rta);
thisifi = rtnh->rtnh_ifindex;
+ } else if (rta->rta_type == RTA_DST) {
+ dst = RTA_DATA(rta);
}
}
if (!thisifi)
continue; /* No interface for this route */
+ /* Skip routes to link-local addresses */
+ if (af == AF_INET && dst &&
+ IN4_IS_PREFIX_LINKLOCAL(dst, rtm->rtm_dst_len))
+ continue;
+
+ if (af == AF_INET6 && dst &&
+ IN6_IS_PREFIX_LINKLOCAL(dst, rtm->rtm_dst_len))
+ continue;
+
if (rtm->rtm_dst_len == 0) {
/* Default route */
ndef++;
@@ -322,7 +335,7 @@ unsigned int nl_get_ext_if(int s, sa_family_t af)
}
if (!nany)
- info("No interfaces with %s routes", af_name(af));
+ info("No interfaces with usable %s routes", af_name(af));
return 0;
}