]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: sr-iov: drop conflicting sections
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 23 Dec 2021 03:59:52 +0000 (12:59 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 19 Jan 2022 05:57:59 +0000 (14:57 +0900)
src/network/networkd-network.c
src/network/networkd-sriov.c
src/network/networkd-sriov.h

index 873ad2e70341a3fc5f47656b7ac5341ab1f58a43..70e8af5bd498bf30a322150ea8de0e20ee220049 100644 (file)
@@ -321,7 +321,9 @@ int network_verify(Network *network) {
         network_drop_invalid_route_prefixes(network);
         network_drop_invalid_routing_policy_rules(network);
         network_drop_invalid_traffic_control(network);
-        network_drop_invalid_sr_iov(network);
+        r = network_drop_invalid_sr_iov(network);
+        if (r < 0)
+                return r;
         network_drop_invalid_static_leases(network);
 
         network_adjust_dhcp_server(network);
index 6805987b2b809c926bb903163aa4c1c4a76c6d07..da98ef9c8bc090fd03635e57605370a8bac2f0ba 100644 (file)
@@ -265,14 +265,39 @@ static int sr_iov_section_verify(SRIOV *sr_iov) {
         return 0;
 }
 
-void network_drop_invalid_sr_iov(Network *network) {
+int network_drop_invalid_sr_iov(Network *network) {
+        _cleanup_hashmap_free_ Hashmap *hashmap = NULL;
         SRIOV *sr_iov;
+        int r;
 
         assert(network);
 
-        ORDERED_HASHMAP_FOREACH(sr_iov, network->sr_iov_by_section)
-                if (sr_iov_section_verify(sr_iov) < 0)
+        ORDERED_HASHMAP_FOREACH(sr_iov, network->sr_iov_by_section) {
+                SRIOV *dup;
+
+                if (sr_iov_section_verify(sr_iov) < 0) {
                         sr_iov_free(sr_iov);
+                        continue;
+                }
+
+                assert(sr_iov->vf < INT_MAX);
+
+                dup = hashmap_remove(hashmap, UINT32_TO_PTR(sr_iov->vf + 1));
+                if (dup) {
+                        log_warning("%s: Conflicting [SR-IOV] section is specified at line %u and %u, "
+                                    "dropping the [SR-IOV] section specified at line %u.",
+                                    dup->section->filename, sr_iov->section->line,
+                                    dup->section->line, dup->section->line);
+                        sr_iov_free(dup);
+                }
+
+                r = hashmap_ensure_put(&hashmap, NULL, UINT32_TO_PTR(sr_iov->vf + 1), sr_iov);
+                if (r < 0)
+                        return log_oom();
+                assert(r > 0);
+        }
+
+        return 0;
 }
 
 int config_parse_sr_iov_uint32(
index 950d1f9c59827ffb6a214b97e64f28740f760710..be4430a9a049c0893f41857a27922c477515e30a 100644 (file)
@@ -35,7 +35,7 @@ typedef struct SRIOV {
 
 SRIOV *sr_iov_free(SRIOV *sr_iov);
 int link_configure_sr_iov(Link *link);
-void network_drop_invalid_sr_iov(Network *network);
+int network_drop_invalid_sr_iov(Network *network);
 
 DEFINE_NETWORK_SECTION_FUNCTIONS(SRIOV, sr_iov_free);