@@ -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
225214static 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
0 commit comments