X Tutup
Skip to content

Commit e680486

Browse files
committed
network: set broadcast address on request
Previously, the broadcast address was set to a Address object in address_section_verify() (or address_acquire()). But, for wireguard interfaces, we do not use the broadcast address. The .network file may be assigned to multiple interfaces, hence, we cannot determine if we should set the broadcast address in address_section_verify(). This makes the broadcast address set in link_request_address(). Then, we set the broadcast address only when we need it.
1 parent 5d00303 commit e680486

File tree

4 files changed

+36
-32
lines changed

4 files changed

+36
-32
lines changed

src/network/networkd-address.c

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,9 @@ void link_mark_addresses(Link *link, NetworkConfigSource source, const struct in
174174
}
175175
}
176176

177-
static bool address_may_have_broadcast(const Address *a) {
177+
static bool address_needs_to_set_broadcast(const Address *a, Link *link) {
178178
assert(a);
179+
assert(link);
179180

180181
if (a->family != AF_INET)
181182
return false;
@@ -188,38 +189,26 @@ static bool address_may_have_broadcast(const Address *a) {
188189
if (a->prefixlen > 30)
189190
return false;
190191

191-
if (a->set_broadcast >= 0)
192-
return a->set_broadcast;
193-
194-
return true; /* Defaults to true. */
195-
}
196-
197-
void address_set_broadcast(Address *a) {
198-
assert(a);
199-
200-
if (!address_may_have_broadcast(a))
201-
return;
202-
203192
/* If explicitly configured, do not update the address. */
204193
if (in4_addr_is_set(&a->broadcast))
205-
return;
194+
return false;
206195

207-
/* If Address= is 0.0.0.0, then the broadcast address will be set later in address_acquire(). */
208-
if (in4_addr_is_null(&a->in_addr.in))
209-
return;
196+
if (a->set_broadcast >= 0)
197+
return a->set_broadcast;
210198

211-
a->broadcast.s_addr = a->in_addr.in.s_addr | htobe32(UINT32_C(0xffffffff) >> a->prefixlen);
199+
/* Defaults to true, except for wireguard, as typical configuration for wireguard does not set
200+
* broadcast. */
201+
return !streq_ptr(link->kind, "wireguard");
212202
}
213203

214-
static bool address_may_set_broadcast(const Address *a, const Link *link) {
204+
void address_set_broadcast(Address *a, Link *link) {
215205
assert(a);
216206
assert(link);
217207

218-
if (!address_may_have_broadcast(a))
219-
return false;
208+
if (!address_needs_to_set_broadcast(a, link))
209+
return;
220210

221-
/* Typical configuration for wireguard does not set broadcast. */
222-
return !streq_ptr(link->kind, "wireguard");
211+
a->broadcast.s_addr = a->in_addr.in.s_addr | htobe32(UINT32_C(0xffffffff) >> a->prefixlen);
223212
}
224213

225214
static struct ifa_cacheinfo *address_set_cinfo(const Address *a, struct ifa_cacheinfo *cinfo) {
@@ -975,7 +964,6 @@ static int address_acquire(Link *link, const Address *original, Address **ret) {
975964
return r;
976965

977966
na->in_addr = in_addr;
978-
address_set_broadcast(na);
979967

980968
*ret = TAKE_PTR(na);
981969
return 1;
@@ -1037,7 +1025,7 @@ static int address_configure(
10371025
r = netlink_message_append_in_addr_union(req, IFA_ADDRESS, address->family, &address->in_addr_peer);
10381026
if (r < 0)
10391027
return log_link_error_errno(link, r, "Could not append IFA_ADDRESS attribute: %m");
1040-
} else if (address_may_set_broadcast(address, link)) {
1028+
} else if (in4_addr_is_set(&address->broadcast)) {
10411029
r = sd_netlink_message_append_in_addr(req, IFA_BROADCAST, &address->broadcast);
10421030
if (r < 0)
10431031
return log_link_error_errno(link, r, "Could not append IFA_BROADCAST attribute: %m");
@@ -1132,6 +1120,21 @@ int link_request_address(
11321120
consume_object = true;
11331121
}
11341122

1123+
if (address_needs_to_set_broadcast(address, link)) {
1124+
if (!consume_object) {
1125+
Address *a;
1126+
1127+
r = address_dup(address, &a);
1128+
if (r < 0)
1129+
return r;
1130+
1131+
address = a;
1132+
consume_object = true;
1133+
}
1134+
1135+
address_set_broadcast(address, link);
1136+
}
1137+
11351138
if (address_get(link, address, &existing) < 0) {
11361139
_cleanup_(address_freep) Address *tmp = NULL;
11371140

@@ -1922,10 +1925,11 @@ static int address_section_verify(Address *address) {
19221925
address->section->filename, address->section->line);
19231926
}
19241927

1925-
if (address_may_have_broadcast(address))
1926-
address_set_broadcast(address);
1927-
else if (address->broadcast.s_addr != 0) {
1928-
log_warning("%s: broadcast address is set for IPv6 address or IPv4 address with prefixlength larger than 30. "
1928+
if (in4_addr_is_set(&address->broadcast) &&
1929+
(address->family == AF_INET6 || address->prefixlen > 30 ||
1930+
in_addr_is_set(address->family, &address->in_addr_peer))) {
1931+
log_warning("%s: broadcast address is set for an IPv6 address, "
1932+
"an IPv4 address with peer address, or with prefix length larger than 30. "
19291933
"Ignoring Broadcast= setting in the [Address] section from line %u.",
19301934
address->section->filename, address->section->line);
19311935

src/network/networkd-address.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ int address_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m,
7070
int address_remove(Address *address);
7171
int address_dup(const Address *src, Address **ret);
7272
bool address_is_ready(const Address *a);
73-
void address_set_broadcast(Address *a);
73+
void address_set_broadcast(Address *a, Link *link);
7474

7575
DEFINE_SECTION_CLEANUP_FUNCTIONS(Address, address_free);
7676

src/network/networkd-dhcp-server.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ int link_request_dhcp_server_address(Link *link) {
106106
address->family = AF_INET;
107107
address->in_addr.in = link->network->dhcp_server_address;
108108
address->prefixlen = link->network->dhcp_server_address_prefixlen;
109-
address_set_broadcast(address);
109+
address_set_broadcast(address, link);
110110

111111
if (address_get(link, address, &existing) >= 0 &&
112112
address_exists(existing) &&

src/network/networkd-ipv4ll.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ static int address_new_from_ipv4ll(Link *link, Address **ret) {
3434
address->prefixlen = 16;
3535
address->scope = RT_SCOPE_LINK;
3636
address->route_metric = IPV4LL_ROUTE_METRIC;
37-
address_set_broadcast(address);
37+
address_set_broadcast(address, link);
3838

3939
*ret = TAKE_PTR(address);
4040
return 0;

0 commit comments

Comments
 (0)
X Tutup