]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: allocate hashmap objects when they are required
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 12 Nov 2018 06:24:11 +0000 (15:24 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 12 Nov 2018 07:32:11 +0000 (16:32 +0900)
src/network/netdev/netdev.c
src/network/networkd-address-label.c
src/network/networkd-address.c
src/network/networkd-fdb.c
src/network/networkd-manager.c
src/network/networkd-network.c
src/network/networkd-network.h
src/network/networkd-radv.c
src/network/networkd-route.c
src/network/networkd-routing-policy-rule.c
src/network/test-networkd-conf.c

index 4c683874ebf59b81022214ebf7ae33e1d0ee8376..33931bad92f4b4215e8eea90a5e00bbb2cfc4a75 100644 (file)
@@ -729,6 +729,10 @@ int netdev_load_one(Manager *manager, const char *filename) {
                         return log_error_errno(r, "Failed to generate predictable MAC address for %s: %m", netdev->ifname);
         }
 
+        r = hashmap_ensure_allocated(&netdev->manager->netdevs, &string_hash_ops);
+        if (r < 0)
+                return r;
+
         r = hashmap_put(netdev->manager->netdevs, netdev->ifname, netdev);
         if (r < 0)
                 return r;
index 1392cba538d0950245631f55c988310dae8960a2..691bbf476194f27d701fb456006695a1bda998c6 100644 (file)
@@ -65,6 +65,10 @@ static int address_label_new_static(Network *network, const char *filename, unsi
         if (filename) {
                 label->section = TAKE_PTR(n);
 
+                r = hashmap_ensure_allocated(&network->address_labels_by_section, &network_config_hash_ops);
+                if (r < 0)
+                        return r;
+
                 r = hashmap_put(network->address_labels_by_section, label->section, label);
                 if (r < 0)
                         return r;
index d028f7226e79de3475b4874c5638d344bac800d2..09f041602ce25e8aa0c3502d4c75d736b2f167d5 100644 (file)
@@ -74,6 +74,10 @@ int address_new_static(Network *network, const char *filename, unsigned section_
         if (filename) {
                 address->section = TAKE_PTR(n);
 
+                r = hashmap_ensure_allocated(&network->addresses_by_section, &network_config_hash_ops);
+                if (r < 0)
+                        return r;
+
                 r = hashmap_put(network->addresses_by_section, address->section, address);
                 if (r < 0)
                         return r;
index 3203470db358b9ec533a9162249241d713bb4db2..c7742a93fb5d82734da565fa9a154699c0e9033c 100644 (file)
@@ -72,6 +72,10 @@ int fdb_entry_new_static(
         if (filename) {
                 fdb_entry->section = TAKE_PTR(n);
 
+                r = hashmap_ensure_allocated(&network->fdb_entries_by_section, &network_config_hash_ops);
+                if (r < 0)
+                        return r;
+
                 r = hashmap_put(network->fdb_entries_by_section, fdb_entry->section, fdb_entry);
                 if (r < 0)
                         return r;
index ac649863b4ceeccc56342e35ef688cf01e86683f..fce8f4610c97444002808c175834e9f4967fa711 100644 (file)
@@ -1213,7 +1213,6 @@ static int manager_dirty_handler(sd_event_source *s, void *userdata) {
 
 Link *manager_dhcp6_prefix_get(Manager *m, struct in6_addr *addr) {
         assert_return(m, NULL);
-        assert_return(m->dhcp6_prefixes, NULL);
         assert_return(addr, NULL);
 
         return hashmap_get(m->dhcp6_prefixes, addr);
@@ -1232,13 +1231,31 @@ static int dhcp6_route_add_handler(sd_netlink *nl, sd_netlink_message *m, void *
         return 0;
 }
 
+static void dhcp6_prefixes_hash_func(const void *p, struct siphash *state) {
+        const struct in6_addr *addr = p;
+
+        assert(p);
+
+        siphash24_compress(addr, sizeof(*addr), state);
+}
+
+static int dhcp6_prefixes_compare_func(const void *_a, const void *_b) {
+        const struct in6_addr *a = _a, *b = _b;
+
+        return memcmp(a, b, sizeof(*a));
+}
+
+static const struct hash_ops dhcp6_prefixes_hash_ops = {
+        .hash = dhcp6_prefixes_hash_func,
+        .compare = dhcp6_prefixes_compare_func,
+};
+
 int manager_dhcp6_prefix_add(Manager *m, struct in6_addr *addr, Link *link) {
-        int r;
-        Route *route;
         _cleanup_free_ char *buf = NULL;
+        Route *route;
+        int r;
 
         assert_return(m, -EINVAL);
-        assert_return(m->dhcp6_prefixes, -ENODATA);
         assert_return(addr, -EINVAL);
 
         r = route_add(link, AF_INET6, (union in_addr_union *) addr, 64,
@@ -1253,6 +1270,10 @@ int manager_dhcp6_prefix_add(Manager *m, struct in6_addr *addr, Link *link) {
         (void) in_addr_to_string(AF_INET6, (union in_addr_union *) addr, &buf);
         log_link_debug(link, "Adding prefix route %s/64", strnull(buf));
 
+        r = hashmap_ensure_allocated(&m->dhcp6_prefixes, &dhcp6_prefixes_hash_ops);
+        if (r < 0)
+                return r;
+
         return hashmap_put(m->dhcp6_prefixes, addr, link);
 }
 
@@ -1270,13 +1291,12 @@ static int dhcp6_route_remove_handler(sd_netlink *nl, sd_netlink_message *m, voi
 }
 
 static int manager_dhcp6_prefix_remove(Manager *m, struct in6_addr *addr) {
+        _cleanup_free_ char *buf = NULL;
+        Route *route;
         Link *l;
         int r;
-        Route *route;
-        _cleanup_free_ char *buf = NULL;
 
         assert_return(m, -EINVAL);
-        assert_return(m->dhcp6_prefixes, -ENODATA);
         assert_return(addr, -EINVAL);
 
         l = hashmap_remove(m->dhcp6_prefixes, addr);
@@ -1300,9 +1320,9 @@ static int manager_dhcp6_prefix_remove(Manager *m, struct in6_addr *addr) {
 }
 
 int manager_dhcp6_prefix_remove_all(Manager *m, Link *link) {
+        struct in6_addr *addr;
         Iterator i;
         Link *l;
-        struct in6_addr *addr;
 
         assert_return(m, -EINVAL);
         assert_return(link, -EINVAL);
@@ -1317,25 +1337,6 @@ int manager_dhcp6_prefix_remove_all(Manager *m, Link *link) {
         return 0;
 }
 
-static void dhcp6_prefixes_hash_func(const void *p, struct siphash *state) {
-        const struct in6_addr *addr = p;
-
-        assert(p);
-
-        siphash24_compress(addr, sizeof(*addr), state);
-}
-
-static int dhcp6_prefixes_compare_func(const void *_a, const void *_b) {
-        const struct in6_addr *a = _a, *b = _b;
-
-        return memcmp(a, b, sizeof(*a));
-}
-
-static const struct hash_ops dhcp6_prefixes_hash_ops = {
-        .hash = dhcp6_prefixes_hash_func,
-        .compare = dhcp6_prefixes_compare_func,
-};
-
 int manager_new(Manager **ret) {
         _cleanup_(manager_freep) Manager *m = NULL;
         int r;
@@ -1372,10 +1373,6 @@ int manager_new(Manager **ret) {
         if (r < 0)
                 return r;
 
-        m->netdevs = hashmap_new(&string_hash_ops);
-        if (!m->netdevs)
-                return -ENOMEM;
-
         LIST_HEAD_INIT(m->networks);
 
         r = sd_resolve_default(&m->resolve);
@@ -1390,10 +1387,6 @@ int manager_new(Manager **ret) {
         if (r < 0)
                 return r;
 
-        m->dhcp6_prefixes = hashmap_new(&dhcp6_prefixes_hash_ops);
-        if (!m->dhcp6_prefixes)
-                return -ENOMEM;
-
         m->duid.type = DUID_TYPE_EN;
 
         (void) routing_policy_load_rules(m->state_file, &m->rules_saved);
index 85d0c1f54eec2ba3eba8dd64e6a7e95c47ba9db2..989c92322bb3d5ad489fe896f7ff41cec14bf87d 100644 (file)
@@ -193,34 +193,6 @@ int network_load_one(Manager *manager, const char *filename) {
                 .ipv6_accept_ra_route_table = RT_TABLE_MAIN,
         };
 
-        network->stacked_netdevs = hashmap_new(&string_hash_ops);
-        if (!network->stacked_netdevs)
-                return log_oom();
-
-        network->addresses_by_section = hashmap_new(&network_config_hash_ops);
-        if (!network->addresses_by_section)
-                return log_oom();
-
-        network->routes_by_section = hashmap_new(&network_config_hash_ops);
-        if (!network->routes_by_section)
-                return log_oom();
-
-        network->fdb_entries_by_section = hashmap_new(&network_config_hash_ops);
-        if (!network->fdb_entries_by_section)
-                return log_oom();
-
-        network->address_labels_by_section = hashmap_new(&network_config_hash_ops);
-        if (!network->address_labels_by_section)
-                log_oom();
-
-        network->prefixes_by_section = hashmap_new(&network_config_hash_ops);
-        if (!network->prefixes_by_section)
-                return log_oom();
-
-        network->rules_by_section = hashmap_new(&network_config_hash_ops);
-        if (!network->rules_by_section)
-                return log_oom();
-
         network->filename = strdup(filename);
         if (!network->filename)
                 return log_oom();
@@ -615,6 +587,10 @@ int config_parse_netdev(const char *unit,
         case NETDEV_KIND_IPVLAN:
         case NETDEV_KIND_VXLAN:
         case NETDEV_KIND_VCAN:
+                r = hashmap_ensure_allocated(&network->stacked_netdevs, &string_hash_ops);
+                if (r < 0)
+                        return log_oom();
+
                 r = hashmap_put(network->stacked_netdevs, netdev->ifname, netdev);
                 if (r < 0) {
                         log_syntax(unit, LOG_ERR, filename, line, r, "Cannot add NetDev '%s' to network: %m", rvalue);
@@ -753,6 +729,10 @@ int config_parse_tunnel(const char *unit,
                 return 0;
         }
 
+        r = hashmap_ensure_allocated(&network->stacked_netdevs, &string_hash_ops);
+        if (r < 0)
+                return log_oom();
+
         r = hashmap_put(network->stacked_netdevs, netdev->ifname, netdev);
         if (r < 0) {
                 log_syntax(unit, LOG_ERR, filename, line, r, "Cannot add VLAN '%s' to network, ignoring: %m", rvalue);
index 919a2c4b3c4e9a4dd26096565753334639dfb648..5c1fccbc41e346d26e6957478a3c4a61856963cf 100644 (file)
@@ -89,8 +89,8 @@ typedef struct NetworkConfigSection {
 
 int network_config_section_new(const char *filename, unsigned line, NetworkConfigSection **s);
 void network_config_section_free(NetworkConfigSection *network);
-
 DEFINE_TRIVIAL_CLEANUP_FUNC(NetworkConfigSection*, network_config_section_free);
+extern const struct hash_ops network_config_hash_ops;
 
 typedef struct Manager Manager;
 
index d893c1e5d5396d8513d870fbacdde04553aad35d..346d64953b619e79e6f74612d24a20b792ad62af 100644 (file)
@@ -160,8 +160,11 @@ int prefix_new_static(Network *network, const char *filename,
         if (filename) {
                 prefix->section = TAKE_PTR(n);
 
-                r = hashmap_put(network->prefixes_by_section, prefix->section,
-                                prefix);
+                r = hashmap_ensure_allocated(&network->prefixes_by_section, &network_config_hash_ops);
+                if (r < 0)
+                        return r;
+
+                r = hashmap_put(network->prefixes_by_section, prefix->section, prefix);
                 if (r < 0)
                         return r;
         }
index 1e16e4a392129452a441cec36289536c77c4a4b2..f13e12654385216a1c9d86790e8f6be379d7ce76 100644 (file)
@@ -102,6 +102,10 @@ int route_new_static(Network *network, const char *filename, unsigned section_li
         if (filename) {
                 route->section = TAKE_PTR(n);
 
+                r = hashmap_ensure_allocated(&network->routes_by_section, &network_config_hash_ops);
+                if (r < 0)
+                        return r;
+
                 r = hashmap_put(network->routes_by_section, route->section, route);
                 if (r < 0)
                         return r;
index 4750073d28b1ef4e9f4adaab07694ad5d81bc710..683c166289e102d6b61c571e95eb47b5571fc72b 100644 (file)
@@ -412,6 +412,10 @@ static int routing_policy_rule_new_static(Network *network, const char *filename
         if (filename) {
                 rule->section = TAKE_PTR(n);
 
+                r = hashmap_ensure_allocated(&network->rules_by_section, &network_config_hash_ops);
+                if (r < 0)
+                        return r;
+
                 r = hashmap_put(network->rules_by_section, rule->section, rule);
                 if (r < 0)
                         return r;
index abef6e761a30277a172ab5c634bef753ebeb073c..86d4e7e733fa684125f1bd8020e7631aa276fa1e 100644 (file)
@@ -172,7 +172,6 @@ static void test_config_parse_address_one(const char *rvalue, int family, unsign
         _cleanup_(network_freep) Network *network = NULL;
 
         assert_se(network = new0(Network, 1));
-        assert_se(network->addresses_by_section = hashmap_new(NULL));
         assert_se(config_parse_address("network", "filename", 1, "section", 1, "Address", 0, rvalue, network, network) == 0);
         assert_se(network->n_static_addresses == n_addresses);
         if (n_addresses > 0) {