mirror of
https://github.com/systemd/systemd.git
synced 2024-12-25 01:34:28 +03:00
Merge pull request #20498 from yuwata/network-fix-gateway
network: fix logic for checking gateway address
This commit is contained in:
commit
f95d1ef5fa
@ -793,12 +793,7 @@ static bool nexthop_is_ready_to_configure(Link *link, const NextHop *nexthop) {
|
||||
}
|
||||
}
|
||||
|
||||
if (nexthop->onlink <= 0 &&
|
||||
in_addr_is_set(nexthop->family, &nexthop->gw) &&
|
||||
!manager_address_is_reachable(link->manager, nexthop->family, &nexthop->gw))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return gateway_is_ready(link, nexthop->onlink, nexthop->family, &nexthop->gw);
|
||||
}
|
||||
|
||||
int request_process_nexthop(Request *req) {
|
||||
|
@ -750,6 +750,8 @@ static bool prefix_route_address_is_reachable(const Address *a, int family, cons
|
||||
|
||||
if (a->family != family)
|
||||
return false;
|
||||
if (!address_is_ready(a))
|
||||
return false;
|
||||
if (FLAGS_SET(a->flags, IFA_F_NOPREFIXROUTE))
|
||||
return false;
|
||||
if (in_addr_is_set(a->family, &a->in_addr_peer))
|
||||
@ -763,37 +765,34 @@ static bool prefix_route_address_is_reachable(const Address *a, int family, cons
|
||||
FAMILY_ADDRESS_SIZE(family) * 8) > 0;
|
||||
}
|
||||
|
||||
bool manager_address_is_reachable(Manager *manager, int family, const union in_addr_union *address) {
|
||||
Link *link;
|
||||
static bool link_address_is_reachable(Link *link, int family, const union in_addr_union *address) {
|
||||
Route *route;
|
||||
|
||||
assert(manager);
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
assert(IN_SET(family, AF_INET, AF_INET6));
|
||||
assert(address);
|
||||
|
||||
HASHMAP_FOREACH(link, manager->links_by_index) {
|
||||
Route *route;
|
||||
|
||||
SET_FOREACH(route, link->routes)
|
||||
if (route_address_is_reachable(route, family, address))
|
||||
return true;
|
||||
SET_FOREACH(route, link->routes_foreign)
|
||||
if (route_address_is_reachable(route, family, address))
|
||||
return true;
|
||||
}
|
||||
SET_FOREACH(route, link->routes)
|
||||
if (route_address_is_reachable(route, family, address))
|
||||
return true;
|
||||
SET_FOREACH(route, link->routes_foreign)
|
||||
if (route_address_is_reachable(route, family, address))
|
||||
return true;
|
||||
|
||||
/* If we do not manage foreign routes, then there may exist a prefix route we do not know,
|
||||
* which was created on configuring an address. Hence, also check the addresses. */
|
||||
if (!manager->manage_foreign_routes)
|
||||
HASHMAP_FOREACH(link, manager->links_by_index) {
|
||||
Address *a;
|
||||
if (!link->manager->manage_foreign_routes) {
|
||||
Address *a;
|
||||
|
||||
SET_FOREACH(a, link->addresses)
|
||||
if (prefix_route_address_is_reachable(a, family, address))
|
||||
return true;
|
||||
SET_FOREACH(a, link->addresses_foreign)
|
||||
if (prefix_route_address_is_reachable(a, family, address))
|
||||
return true;
|
||||
}
|
||||
SET_FOREACH(a, link->addresses)
|
||||
if (prefix_route_address_is_reachable(a, family, address))
|
||||
return true;
|
||||
SET_FOREACH(a, link->addresses_foreign)
|
||||
if (prefix_route_address_is_reachable(a, family, address))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -1689,6 +1688,22 @@ int link_request_static_routes(Link *link, bool only_ipv4) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool gateway_is_ready(Link *link, int onlink, int family, const union in_addr_union *gw) {
|
||||
assert(link);
|
||||
assert(gw);
|
||||
|
||||
if (onlink > 0)
|
||||
return true;
|
||||
|
||||
if (!in_addr_is_set(family, gw))
|
||||
return true;
|
||||
|
||||
if (family == AF_INET6 && in6_addr_is_link_local(&gw->in6))
|
||||
return true;
|
||||
|
||||
return link_address_is_reachable(link, family, gw);
|
||||
}
|
||||
|
||||
static int route_is_ready_to_configure(const Route *route, Link *link) {
|
||||
MultipathRoute *m;
|
||||
NextHop *nh = NULL;
|
||||
@ -1732,19 +1747,13 @@ static int route_is_ready_to_configure(const Route *route, Link *link) {
|
||||
return r;
|
||||
}
|
||||
|
||||
if (route->gateway_onlink <= 0 &&
|
||||
in_addr_is_set(route->gw_family, &route->gw) > 0 &&
|
||||
!manager_address_is_reachable(link->manager, route->gw_family, &route->gw))
|
||||
if (!gateway_is_ready(link, route->gateway_onlink, route->gw_family, &route->gw))
|
||||
return false;
|
||||
|
||||
ORDERED_SET_FOREACH(m, route->multipath_routes) {
|
||||
union in_addr_union a = m->gateway.address;
|
||||
Link *l = NULL;
|
||||
|
||||
if (route->gateway_onlink <= 0 &&
|
||||
!manager_address_is_reachable(link->manager, m->gateway.family, &a))
|
||||
return false;
|
||||
|
||||
if (m->ifname) {
|
||||
if (link_get_by_name(link->manager, m->ifname, &l) < 0)
|
||||
return false;
|
||||
@ -1756,6 +1765,9 @@ static int route_is_ready_to_configure(const Route *route, Link *link) {
|
||||
}
|
||||
if (l && !link_is_ready_to_configure(l, true))
|
||||
return false;
|
||||
|
||||
if (!gateway_is_ready(l ?: link, route->gateway_onlink, m->gateway.family, &a))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -78,8 +78,8 @@ int route_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Li
|
||||
int route_remove(const Route *route, Manager *manager, Link *link);
|
||||
|
||||
int link_has_route(Link *link, const Route *route);
|
||||
bool manager_address_is_reachable(Manager *manager, int family, const union in_addr_union *address);
|
||||
int manager_find_uplink(Manager *m, int family, Link *exclude, Link **ret);
|
||||
bool gateway_is_ready(Link *link, int onlink, int family, const union in_addr_union *gw);
|
||||
|
||||
int link_drop_routes(Link *link);
|
||||
int link_drop_foreign_routes(Link *link);
|
||||
|
@ -38,6 +38,10 @@ Id=7
|
||||
Family=ipv6
|
||||
Blackhole=yes
|
||||
|
||||
[NextHop]
|
||||
Id=8
|
||||
Gateway=fe80::222:4dff:ff:ff:ff:ff
|
||||
|
||||
[NextHop]
|
||||
Gateway=192.168.5.2
|
||||
|
||||
|
@ -17,6 +17,10 @@ Destination=2001:1234:5:9fff:ff:ff:ff:ff/128
|
||||
[Route]
|
||||
Gateway=2001:1234:5:8fff:ff:ff:ff:ff
|
||||
|
||||
[Route]
|
||||
Destination=2001:1234:5:afff:ff:ff:ff:ff/128
|
||||
Gateway=fe80::222:4dff:ff:ff:ff:ff
|
||||
|
||||
[Route]
|
||||
Destination=149.10.124.64
|
||||
Scope=link
|
||||
|
@ -2337,6 +2337,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
||||
print(output)
|
||||
self.assertIn('2001:1234:5:8fff:ff:ff:ff:ff proto static', output)
|
||||
self.assertIn('2001:1234:5:8f63::1 proto kernel', output)
|
||||
self.assertIn('2001:1234:5:afff:ff:ff:ff:ff via fe80:0:222:4dff:ff:ff:ff:ff proto static', output)
|
||||
|
||||
print('### ip -6 route show default')
|
||||
output = check_output('ip -6 route show default')
|
||||
@ -2985,6 +2986,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
||||
self.assertIn('id 3 dev veth99', output)
|
||||
self.assertIn('id 4 dev veth99', output)
|
||||
self.assertRegex(output, 'id 5 via 192.168.10.1 dev veth99 .*onlink')
|
||||
self.assertIn('id 8 via fe80:0:222:4dff:ff:ff:ff:ff dev veth99', output)
|
||||
self.assertRegex(output, r'id [0-9]* via 192.168.5.2 dev veth99')
|
||||
|
||||
output = check_output('ip nexthop list dev dummy98')
|
||||
|
Loading…
Reference in New Issue
Block a user