From: Patrik Flykt Date: Thu, 4 Jan 2018 13:12:00 +0000 (+0200) Subject: manager: Add and remove routes for DHCPv6 Prefix Delegation X-Git-Tag: v237~103^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9f386c6d3bd8bb103affece9221523d66d6932a0;p=thirdparty%2Fsystemd.git 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. --- diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 9d9d96ec8f1..2a0a546d543 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -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;