1
0
mirror of https://github.com/systemd/systemd.git synced 2025-02-09 13:57:42 +03:00

network/address: merge address_needs_to_set_broadcast() with address_get_broadcast()

No functional change, preparation for later commits.
This commit is contained in:
Yu Watanabe 2023-07-11 10:53:27 +09:00 committed by Luca Boccassi
parent 9dabe36cb0
commit 1a1f4a8092
2 changed files with 39 additions and 21 deletions

View File

@ -205,41 +205,55 @@ void link_mark_addresses(Link *link, NetworkConfigSource source) {
}
}
static bool address_needs_to_set_broadcast(const Address *a, Link *link) {
int address_get_broadcast(const Address *a, Link *link, struct in_addr *ret) {
struct in_addr b_addr = {};
assert(a);
assert(link);
if (a->family != AF_INET)
return false;
/* Returns 0 when broadcast address is null, 1 when non-null broadcast address, -EAGAIN when the main
* address is null. */
/* broadcast is only for IPv4. */
if (a->family != AF_INET)
goto finalize;
/* broadcast address cannot be used when peer address is specified. */
if (in4_addr_is_set(&a->in_addr_peer.in))
return false;
goto finalize;
/* A /31 or /32 IPv4 address does not have a broadcast address.
* See https://tools.ietf.org/html/rfc3021 */
if (a->prefixlen > 30)
return false;
goto finalize;
/* If explicitly configured, do not update the address. */
if (in4_addr_is_set(&a->broadcast))
return false;
/* If explicitly configured, use the address as is. */
if (in4_addr_is_set(&a->broadcast)) {
b_addr = a->broadcast;
goto finalize;
}
if (a->set_broadcast >= 0)
return a->set_broadcast;
/* If explicitly disabled, then return null address. */
if (a->set_broadcast == 0)
goto finalize;
/* Defaults to true, except for wireguard, as typical configuration for wireguard does not set
* broadcast. */
return !streq_ptr(link->kind, "wireguard");
}
/* For wireguard interfaces, broadcast is disabled by default. */
if (a->set_broadcast < 0 && streq_ptr(link->kind, "wireguard"))
goto finalize;
void address_set_broadcast(Address *a, Link *link) {
assert(a);
assert(link);
/* If the main address is null, e.g. Address=0.0.0.0/24, the broadcast address will be automatically
* determined after an address is acquired. */
if (!in4_addr_is_set(&a->in_addr.in))
return -EAGAIN;
if (!address_needs_to_set_broadcast(a, link))
return;
/* Otherwise, generate a broadcast address from the main address and prefix length. */
b_addr.s_addr = a->in_addr.in.s_addr | htobe32(UINT32_C(0xffffffff) >> a->prefixlen);
a->broadcast.s_addr = a->in_addr.in.s_addr | htobe32(UINT32_C(0xffffffff) >> a->prefixlen);
finalize:
if (ret)
*ret = b_addr;
return in4_addr_is_set(&b_addr);
}
static void address_set_cinfo(Manager *m, const Address *a, struct ifa_cacheinfo *cinfo) {

View File

@ -83,7 +83,11 @@ int address_remove_and_drop(Address *address);
int address_dup(const Address *src, Address **ret);
bool address_is_ready(const Address *a);
bool link_check_addresses_ready(Link *link, NetworkConfigSource source);
void address_set_broadcast(Address *a, Link *link);
int address_get_broadcast(const Address *a, Link *link, struct in_addr *ret);
static inline void address_set_broadcast(Address *a, Link *link) {
assert(a);
assert_se(address_get_broadcast(a, link, &a->broadcast) >= 0);
}
DEFINE_SECTION_CLEANUP_FUNCTIONS(Address, address_free);