mirror of
https://github.com/systemd/systemd.git
synced 2024-11-01 09:21:26 +03:00
network: introduce address_set_broadcast()
This commit is contained in:
parent
c9f2db2c40
commit
473680be32
@ -146,12 +146,38 @@ Address *address_free(Address *address) {
|
||||
static bool address_may_have_broadcast(const Address *a) {
|
||||
assert(a);
|
||||
|
||||
if (a->family != AF_INET)
|
||||
return false;
|
||||
|
||||
if (in4_addr_is_set(&a->in_addr_peer.in))
|
||||
return false;
|
||||
|
||||
/* 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;
|
||||
|
||||
return a->family == AF_INET &&
|
||||
in4_addr_is_null(&a->in_addr_peer.in) &&
|
||||
a->prefixlen <= 30;
|
||||
if (a->set_broadcast >= 0)
|
||||
return a->set_broadcast;
|
||||
|
||||
return true; /* Defaults to true. */
|
||||
}
|
||||
|
||||
void address_set_broadcast(Address *a) {
|
||||
assert(a);
|
||||
|
||||
if (!address_may_have_broadcast(a))
|
||||
return;
|
||||
|
||||
/* If explicitly configured, do not update the address. */
|
||||
if (in4_addr_is_set(&a->broadcast))
|
||||
return;
|
||||
|
||||
/* If Address= is 0.0.0.0, then the broadcast address will be set later in address_acquire(). */
|
||||
if (in4_addr_is_null(&a->in_addr.in))
|
||||
return;
|
||||
|
||||
a->broadcast.s_addr = a->in_addr.in.s_addr | htobe32(UINT32_C(0xffffffff) >> a->prefixlen);
|
||||
}
|
||||
|
||||
static bool address_may_set_broadcast(const Address *a, const Link *link) {
|
||||
@ -161,9 +187,6 @@ static bool address_may_set_broadcast(const Address *a, const Link *link) {
|
||||
if (!address_may_have_broadcast(a))
|
||||
return false;
|
||||
|
||||
if (a->set_broadcast >= 0)
|
||||
return a->set_broadcast;
|
||||
|
||||
/* Typical configuration for wireguard does not set broadcast. */
|
||||
return !streq_ptr(link->kind, "wireguard");
|
||||
}
|
||||
@ -825,7 +848,6 @@ int link_drop_addresses(Link *link) {
|
||||
|
||||
static int address_acquire(Link *link, const Address *original, Address **ret) {
|
||||
union in_addr_union in_addr = IN_ADDR_NULL;
|
||||
struct in_addr broadcast = {};
|
||||
_cleanup_(address_freep) Address *na = NULL;
|
||||
int r;
|
||||
|
||||
@ -847,16 +869,10 @@ static int address_acquire(Link *link, const Address *original, Address **ret) {
|
||||
if (r == 0)
|
||||
return -EBUSY;
|
||||
|
||||
if (original->family == AF_INET) {
|
||||
/* Pick first address in range for ourselves ... */
|
||||
/* Pick first address in range for ourselves. */
|
||||
if (original->family == AF_INET)
|
||||
in_addr.in.s_addr = in_addr.in.s_addr | htobe32(1);
|
||||
|
||||
/* .. and use last as broadcast address */
|
||||
if (original->prefixlen > 30)
|
||||
broadcast.s_addr = 0;
|
||||
else
|
||||
broadcast.s_addr = in_addr.in.s_addr | htobe32(0xFFFFFFFFUL >> original->prefixlen);
|
||||
} else if (original->family == AF_INET6)
|
||||
else if (original->family == AF_INET6)
|
||||
in_addr.in6.s6_addr[15] |= 1;
|
||||
|
||||
r = address_new(&na);
|
||||
@ -867,8 +883,8 @@ static int address_acquire(Link *link, const Address *original, Address **ret) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
na->broadcast = broadcast;
|
||||
na->in_addr = in_addr;
|
||||
address_set_broadcast(na);
|
||||
|
||||
r = set_ensure_put(&link->pool_addresses, &address_hash_ops, na);
|
||||
if (r < 0)
|
||||
@ -1957,10 +1973,9 @@ static int address_section_verify(Address *address) {
|
||||
address->section->filename, address->section->line);
|
||||
}
|
||||
|
||||
if (address_may_have_broadcast(address)) {
|
||||
if (address->broadcast.s_addr == 0 && address->set_broadcast != 0)
|
||||
address->broadcast.s_addr = address->in_addr.in.s_addr | htobe32(0xfffffffflu >> address->prefixlen);
|
||||
} else if (address->broadcast.s_addr != 0) {
|
||||
if (address_may_have_broadcast(address))
|
||||
address_set_broadcast(address);
|
||||
else if (address->broadcast.s_addr != 0) {
|
||||
log_warning("%s: broadcast address is set for IPv6 address or IPv4 address with prefixlength larger than 30. "
|
||||
"Ignoring Broadcast= setting in the [Address] section from line %u.",
|
||||
address->section->filename, address->section->line);
|
||||
|
@ -57,6 +57,7 @@ int address_remove_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Lin
|
||||
int address_remove(const Address *address, Link *link, link_netlink_message_handler_t callback);
|
||||
bool address_equal(const Address *a1, const Address *a2);
|
||||
bool address_is_ready(const Address *a);
|
||||
void address_set_broadcast(Address *a);
|
||||
|
||||
int generate_ipv6_eui_64_address(const Link *link, struct in6_addr *ret);
|
||||
|
||||
|
@ -31,9 +31,9 @@ static int address_new_from_ipv4ll(Link *link, Address **ret) {
|
||||
address->family = AF_INET;
|
||||
address->in_addr.in = addr;
|
||||
address->prefixlen = 16;
|
||||
address->broadcast.s_addr = address->in_addr.in.s_addr | htobe32(UINT32_C(0xffffffff) >> address->prefixlen);
|
||||
address->scope = RT_SCOPE_LINK;
|
||||
address->route_metric = IPV4LL_ROUTE_METRIC;
|
||||
address_set_broadcast(address);
|
||||
|
||||
*ret = TAKE_PTR(address);
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user