summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/dhcpv6-ia.c61
-rw-r--r--src/odhcpd.h5
-rw-r--r--src/router.c8
3 files changed, 58 insertions, 16 deletions
diff --git a/src/dhcpv6-ia.c b/src/dhcpv6-ia.c
index a59fc20..639e368 100644
--- a/src/dhcpv6-ia.c
+++ b/src/dhcpv6-ia.c
@@ -231,9 +231,19 @@ void dhcpv6_ia_enum_addrs(struct interface *iface, struct dhcp_assignment *c,
if (!valid_addr(&addrs[i], now))
continue;
+ /* Filter Out Prefixes */
+ if (ADDR_MATCH_PIO_FILTER(&addrs[i], iface)) {
+ char addrbuf[INET6_ADDRSTRLEN];
+ syslog(LOG_INFO, "Address %s filtered out on %s",
+ inet_ntop(AF_INET6, &addrs[i].addr.in6, addrbuf, sizeof(addrbuf)),
+ iface->name);
+ continue;
+ }
+
addr = addrs[i].addr.in6;
pref = addrs[i].preferred;
valid = addrs[i].valid;
+
if (c->flags & OAF_DHCPV6_NA) {
if (!ADDR_ENTRY_VALID_IA_ADDR(iface, i, m, addrs))
continue;
@@ -443,7 +453,12 @@ static void __apply_lease(struct dhcp_assignment *a,
return;
for (ssize_t i = 0; i < addr_len; ++i) {
- struct in6_addr prefix = addrs[i].addr.in6;
+ struct in6_addr prefix;
+
+ if (ADDR_MATCH_PIO_FILTER(&addrs[i], a->iface))
+ continue;
+
+ prefix = addrs[i].addr.in6;
prefix.s6_addr32[1] |= htonl(a->assigned);
prefix.s6_addr32[2] = prefix.s6_addr32[3] = 0;
netlink_setup_route(&prefix, (a->managed_size) ? addrs[i].prefix : a->length,
@@ -467,10 +482,15 @@ static void set_border_assignment_size(struct interface *iface, struct dhcp_assi
int minprefix = -1;
for (size_t i = 0; i < iface->addr6_len; ++i) {
- if (iface->addr6[i].preferred > (uint32_t)now &&
- iface->addr6[i].prefix < 64 &&
- iface->addr6[i].prefix > minprefix)
- minprefix = iface->addr6[i].prefix;
+ struct odhcpd_ipaddr *addr = &iface->addr6[i];
+
+ if (ADDR_MATCH_PIO_FILTER(addr, iface))
+ continue;
+
+ if (addr->preferred > (uint32_t)now &&
+ addr->prefix < 64 &&
+ addr->prefix > minprefix)
+ minprefix = addr->prefix;
}
if (minprefix > 32 && minprefix <= 64)
@@ -847,12 +867,23 @@ static size_t build_ia(uint8_t *buf, size_t buflen, uint16_t status,
size_t m = get_preferred_addr(addrs, addrlen);
for (size_t i = 0; i < addrlen; ++i) {
- uint32_t prefix_pref = addrs[i].preferred;
- uint32_t prefix_valid = addrs[i].valid;
+ uint32_t prefix_pref, prefix_valid;
if (!valid_addr(&addrs[i], now))
continue;
+ /* Filter Out Prefixes */
+ if (ADDR_MATCH_PIO_FILTER(&addrs[i], iface)) {
+ char addrbuf[INET6_ADDRSTRLEN];
+ syslog(LOG_INFO, "Address %s filtered out on %s",
+ inet_ntop(AF_INET6, &addrs[i].addr.in6, addrbuf, sizeof(addrbuf)),
+ iface->name);
+ continue;
+ }
+
+ prefix_pref = addrs[i].preferred;
+ prefix_valid = addrs[i].valid;
+
if (prefix_pref != UINT32_MAX)
prefix_pref -= now;
@@ -955,11 +986,18 @@ static size_t build_ia(uint8_t *buf, size_t buflen, uint16_t status,
size_t addrlen = (a->managed) ? (size_t)a->managed_size : iface->addr6_len;
for (size_t i = 0; i < addrlen; ++i) {
- if (!valid_addr(&addrs[i], now) ||
- !valid_prefix_length(a, addrs[i].prefix))
+ struct in6_addr addr;
+
+ if (!valid_addr(&addrs[i], now))
+ continue;
+
+ if (!valid_prefix_length(a, addrs[i].prefix))
+ continue;
+
+ if (ADDR_MATCH_PIO_FILTER(&addrs[i], iface))
continue;
- struct in6_addr addr = addrs[i].addr.in6;
+ 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;
@@ -1118,6 +1156,9 @@ static bool dhcpv6_ia_on_link(const struct dhcpv6_ia_hdr *ia, struct dhcp_assign
if (!valid_addr(&addrs[i], now))
continue;
+ if (ADDR_MATCH_PIO_FILTER(&addrs[i], iface))
+ continue;
+
if (ia->type == htons(DHCPV6_OPT_IA_PD)) {
if (p->prefix < addrs[i].prefix ||
odhcpd_bmemcmp(&p->addr, &addrs[i].addr.in6, addrs[i].prefix))
diff --git a/src/odhcpd.h b/src/odhcpd.h
index 45b6784..ee7b008 100644
--- a/src/odhcpd.h
+++ b/src/odhcpd.h
@@ -41,6 +41,11 @@
#define IN6_IS_ADDR_ULA(a) (((a)->s6_addr32[0] & htonl(0xfe000000)) == htonl(0xfc000000))
+#define ADDR_MATCH_PIO_FILTER(_addr, iface) (odhcpd_bmemcmp(&(_addr)->addr, \
+ &(iface)->pio_filter_addr, \
+ (iface)->pio_filter_length) != 0 || \
+ (_addr)->prefix < (iface)->pio_filter_length)
+
struct interface;
struct nl_sock;
extern struct vlist_tree leases;
diff --git a/src/router.c b/src/router.c
index d6ab4bb..541c023 100644
--- a/src/router.c
+++ b/src/router.c
@@ -518,9 +518,7 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
continue;
}
- if (odhcpd_bmemcmp(&addr->addr, &iface->pio_filter_addr,
- iface->pio_filter_length) != 0 ||
- addr->prefix < iface->pio_filter_length) {
+ if (ADDR_MATCH_PIO_FILTER(addr, iface)) {
syslog(LOG_INFO, "Address %s filtered out as RA prefix on %s",
inet_ntop(AF_INET6, &addr->addr.in6, buf, sizeof(buf)),
iface->name);
@@ -682,9 +680,7 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
continue; /* Address not suitable */
}
- if (odhcpd_bmemcmp(&addr->addr, &iface->pio_filter_addr,
- iface->pio_filter_length) != 0 ||
- addr->prefix < iface->pio_filter_length) {
+ if (ADDR_MATCH_PIO_FILTER(addr, iface)) {
syslog(LOG_INFO, "Address %s filtered out as RA route on %s",
inet_ntop(AF_INET6, &addr->addr.in6, buf, sizeof(buf)),
iface->name);