diff --git a/src/network/networkd-address-label.c b/src/network/networkd-address-label.c index 139610631f..6f911b805f 100644 --- a/src/network/networkd-address-label.c +++ b/src/network/networkd-address-label.c @@ -54,6 +54,7 @@ static int address_label_new_static(Network *network, const char *filename, unsi *label = (AddressLabel) { .network = network, .section = TAKE_PTR(n), + .label = UINT32_MAX, }; r = hashmap_ensure_put(&network->address_labels_by_section, &network_config_hash_ops, label->section, label); @@ -118,7 +119,7 @@ static int address_label_configure(AddressLabel *label, Link *link, link_netlink if (r < 0) return log_link_error_errno(link, r, "Could not append IFAL_LABEL attribute: %m"); - r = sd_netlink_message_append_in6_addr(req, IFA_ADDRESS, &label->in_addr); + r = sd_netlink_message_append_in6_addr(req, IFA_ADDRESS, &label->prefix); if (r < 0) return log_link_error_errno(link, r, "Could not append IFA_ADDRESS attribute: %m"); @@ -171,13 +172,35 @@ int request_process_address_label(Request *req) { return address_label_configure(req->label, req->link, req->netlink_handler); } +static int address_label_section_verify(AddressLabel *label) { + assert(label); + assert(label->section); + + if (section_is_invalid(label->section)) + return -EINVAL; + + if (!label->prefix_set) + return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), + "%s: [IPv6AddressLabel] section without Prefix= setting specified. " + "Ignoring [IPv6AddressLabel] section from line %u.", + label->section->filename, label->section->line); + + if (label->label == UINT32_MAX) + return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), + "%s: [IPv6AddressLabel] section without Label= setting specified. " + "Ignoring [IPv6AddressLabel] section from line %u.", + label->section->filename, label->section->line); + + return 0; +} + void network_drop_invalid_address_labels(Network *network) { AddressLabel *label; assert(network); HASHMAP_FOREACH(label, network->address_labels_by_section) - if (section_is_invalid(label->section)) + if (address_label_section_verify(label) < 0) address_label_free(label); } @@ -223,8 +246,9 @@ int config_parse_address_label_prefix( return 0; } - n->in_addr = a.in6; + n->prefix = a.in6; n->prefixlen = prefixlen; + n->prefix_set = true; TAKE_PTR(n); return 0; @@ -263,7 +287,7 @@ int config_parse_address_label( return 0; } - if (k == UINT32_C(0xffffffff)) { + if (k == UINT_MAX) { log_syntax(unit, LOG_WARNING, filename, line, 0, "Address label is invalid, ignoring: %s", rvalue); return 0; } diff --git a/src/network/networkd-address-label.h b/src/network/networkd-address-label.h index 26d2d94911..0f975454d9 100644 --- a/src/network/networkd-address-label.h +++ b/src/network/networkd-address-label.h @@ -15,9 +15,10 @@ typedef struct AddressLabel { Network *network; NetworkConfigSection *section; - unsigned char prefixlen; uint32_t label; - struct in6_addr in_addr; + struct in6_addr prefix; + unsigned char prefixlen; + bool prefix_set; } AddressLabel; AddressLabel *address_label_free(AddressLabel *label); diff --git a/test/test-network/conf/25-address-static.network b/test/test-network/conf/25-address-static.network index 209a8553b9..2a4c1a6039 100644 --- a/test/test-network/conf/25-address-static.network +++ b/test/test-network/conf/25-address-static.network @@ -43,6 +43,11 @@ Label=30 Peer=hoge Address=10.10.0.2/16 +[Address] +# address and peer must be in the same family +Address=10.10.0.3/16 +Peer=2001:db8:0:f103::10/128 + [Address] Address=2001:db8:0:f102::16/64 @@ -65,6 +70,7 @@ Scope=link [Address] # this will also deduped Address=2001:0db8:1:f101::1/64 +PreferredLifetime=infinity [Address] Address=2001:0db8:1:f101::1/64 @@ -72,8 +78,33 @@ PreferredLifetime=0 [Address] Address=10.8.8.1/16 +Broadcast=yes +Broadcast= Broadcast=no +[Address] +Address=10.8.8.2/16 +Broadcast=10.8.8.128 + +[Address] +# Invalid broadcast +Address=10.8.8.2/16 +Broadcast=::1 + +[Address] +# broadcast cannot set for IPv6 address +Address=2001:0db8:1:f101::2/64 +Broadcast=::1 + +[Address] +Address=10.9.0.1/16 +RouteMetric=128 + +[Address] +# invalid metric +Address=10.9.0.1/16 +RouteMetric=hoge + # test for ENOBUFS issue #17012 [Network] Address=10.3.3.1/16 diff --git a/test/test-network/conf/25-ipv6-address-label-section.network b/test/test-network/conf/25-ipv6-address-label-section.network index 1e3f47b567..89a5c2a6bc 100644 --- a/test/test-network/conf/25-ipv6-address-label-section.network +++ b/test/test-network/conf/25-ipv6-address-label-section.network @@ -8,3 +8,27 @@ IPv6AcceptRA=no [IPv6AddressLabel] Label=4444 Prefix=2004:da8:1:0::/64 + +# invalid sections +[IPv6AddressLabel] +# No Label= +Prefix=2004:da8:1:1::/64 + +[IPv6AddressLabel] +# No Prefix= +Label=4445 + +[IPv6AddressLabel] +# Invalid label +Label=0xffffffff +Prefix=2004:da8:1:2::/64 + +[IPv6AddressLabel] +# IPv4 mapped prefix +Label=4446 +Prefix=::ffff:c0a8:0/120 + +[IPv6AddressLabel] +# Invalid prefix +Label=4447 +Prefix=192.168.1.0/24 diff --git a/test/test-network/conf/ipv6-prefix-veth-token-prefixstable.network b/test/test-network/conf/ipv6-prefix-veth-token-prefixstable.network index b0afecdc2b..02056d335b 100644 --- a/test/test-network/conf/ipv6-prefix-veth-token-prefixstable.network +++ b/test/test-network/conf/ipv6-prefix-veth-token-prefixstable.network @@ -7,3 +7,8 @@ IPv6AcceptRA=true [IPv6AcceptRA] Token=prefixstable:2002:da8:1:: +# invalid tokens +Token=prefixstable@ +Token=static +Token=static: +Token=static::: diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index fc46c31c5d..7eb94a32d3 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -2002,6 +2002,8 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities): self.assertIn('inet 10.2.2.4/16 brd 10.2.255.255 scope global dummy98', output) self.assertIn('inet 10.7.8.9/16 brd 10.7.255.255 scope link deprecated dummy98', output) self.assertIn('inet 10.8.8.1/16 scope global dummy98', output) + self.assertIn('inet 10.8.8.2/16 brd 10.8.8.128 scope global secondary dummy98', output) + self.assertRegex(output, 'inet 10.9.0.1/16 (metric 128 |)brd 10.9.255.255 scope global dummy98') # test for ENOBUFS issue #17012 for i in range(1,254): @@ -2023,6 +2025,10 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities): output = check_output('ip -4 address show dev dummy98 label 35') self.assertRegex(output, r'inet 172.[0-9]*.0.1/16 brd 172.[0-9]*.255.255 scope global 35') + output = check_output('ip -4 route show dev dummy98') + print(output) + self.assertIn('10.9.0.0/16 proto kernel scope link src 10.9.0.1 metric 128', output) + output = check_output('ip -6 address show dev dummy98') print(output) self.assertIn('inet6 2001:db8:0:f101::15/64 scope global', output)