summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/config.c13
-rw-r--r--src/dhcpv6-ia.c13
-rw-r--r--src/dhcpv6.c36
-rw-r--r--src/dhcpv6.h2
-rw-r--r--src/ndp.c53
-rw-r--r--src/odhcpd.c41
-rw-r--r--src/odhcpd.h13
-rw-r--r--src/router.c31
8 files changed, 113 insertions, 89 deletions
diff --git a/src/config.c b/src/config.c
index 1276b6f..e6f2382 100644
--- a/src/config.c
+++ b/src/config.c
@@ -388,6 +388,8 @@ err:
int config_parse_interface(void *data, size_t len, const char *name, bool overwrite)
{
struct blob_attr *tb[IFACE_ATTR_MAX], *c;
+ bool get_addrs = false;
+
blobmsg_parse(iface_attrs, IFACE_ATTR_MAX, tb, data, len);
if (tb[IFACE_ATTR_INTERFACE])
@@ -409,7 +411,7 @@ int config_parse_interface(void *data, size_t len, const char *name, bool overwr
set_interface_defaults(iface);
list_add(&iface->head, &interfaces);
- overwrite = true;
+ get_addrs = overwrite = true;
}
const char *ifname = NULL;
@@ -439,6 +441,14 @@ int config_parse_interface(void *data, size_t len, const char *name, bool overwr
if ((iface->ifindex = if_nametoindex(iface->ifname)) <= 0)
goto err;
+ if (get_addrs) {
+ ssize_t len = odhcpd_get_interface_addresses(iface->ifindex,
+ true, &iface->ia_addr);
+
+ if (len > 0)
+ iface->ia_addr_len = len;
+ }
+
iface->inuse = true;
if ((c = tb[IFACE_ATTR_DYNAMICDHCP]))
@@ -823,7 +833,6 @@ void odhcpd_reload(void)
close_interface(i);
}
- ndp_handle_addr6_dump();
uci_unload(uci, dhcp);
uci_free_context(uci);
}
diff --git a/src/dhcpv6-ia.c b/src/dhcpv6-ia.c
index c2221d8..502373f 100644
--- a/src/dhcpv6-ia.c
+++ b/src/dhcpv6-ia.c
@@ -248,7 +248,7 @@ void dhcpv6_enum_ia_addrs(struct interface *iface, struct dhcpv6_assignment *c,
if (!valid_addr(&addrs[i], now))
continue;
- addr = addrs[i].addr;
+ addr = addrs[i].addr.in6;
pref = addrs[i].preferred;
valid = addrs[i].valid;
if (prefix == 128) {
@@ -444,7 +444,7 @@ static void apply_lease(struct interface *iface, struct dhcpv6_assignment *a, bo
size_t addrlen = (a->managed) ? (size_t)a->managed_size : iface->ia_addr_len;
for (size_t i = 0; i < addrlen; ++i) {
- struct in6_addr prefix = addrs[i].addr;
+ struct in6_addr prefix = addrs[i].addr.in6;
prefix.s6_addr32[1] |= htonl(a->assigned);
prefix.s6_addr32[2] = prefix.s6_addr32[3] = 0;
odhcpd_setup_route(&prefix, (a->managed_size) ? addrs[i].prefix : a->length,
@@ -661,11 +661,12 @@ void dhcpv6_ia_preupdate(struct interface *iface)
apply_lease(iface, c, false);
}
-void dhcpv6_ia_postupdate(struct interface *iface, time_t now)
+void dhcpv6_ia_postupdate(struct interface *iface)
{
if (iface->dhcpv6 != RELAYD_SERVER)
return;
+ time_t now = odhcpd_time();
int minprefix = -1;
for (size_t i = 0; i < iface->ia_addr_len; ++i) {
if (iface->ia_addr[i].preferred > (uint32_t)now &&
@@ -802,7 +803,7 @@ static size_t append_reply(uint8_t *buf, size_t buflen, uint16_t status,
.preferred = htonl(prefix_pref),
.valid = htonl(prefix_valid),
.prefix = (a->managed_size) ? addrs[i].prefix : a->length,
- .addr = addrs[i].addr
+ .addr = addrs[i].addr.in6,
};
p.addr.s6_addr32[1] |= htonl(a->assigned);
p.addr.s6_addr32[2] = p.addr.s6_addr32[3] = 0;
@@ -820,7 +821,7 @@ static size_t append_reply(uint8_t *buf, size_t buflen, uint16_t status,
struct dhcpv6_ia_addr n = {
.type = htons(DHCPV6_OPT_IA_ADDR),
.len = htons(sizeof(n) - 4),
- .addr = addrs[i].addr,
+ .addr = addrs[i].addr.in6,
.preferred = htonl(prefix_pref),
.valid = htonl(prefix_valid)
};
@@ -879,7 +880,7 @@ static size_t append_reply(uint8_t *buf, size_t buflen, uint16_t status,
if (!valid_addr(&addrs[i], now))
continue;
- struct in6_addr addr = addrs[i].addr;
+ struct in6_addr addr = addrs[i].addr.in6;
if (ia->type == htons(DHCPV6_OPT_IA_PD)) {
addr.s6_addr32[1] |= htonl(a->assigned);
addr.s6_addr32[2] = addr.s6_addr32[3] = 0;
diff --git a/src/dhcpv6.c b/src/dhcpv6.c
index 3128968..4ecb54a 100644
--- a/src/dhcpv6.c
+++ b/src/dhcpv6.c
@@ -90,9 +90,6 @@ int setup_dhcpv6_interface(struct interface *iface, bool enable)
if (iface->dhcpv6 == RELAYD_SERVER)
setsockopt(sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &server, sizeof(server));
- if (iface->dhcpv6 != RELAYD_RELAY || !iface->master)
- ndp_rqs_addr6_dump();
-
iface->dhcpv6_event.uloop.fd = sock;
iface->dhcpv6_event.handle_dgram = handle_dhcpv6;
odhcpd_register(&iface->dhcpv6_event);
@@ -336,7 +333,7 @@ static void handle_client_request(void *addr, void *data, size_t len,
if (IN6_IS_ADDR_UNSPECIFIED(&cerid.addr)) {
struct odhcpd_ipaddr *addrs;
- ssize_t len = odhcpd_get_interface_addresses(0, &addrs);
+ ssize_t len = odhcpd_get_interface_addresses(0, true, &addrs);
for (ssize_t i = 0; i < len; ++i)
if (IN6_IS_ADDR_UNSPECIFIED(&cerid.addr)
@@ -483,6 +480,26 @@ static void relay_server_response(uint8_t *data, size_t len)
odhcpd_send(iface->dhcpv6_event.uloop.fd, &target, &iov, 1, iface);
}
+static struct odhcpd_ipaddr *relay_link_address(struct interface *iface)
+{
+ struct odhcpd_ipaddr *addr = NULL;
+ time_t now = odhcpd_time();
+
+ for (size_t i = 0; i < iface->ia_addr_len; i++) {
+ if (iface->ia_addr[i].valid <= (uint32_t)now)
+ continue;
+
+ if (iface->ia_addr[i].preferred > (uint32_t)now) {
+ addr = &iface->ia_addr[i];
+ break;
+ }
+
+ if (!addr || (iface->ia_addr[i].valid > addr->valid))
+ addr = &iface->ia_addr[i];
+ }
+
+ return addr;
+}
// Relay client request (regular DHCPv6-relay)
static void relay_client_request(struct sockaddr_in6 *source,
@@ -522,18 +539,19 @@ static void relay_client_request(struct sockaddr_in6 *source,
memcpy(&hdr.interface_id_data, &ifindex, sizeof(ifindex));
// Detect public IP of slave interface to use as link-address
- struct odhcpd_ipaddr *ip = NULL;
- if (odhcpd_get_interface_addresses(iface->ifindex, &ip) < 1) {
+ struct odhcpd_ipaddr *ip = relay_link_address(iface);
+ if (!ip) {
// No suitable address! Is the slave not configured yet?
// Detect public IP of master interface and use it instead
// This is WRONG and probably violates the RFC. However
// otherwise we have a hen and egg problem because the
// slave-interface cannot be auto-configured.
- if (odhcpd_get_interface_addresses(master->ifindex, &ip) < 1)
+ ip = relay_link_address(master);
+ if (!ip)
return; // Could not obtain a suitable address
}
- memcpy(&hdr.link_address, &ip[0].addr, sizeof(hdr.link_address));
- free(ip);
+
+ memcpy(&hdr.link_address, &ip->addr.in6, sizeof(hdr.link_address));
struct sockaddr_in6 dhcpv6_servers = {AF_INET6,
htons(DHCPV6_SERVER_PORT), 0, ALL_DHCPV6_SERVERS, 0};
diff --git a/src/dhcpv6.h b/src/dhcpv6.h
index b38ae82..e58cb69 100644
--- a/src/dhcpv6.h
+++ b/src/dhcpv6.h
@@ -190,4 +190,4 @@ void dhcpv6_enum_ia_addrs(struct interface *iface, struct dhcpv6_assignment *c,
dhcpv6_binding_cb_handler_t func, void *arg);
void dhcpv6_write_statefile(void);
void dhcpv6_ia_preupdate(struct interface *iface);
-void dhcpv6_ia_postupdate(struct interface *iface, time_t now);
+void dhcpv6_ia_postupdate(struct interface *iface);
diff --git a/src/ndp.c b/src/ndp.c
index 8488fc5..94b7e96 100644
--- a/src/ndp.c
+++ b/src/ndp.c
@@ -48,7 +48,6 @@ static void handle_rtnl_event(struct odhcpd_event *ev);
static int cb_rtnl_valid(struct nl_msg *msg, void *arg);
static void catch_rtnl_err(struct odhcpd_event *e, int error);
-static int addr6_dump_rqs = 0;
static int ping_socket = -1;
static struct event_socket rtnl_event = {
.ev = {
@@ -150,11 +149,11 @@ static void dump_neigh_table(const bool proxy)
nlmsg_free(msg);
}
-static void dump_addr6_table(void)
+static void dump_addr_table(bool v6)
{
struct nl_msg *msg;
struct ifaddrmsg ifa = {
- .ifa_family = AF_INET6,
+ .ifa_family = v6 ? AF_INET6 : AF_INET,
};
msg = nlmsg_alloc_simple(RTM_GETADDR, NLM_F_REQUEST | NLM_F_DUMP);
@@ -168,20 +167,6 @@ static void dump_addr6_table(void)
nlmsg_free(msg);
}
-void ndp_handle_addr6_dump(void)
-{
- if (!addr6_dump_rqs)
- return;
-
- dump_addr6_table();
- addr6_dump_rqs = 0;
-}
-
-inline void ndp_rqs_addr6_dump(void)
-{
- addr6_dump_rqs++;
-}
-
int setup_ndp_interface(struct interface *iface, bool enable)
{
int ret = 0, procfd;
@@ -253,8 +238,6 @@ int setup_ndp_interface(struct interface *iface, bool enable)
dump_neigh_table(false);
else
dump_neigh = false;
-
- ndp_rqs_addr6_dump();
}
if (dump_neigh)
@@ -340,38 +323,18 @@ static void setup_route(struct in6_addr *addr, struct interface *iface, bool add
odhcpd_setup_route(addr, 128, iface, NULL, 1024, add);
}
-// compare prefixes
-static int prefixcmp(const void *va, const void *vb)
-{
- const struct odhcpd_ipaddr *a = va, *b = vb;
- uint32_t a_pref = IN6_IS_ADDR_ULA(&a->addr) ? 1 : a->preferred;
- uint32_t b_pref = IN6_IS_ADDR_ULA(&b->addr) ? 1 : b->preferred;
- return (a_pref < b_pref) ? 1 : (a_pref > b_pref) ? -1 : 0;
-}
-
// Check address update
-static void check_addr_updates(struct interface *iface)
+static void check_addr6_updates(struct interface *iface)
{
struct odhcpd_ipaddr *addr = NULL;
- time_t now = odhcpd_time();
- ssize_t len = odhcpd_get_interface_addresses(iface->ifindex, &addr);
+ ssize_t len = odhcpd_get_interface_addresses(iface->ifindex, true, &addr);
if (len < 0)
return;
- qsort(addr, len, sizeof(*addr), prefixcmp);
-
- for (int i = 0; i < len; ++i) {
- if (addr[i].preferred < UINT32_MAX - now)
- addr[i].preferred += now;
-
- if (addr[i].valid < UINT32_MAX - now)
- addr[i].valid += now;
- }
-
bool change = len != (ssize_t)iface->ia_addr_len;
for (ssize_t i = 0; !change && i < len; ++i)
- if (!IN6_ARE_ADDR_EQUAL(&addr[i].addr, &iface->ia_addr[i].addr) ||
+ if (!IN6_ARE_ADDR_EQUAL(&addr[i].addr.in6, &iface->ia_addr[i].addr.in6) ||
(addr[i].preferred > 0) != (iface->ia_addr[i].preferred > 0) ||
addr[i].valid < iface->ia_addr[i].valid ||
addr[i].preferred < iface->ia_addr[i].preferred)
@@ -385,7 +348,7 @@ static void check_addr_updates(struct interface *iface)
iface->ia_addr_len = len;
if (change)
- dhcpv6_ia_postupdate(iface, now);
+ dhcpv6_ia_postupdate(iface);
if (change) {
syslog(LOG_INFO, "Raising SIGUSR1 due to address change on %s", iface->ifname);
@@ -477,7 +440,7 @@ static int cb_rtnl_valid(struct nl_msg *msg, _unused void *arg)
syslog(LOG_DEBUG, "Netlink %s %s%%%s", true ? "newaddr" : "deladdr",
ipbuf, iface->ifname);
- check_addr_updates(iface);
+ check_addr6_updates(iface);
if (iface->ndp != RELAYD_RELAY)
break;
@@ -562,7 +525,7 @@ static void catch_rtnl_err(struct odhcpd_event *e, int error)
if (nl_socket_set_buffer_size(ev_sock->sock, ev_sock->sock_bufsize, 0))
goto err;
- dump_addr6_table();
+ dump_addr_table(true);
return;
err:
diff --git a/src/odhcpd.c b/src/odhcpd.c
index ee628a5..6f38d5c 100644
--- a/src/odhcpd.c
+++ b/src/odhcpd.c
@@ -222,6 +222,7 @@ ssize_t odhcpd_send(int socket, struct sockaddr_in6 *dest,
struct addr_info {
int ifindex;
+ int af;
struct odhcpd_ipaddr **addrs;
int pending;
ssize_t ret;
@@ -240,6 +241,7 @@ static int cb_valid_handler(struct nl_msg *msg, void *arg)
ifa = NLMSG_DATA(hdr);
if (ifa->ifa_scope != RT_SCOPE_UNIVERSE ||
+ (ctxt->af != ifa->ifa_family) ||
(ctxt->ifindex && ifa->ifa_index != (unsigned)ctxt->ifindex))
return NL_SKIP;
@@ -293,12 +295,21 @@ static int cb_error_handler(_unused struct sockaddr_nl *nla, struct nlmsgerr *er
return NL_STOP;
}
+// compare prefixes
+static int prefixcmp(const void *va, const void *vb)
+{
+ const struct odhcpd_ipaddr *a = va, *b = vb;
+ uint32_t a_pref = IN6_IS_ADDR_ULA(&a->addr.in6) ? 1 : a->preferred;
+ uint32_t b_pref = IN6_IS_ADDR_ULA(&b->addr.in6) ? 1 : b->preferred;
+ return (a_pref < b_pref) ? 1 : (a_pref > b_pref) ? -1 : 0;
+}
+
// Detect an IPV6-address currently assigned to the given interface
-ssize_t odhcpd_get_interface_addresses(int ifindex, struct odhcpd_ipaddr **addrs)
+ssize_t odhcpd_get_interface_addresses(int ifindex, bool v6, struct odhcpd_ipaddr **addrs)
{
struct nl_msg *msg;
struct ifaddrmsg ifa = {
- .ifa_family = AF_INET6,
+ .ifa_family = v6? AF_INET6: AF_INET,
.ifa_prefixlen = 0,
.ifa_flags = 0,
.ifa_scope = 0,
@@ -306,6 +317,7 @@ ssize_t odhcpd_get_interface_addresses(int ifindex, struct odhcpd_ipaddr **addrs
struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
struct addr_info ctxt = {
.ifindex = ifindex,
+ .af = v6? AF_INET6: AF_INET,
.addrs = addrs,
.ret = 0,
.pending = 1,
@@ -334,6 +346,23 @@ ssize_t odhcpd_get_interface_addresses(int ifindex, struct odhcpd_ipaddr **addrs
nl_recvmsgs(rtnl_socket, cb);
nlmsg_free(msg);
+
+ if (ctxt.ret <= 0)
+ goto out;
+
+ time_t now = odhcpd_time();
+ struct odhcpd_ipaddr *addr = *addrs;
+
+ qsort(addr, ctxt.ret, sizeof(*addr), prefixcmp);
+
+ for (ssize_t i = 0; i < ctxt.ret; ++i) {
+ if (addr[i].preferred < UINT32_MAX - now)
+ addr[i].preferred += now;
+
+ if (addr[i].valid < UINT32_MAX - now)
+ addr[i].valid += now;
+ }
+
out:
nl_cb_put(cb);
@@ -383,12 +412,12 @@ int odhcpd_get_interface_dns_addr(const struct interface *iface, struct in6_addr
iface->ia_addr[i].preferred < (uint32_t)now)
continue;
- if (IN6_IS_ADDR_ULA(&iface->ia_addr[i].addr)) {
- if (!IN6_IS_ADDR_ULA(&iface->ia_addr[m].addr)) {
+ if (IN6_IS_ADDR_ULA(&iface->ia_addr[i].addr.in6)) {
+ if (!IN6_IS_ADDR_ULA(&iface->ia_addr[m].addr.in6)) {
m = i;
continue;
}
- } else if (IN6_IS_ADDR_ULA(&iface->ia_addr[m].addr))
+ } else if (IN6_IS_ADDR_ULA(&iface->ia_addr[m].addr.in6))
continue;
if (iface->ia_addr[i].preferred > iface->ia_addr[m].preferred)
@@ -396,7 +425,7 @@ int odhcpd_get_interface_dns_addr(const struct interface *iface, struct in6_addr
}
if (m >= 0) {
- *addr = iface->ia_addr[m].addr;
+ *addr = iface->ia_addr[m].addr.in6;
return 0;
}
diff --git a/src/odhcpd.h b/src/odhcpd.h
index 8a196ea..28eb88e 100644
--- a/src/odhcpd.h
+++ b/src/odhcpd.h
@@ -68,10 +68,16 @@ struct odhcpd_event {
void (*recv_msgs)(struct odhcpd_event *e);
};
+union if_addr {
+ struct in_addr in;
+ struct in6_addr in6;
+};
struct odhcpd_ipaddr {
- struct in6_addr addr;
+ union if_addr addr;
uint8_t prefix;
+
+ /* ipv6 only */
uint8_t dprefix;
uint32_t preferred;
uint32_t valid;
@@ -203,7 +209,7 @@ struct nl_sock *odhcpd_create_nl_socket(int protocol);
ssize_t odhcpd_send(int socket, struct sockaddr_in6 *dest,
struct iovec *iov, size_t iov_len,
const struct interface *iface);
-ssize_t odhcpd_get_interface_addresses(int ifindex,
+ssize_t odhcpd_get_interface_addresses(int ifindex, bool v6,
struct odhcpd_ipaddr **addrs);
int odhcpd_get_interface_dns_addr(const struct interface *iface,
struct in6_addr *addr);
@@ -229,9 +235,6 @@ void odhcpd_bmemcpy(void *av, const void *bv, size_t bits);
int config_parse_interface(void *data, size_t len, const char *iname, bool overwrite);
-void ndp_handle_addr6_dump(void);
-void ndp_rqs_addr6_dump(void);
-
#ifdef WITH_UBUS
int init_ubus(void);
const char* ubus_get_ifname(const char *name);
diff --git a/src/router.c b/src/router.c
index 0463d68..19702a2 100644
--- a/src/router.c
+++ b/src/router.c
@@ -119,7 +119,6 @@ int setup_router_interface(struct interface *iface, bool enable)
} else if (iface->ra == RELAYD_SERVER && !iface->master) {
iface->timer_rs.cb = trigger_router_advert;
uloop_timeout_set(&iface->timer_rs, 1000);
- ndp_rqs_addr6_dump();
}
if (iface->ra == RELAYD_RELAY || (iface->ra == RELAYD_SERVER && !iface->master))
@@ -182,7 +181,9 @@ static bool parse_routes(struct odhcpd_ipaddr *n, ssize_t len)
char line[512], ifname[16];
bool found_default = false;
- struct odhcpd_ipaddr p = {IN6ADDR_ANY_INIT, 0, 0, 0, 0};
+ struct odhcpd_ipaddr p = { .addr.in6 = IN6ADDR_ANY_INIT, .prefix = 0,
+ .dprefix = 0, .preferred = 0, .valid = 0};
+
while (fgets(line, sizeof(line), fp_route)) {
uint32_t rflags;
if (sscanf(line, "00000000000000000000000000000000 00 "
@@ -191,15 +192,15 @@ static bool parse_routes(struct odhcpd_ipaddr *n, ssize_t len)
found_default = true;
} else if (sscanf(line, "%8" SCNx32 "%8" SCNx32 "%*8" SCNx32 "%*8" SCNx32 " %hhx %*s "
"%*s 00000000000000000000000000000000 %*s %*s %*s %" SCNx32 " lo",
- &p.addr.s6_addr32[0], &p.addr.s6_addr32[1], &p.prefix, &rflags) &&
+ &p.addr.in6.s6_addr32[0], &p.addr.in6.s6_addr32[1], &p.prefix, &rflags) &&
p.prefix > 0 && (rflags & RTF_NONEXTHOP) && (rflags & RTF_REJECT)) {
// Find source prefixes by scanning through unreachable-routes
- p.addr.s6_addr32[0] = htonl(p.addr.s6_addr32[0]);
- p.addr.s6_addr32[1] = htonl(p.addr.s6_addr32[1]);
+ p.addr.in6.s6_addr32[0] = htonl(p.addr.in6.s6_addr32[0]);
+ p.addr.in6.s6_addr32[1] = htonl(p.addr.in6.s6_addr32[1]);
for (ssize_t i = 0; i < len; ++i) {
if (n[i].prefix <= 64 && n[i].prefix >= p.prefix &&
- !odhcpd_bmemcmp(&p.addr, &n[i].addr, p.prefix)) {
+ !odhcpd_bmemcmp(&p.addr.in6, &n[i].addr.in6, p.prefix)) {
n[i].dprefix = p.prefix;
break;
}
@@ -353,7 +354,7 @@ static uint64_t send_router_advert(struct interface *iface, const struct in6_add
if (addr->prefix > 96 || addr->valid <= (uint32_t)now) {
char namebuf[INET6_ADDRSTRLEN];
- inet_ntop(AF_INET6, addr, namebuf, sizeof(namebuf));
+ inet_ntop(AF_INET6, &addr->addr.in6, namebuf, sizeof(namebuf));
syslog(LOG_INFO, "Address %s (prefix %d, valid %u) not suitable as RA prefix on %s",
namebuf, addr->prefix, addr->valid, iface->ifname);
continue;
@@ -363,7 +364,7 @@ static uint64_t send_router_advert(struct interface *iface, const struct in6_add
for (size_t i = 0; i < pfxs_cnt; ++i) {
if (addr->prefix == pfxs[i].nd_opt_pi_prefix_len &&
!odhcpd_bmemcmp(&pfxs[i].nd_opt_pi_prefix,
- &addr->addr, addr->prefix))
+ &addr->addr.in6, addr->prefix))
p = &pfxs[i];
}
@@ -396,10 +397,10 @@ static uint64_t send_router_advert(struct interface *iface, const struct in6_add
if (minvalid > valid)
minvalid = valid;
- if (!IN6_IS_ADDR_ULA(&addr->addr) || iface->default_router)
+ if (!IN6_IS_ADDR_ULA(&addr->addr.in6) || iface->default_router)
valid_prefix = true;
- odhcpd_bmemcpy(&p->nd_opt_pi_prefix, &addr->addr,
+ odhcpd_bmemcpy(&p->nd_opt_pi_prefix, &addr->addr.in6,
(iface->ra_advrouter) ? 128 : addr->prefix);
p->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
p->nd_opt_pi_len = 4;
@@ -498,10 +499,10 @@ static uint64_t send_router_advert(struct interface *iface, const struct in6_add
(addr->dprefix == 64 && addr->prefix == 64)) {
continue; // Address not suitable
} else if (addr->dprefix > 32) {
- addr->addr.s6_addr32[1] &= htonl(~((1U << (64 - addr->dprefix)) - 1));
+ addr->addr.in6.s6_addr32[1] &= htonl(~((1U << (64 - addr->dprefix)) - 1));
} else if (addr->dprefix <= 32) {
- addr->addr.s6_addr32[0] &= htonl(~((1U << (32 - addr->dprefix)) - 1));
- addr->addr.s6_addr32[1] = 0;
+ addr->addr.in6.s6_addr32[0] &= htonl(~((1U << (32 - addr->dprefix)) - 1));
+ addr->addr.in6.s6_addr32[1] = 0;
}
tmp = realloc(routes, sizeof(*routes) * (routes_cnt + 1));
@@ -522,8 +523,8 @@ static uint64_t send_router_advert(struct interface *iface, const struct in6_add
else if (iface->route_preference > 0)
routes[routes_cnt].flags |= ND_RA_PREF_HIGH;
routes[routes_cnt].lifetime = htonl(TIME_LEFT(addr->valid, now));
- routes[routes_cnt].addr[0] = addr->addr.s6_addr32[0];
- routes[routes_cnt].addr[1] = addr->addr.s6_addr32[1];
+ routes[routes_cnt].addr[0] = addr->addr.in6.s6_addr32[0];
+ routes[routes_cnt].addr[1] = addr->addr.in6.s6_addr32[1];
routes[routes_cnt].addr[2] = 0;
routes[routes_cnt].addr[3] = 0;