summaryrefslogtreecommitdiffhomepage
path: root/src/dhcpv6-ia.c
diff options
context:
space:
mode:
authorNick Hainke <vincent@systemli.org>2021-01-06 13:04:02 +0100
committerHans Dedecker <dedeckeh@gmail.com>2021-01-30 21:14:08 +0100
commit8d8a8cd35137ff0fa11b6be455fdd596a8d7d2e9 (patch)
tree3f24ca68e66d1f880a75a794a48a3730f77be4e0 /src/dhcpv6-ia.c
parent3bda90079ec5574ef469e2a7804808302f17769d (diff)
dhcpv6-ia: apply prefix_filter on dhcpv6
The prefix_filter allows to select which prefix should be assigned to clients if you have multiple prefixes on an interface. Currently, the filter only applies to RAs and does work with a dhcpv6 server. This commit enables the filter also on dhcpv6. Signed-off-by: Nick Hainke <vincent@systemli.org> Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
Diffstat (limited to 'src/dhcpv6-ia.c')
-rw-r--r--src/dhcpv6-ia.c61
1 files changed, 51 insertions, 10 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))