manager: Add and remove routes for DHCPv6 Prefix Delegation

Configure routes to the links they are delegated to. Remove routes
once the delegation itself or the link is removed.
This commit is contained in:
Patrik Flykt 2018-01-04 15:12:00 +02:00
parent 76c3246d8d
commit 9f386c6d3b

View file

@ -1242,16 +1242,82 @@ Link *manager_dhcp6_prefix_get(Manager *m, struct in6_addr *addr) {
return hashmap_get(m->dhcp6_prefixes, addr);
}
static int dhcp6_route_add_callback(sd_netlink *nl, sd_netlink_message *m,
void *userdata) {
Link *l = userdata;
int r;
union in_addr_union prefix;
_cleanup_free_ char *buf = NULL;
r = sd_netlink_message_get_errno(m);
if (r != 0) {
log_link_debug_errno(l, r, "Received error adding DHCPv6 Prefix Delegation route: %m");
return 0;
}
r = sd_netlink_message_read_in6_addr(m, RTA_DST, &prefix.in6);
if (r < 0) {
log_link_debug_errno(l, r, "Could not read IPv6 address from DHCPv6 Prefix Delegation while adding route: %m");
return 0;
}
(void) in_addr_to_string(AF_INET6, &prefix, &buf);
log_link_debug(l, "Added DHCPv6 Prefix Deleagtion route %s/64",
strnull(buf));
return 0;
}
int manager_dhcp6_prefix_add(Manager *m, struct in6_addr *addr, Link *link) {
int r;
Route *route;
assert_return(m, -EINVAL);
assert_return(m->dhcp6_prefixes, -ENODATA);
assert_return(addr, -EINVAL);
r = route_add(link, AF_INET6, (union in_addr_union *) addr, 64,
0, 0, 0, &route);
if (r < 0)
return r;
r = route_configure(route, link, dhcp6_route_add_callback);
if (r < 0)
return r;
return hashmap_put(m->dhcp6_prefixes, addr, link);
}
static int dhcp6_route_remove_callback(sd_netlink *nl, sd_netlink_message *m,
void *userdata) {
Link *l = userdata;
int r;
union in_addr_union prefix;
_cleanup_free_ char *buf = NULL;
r = sd_netlink_message_get_errno(m);
if (r != 0) {
log_link_debug_errno(l, r, "Received error on DHCPv6 Prefix Delegation route removal: %m");
return 0;
}
r = sd_netlink_message_read_in6_addr(m, RTA_DST, &prefix.in6);
if (r < 0) {
log_link_debug_errno(l, r, "Could not read IPv6 address from DHCPv6 Prefix Delegation while removing route: %m");
return 0;
}
(void) in_addr_to_string(AF_INET6, &prefix, &buf);
log_link_debug(l, "Removed DHCPv6 Prefix Delegation route %s/64",
strnull(buf));
return 0;
}
int manager_dhcp6_prefix_remove(Manager *m, struct in6_addr *addr) {
Link *l;
int r;
Route *route;
assert_return(m, -EINVAL);
assert_return(m->dhcp6_prefixes, -ENODATA);
@ -1262,6 +1328,10 @@ int manager_dhcp6_prefix_remove(Manager *m, struct in6_addr *addr) {
return -EINVAL;
(void) sd_radv_remove_prefix(l->radv, addr, 64);
r = route_get(l, AF_INET6, (union in_addr_union *) addr, 64,
0, 0, 0, &route);
if (r >= 0)
(void) route_remove(route, l, dhcp6_route_remove_callback);
return 0;
}
@ -1278,9 +1348,7 @@ int manager_dhcp6_prefix_remove_all(Manager *m, Link *link) {
if (l != link)
continue;
(void) sd_radv_remove_prefix(l->radv, addr, 64);
hashmap_remove(m->dhcp6_prefixes, addr);
(void) manager_dhcp6_prefix_remove(m, addr);
}
return 0;