diff options
author | Daniel Mack <github@zonque.org> | 2015-11-19 14:18:01 +0100 |
---|---|---|
committer | Daniel Mack <github@zonque.org> | 2015-11-19 14:18:01 +0100 |
commit | 265fb8052dc3ca334951a5693cdfd6fb968c94c7 (patch) | |
tree | 55d67a30d9562b38b2b2b22f731aca60440438f0 /src | |
parent | a0d8b7f79505af842c26a9ab3076b4615564f061 (diff) | |
parent | d7fa4380c898c6d3aa96e5920c7f24d1dfdf1fc7 (diff) |
Merge pull request #1958 from teg/networkd-fixes
nd-ndisc: don't fail if src address is unset
Diffstat (limited to 'src')
-rw-r--r-- | src/libsystemd-network/sd-ndisc.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index 3bb06f6892..713438f212 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -32,6 +32,7 @@ #include "in-addr-util.h" #include "list.h" #include "socket-util.h" +#include "string-util.h" #define NDISC_ROUTER_SOLICITATION_INTERVAL 4 * USEC_PER_SEC #define NDISC_MAX_ROUTER_SOLICITATIONS 3 @@ -484,6 +485,7 @@ static int ndisc_router_advertisment_recv(sd_event_source *s, int fd, uint32_t r int r, buflen = 0, pref, stateful; union sockaddr_union router = {}; socklen_t router_len = sizeof(router); + struct in6_addr *gw; unsigned lifetime; ssize_t len; @@ -503,13 +505,22 @@ static int ndisc_router_advertisment_recv(sd_event_source *s, int fd, uint32_t r if (len < 0) { log_ndisc(nd, "Could not receive message from ICMPv6 socket: %m"); return 0; - } else if (router_len != sizeof(router.in6) && router_len != 0) { + } else if (router_len == 0) + gw = NULL; /* only happens when running the test-suite over a socketpair */ + else if (router_len != sizeof(router.in6)) { log_ndisc(nd, "Received invalid source address size from ICMPv6 socket: %zu bytes", (size_t)router_len); return 0; - } + } else + gw = &router.in6.sin6_addr; + + if (gw && !in_addr_is_link_local(AF_INET6, (const union in_addr_union*) gw)) { + _cleanup_free_ char *addr = NULL; - if (!in_addr_is_link_local(AF_INET6, (const union in_addr_union*) &router.in6.sin6_addr)) + (void)in_addr_to_string(AF_INET6, (const union in_addr_union*) gw, &addr); + + log_ndisc(nd, "Received RA from non-link-local address %s. Ignoring.", strna(addr)); return 0; + } if (ra->nd_ra_type != ND_ROUTER_ADVERT) return 0; @@ -547,7 +558,7 @@ static int ndisc_router_advertisment_recv(sd_event_source *s, int fd, uint32_t r } if (nd->router_callback) - nd->router_callback(nd, stateful, router_len != 0 ? &router.in6.sin6_addr : NULL, lifetime, pref, nd->userdata); + nd->router_callback(nd, stateful, gw, lifetime, pref, nd->userdata); return 0; } |