mirror of
https://github.com/systemd/systemd.git
synced 2025-03-25 18:50:18 +03:00
network: introduce link_drop_foreign_addresses()
This commit is contained in:
parent
682c65b04c
commit
f8f2f880d4
@ -542,6 +542,85 @@ int address_remove(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool link_is_static_address_configured(Link *link, Address *address) {
|
||||
Address *net_address;
|
||||
|
||||
assert(link);
|
||||
assert(address);
|
||||
|
||||
if (!link->network)
|
||||
return false;
|
||||
|
||||
LIST_FOREACH(addresses, net_address, link->network->static_addresses)
|
||||
if (address_equal(net_address, address))
|
||||
return true;
|
||||
else if (address->family == AF_INET6 && net_address->family == AF_INET6 &&
|
||||
in_addr_equal(AF_INET6, &address->in_addr, &net_address->in_addr_peer) > 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool link_address_is_dynamic(Link *link, Address *address) {
|
||||
Route *route;
|
||||
|
||||
assert(link);
|
||||
assert(address);
|
||||
|
||||
if (address->cinfo.ifa_prefered != CACHE_INFO_INFINITY_LIFE_TIME)
|
||||
return true;
|
||||
|
||||
/* Even when the address is leased from a DHCP server, networkd assign the address
|
||||
* without lifetime when KeepConfiguration=dhcp. So, let's check that we have
|
||||
* corresponding routes with RTPROT_DHCP. */
|
||||
SET_FOREACH(route, link->routes_foreign) {
|
||||
if (route->protocol != RTPROT_DHCP)
|
||||
continue;
|
||||
|
||||
if (address->family != route->family)
|
||||
continue;
|
||||
|
||||
if (in_addr_equal(address->family, &address->in_addr, &route->prefsrc))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int link_drop_foreign_addresses(Link *link) {
|
||||
Address *address;
|
||||
int k, r = 0;
|
||||
|
||||
assert(link);
|
||||
|
||||
SET_FOREACH(address, link->addresses_foreign) {
|
||||
/* we consider IPv6LL addresses to be managed by the kernel */
|
||||
if (address->family == AF_INET6 && in_addr_is_link_local(AF_INET6, &address->in_addr) == 1 && link_ipv6ll_enabled(link))
|
||||
continue;
|
||||
|
||||
if (link_address_is_dynamic(link, address)) {
|
||||
if (link->network && FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP))
|
||||
continue;
|
||||
} else if (link->network && FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_STATIC))
|
||||
continue;
|
||||
|
||||
if (link_is_static_address_configured(link, address)) {
|
||||
k = address_add(link, address->family, &address->in_addr, address->prefixlen, NULL);
|
||||
if (k < 0) {
|
||||
log_link_error_errno(link, k, "Failed to add address: %m");
|
||||
if (r >= 0)
|
||||
r = k;
|
||||
}
|
||||
} else {
|
||||
k = address_remove(address, link, NULL);
|
||||
if (k < 0 && r >= 0)
|
||||
r = k;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int address_acquire(Link *link, Address *original, Address **ret) {
|
||||
union in_addr_union in_addr = IN_ADDR_NULL;
|
||||
struct in_addr broadcast = {};
|
||||
|
@ -76,6 +76,7 @@ int generate_ipv6_eui_64_address(Link *link, struct in6_addr *ret);
|
||||
DEFINE_NETWORK_SECTION_FUNCTIONS(Address, address_free);
|
||||
|
||||
int link_set_addresses(Link *link);
|
||||
int link_drop_foreign_addresses(Link *link);
|
||||
|
||||
void address_hash_func(const Address *a, struct siphash *state);
|
||||
int address_compare_func(const Address *a1, const Address *a2);
|
||||
|
@ -163,7 +163,7 @@ bool link_ipv4ll_enabled(Link *link, AddressFamily mask) {
|
||||
return link->network->link_local & mask;
|
||||
}
|
||||
|
||||
static bool link_ipv6ll_enabled(Link *link) {
|
||||
bool link_ipv6ll_enabled(Link *link) {
|
||||
assert(link);
|
||||
|
||||
if (!socket_ipv6_is_supported())
|
||||
@ -2320,51 +2320,6 @@ static int link_set_ipv4_accept_local(Link *link) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool link_is_static_address_configured(Link *link, Address *address) {
|
||||
Address *net_address;
|
||||
|
||||
assert(link);
|
||||
assert(address);
|
||||
|
||||
if (!link->network)
|
||||
return false;
|
||||
|
||||
LIST_FOREACH(addresses, net_address, link->network->static_addresses)
|
||||
if (address_equal(net_address, address))
|
||||
return true;
|
||||
else if (address->family == AF_INET6 && net_address->family == AF_INET6 &&
|
||||
in_addr_equal(AF_INET6, &address->in_addr, &net_address->in_addr_peer) > 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool link_address_is_dynamic(Link *link, Address *address) {
|
||||
Route *route;
|
||||
|
||||
assert(link);
|
||||
assert(address);
|
||||
|
||||
if (address->cinfo.ifa_prefered != CACHE_INFO_INFINITY_LIFE_TIME)
|
||||
return true;
|
||||
|
||||
/* Even when the address is leased from a DHCP server, networkd assign the address
|
||||
* without lifetime when KeepConfiguration=dhcp. So, let's check that we have
|
||||
* corresponding routes with RTPROT_DHCP. */
|
||||
SET_FOREACH(route, link->routes_foreign) {
|
||||
if (route->protocol != RTPROT_DHCP)
|
||||
continue;
|
||||
|
||||
if (address->family != route->family)
|
||||
continue;
|
||||
|
||||
if (in_addr_equal(address->family, &address->in_addr, &route->prefsrc))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int link_enumerate_ipv6_tentative_addresses(Link *link) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
|
||||
sd_netlink_message *addr;
|
||||
@ -2408,7 +2363,6 @@ static int link_enumerate_ipv6_tentative_addresses(Link *link) {
|
||||
}
|
||||
|
||||
static int link_drop_foreign_config(Link *link) {
|
||||
Address *address;
|
||||
int r;
|
||||
|
||||
/* The kernel doesn't notify us about tentative addresses;
|
||||
@ -2419,27 +2373,9 @@ static int link_drop_foreign_config(Link *link) {
|
||||
return r;
|
||||
}
|
||||
|
||||
SET_FOREACH(address, link->addresses_foreign) {
|
||||
/* we consider IPv6LL addresses to be managed by the kernel */
|
||||
if (address->family == AF_INET6 && in_addr_is_link_local(AF_INET6, &address->in_addr) == 1 && link_ipv6ll_enabled(link))
|
||||
continue;
|
||||
|
||||
if (link_address_is_dynamic(link, address)) {
|
||||
if (link->network && FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP))
|
||||
continue;
|
||||
} else if (link->network && FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_STATIC))
|
||||
continue;
|
||||
|
||||
if (link_is_static_address_configured(link, address)) {
|
||||
r = address_add(link, address->family, &address->in_addr, address->prefixlen, NULL);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to add address: %m");
|
||||
} else {
|
||||
r = address_remove(address, link, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
r = link_drop_foreign_addresses(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = link_drop_foreign_neighbors(link);
|
||||
if (r < 0)
|
||||
|
@ -226,6 +226,7 @@ int link_save_and_clean(Link *link);
|
||||
int link_carrier_reset(Link *link);
|
||||
bool link_has_carrier(Link *link);
|
||||
|
||||
bool link_ipv6ll_enabled(Link *link);
|
||||
int link_ipv6ll_gained(Link *link, const struct in6_addr *address);
|
||||
|
||||
int link_set_mtu(Link *link, uint32_t mtu);
|
||||
|
Loading…
x
Reference in New Issue
Block a user