network: introduce link_drop_foreign_routes()

This commit is contained in:
Yu Watanabe 2020-10-02 09:38:31 +09:00
parent 169948e9d2
commit 779804dd60
3 changed files with 57 additions and 51 deletions

View File

@ -2497,22 +2497,6 @@ static bool link_is_static_address_configured(Link *link, Address *address) {
return false;
}
static bool link_is_static_route_configured(Link *link, Route *route) {
Route *net_route;
assert(link);
assert(route);
if (!link->network)
return false;
LIST_FOREACH(routes, net_route, link->network->static_routes)
if (route_equal(net_route, route))
return true;
return false;
}
static bool link_address_is_dynamic(Link *link, Address *address) {
Route *route;
@ -2583,7 +2567,6 @@ static int link_enumerate_ipv6_tentative_addresses(Link *link) {
static int link_drop_foreign_config(Link *link) {
Address *address;
Route *route;
int r;
/* The kernel doesn't notify us about tentative addresses;
@ -2620,40 +2603,7 @@ static int link_drop_foreign_config(Link *link) {
if (r < 0)
return r;
SET_FOREACH(route, link->routes_foreign) {
/* do not touch routes managed by the kernel */
if (route->protocol == RTPROT_KERNEL)
continue;
/* do not touch multicast route added by kernel */
/* FIXME: Why the kernel adds this route with protocol RTPROT_BOOT??? We need to investigate that.
* https://tools.ietf.org/html/rfc4862#section-5.4 may explain why. */
if (route->protocol == RTPROT_BOOT &&
route->family == AF_INET6 &&
route->dst_prefixlen == 8 &&
in_addr_equal(AF_INET6, &route->dst, &(union in_addr_union) { .in6 = {{{ 0xff,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 }}} }))
continue;
if (route->protocol == RTPROT_STATIC && link->network &&
FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_STATIC))
continue;
if (route->protocol == RTPROT_DHCP && link->network &&
FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP))
continue;
if (link_is_static_route_configured(link, route)) {
r = route_add(link, route, NULL);
if (r < 0)
return r;
} else {
r = route_remove(route, link, NULL);
if (r < 0)
return r;
}
}
return 0;
return link_drop_foreign_routes(link);
}
static int remove_static_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {

View File

@ -511,6 +511,61 @@ int route_remove(Route *route, Link *link,
return 0;
}
static bool link_is_static_route_configured(Link *link, Route *route) {
Route *net_route;
assert(link);
assert(route);
if (!link->network)
return false;
LIST_FOREACH(routes, net_route, link->network->static_routes)
if (route_equal(net_route, route))
return true;
return false;
}
int link_drop_foreign_routes(Link *link) {
Route *route;
int k, r = 0;
assert(link);
SET_FOREACH(route, link->routes_foreign) {
/* do not touch routes managed by the kernel */
if (route->protocol == RTPROT_KERNEL)
continue;
/* do not touch multicast route added by kernel */
/* FIXME: Why the kernel adds this route with protocol RTPROT_BOOT??? We need to investigate that.
* https://tools.ietf.org/html/rfc4862#section-5.4 may explain why. */
if (route->protocol == RTPROT_BOOT &&
route->family == AF_INET6 &&
route->dst_prefixlen == 8 &&
in_addr_equal(AF_INET6, &route->dst, &(union in_addr_union) { .in6 = {{{ 0xff,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 }}} }))
continue;
if (route->protocol == RTPROT_STATIC && link->network &&
FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_STATIC))
continue;
if (route->protocol == RTPROT_DHCP && link->network &&
FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP))
continue;
if (link_is_static_route_configured(link, route))
k = route_add(link, route, NULL);
else
k = route_remove(route, link, NULL);
if (k < 0 && r >= 0)
r = k;
}
return r;
}
int route_expire_handler(sd_event_source *s, uint64_t usec, void *userdata) {
Route *route = userdata;
int r;

View File

@ -72,6 +72,7 @@ int route_configure(Route *route, Link *link, link_netlink_message_handler_t cal
int route_remove(Route *route, Link *link, link_netlink_message_handler_t callback);
int link_set_routes(Link *link);
int link_drop_foreign_routes(Link *link);
int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, Manager *m);