networkd: Add initial prefix handling for network configuration
authorPatrik Flykt <patrik.flykt@linux.intel.com>
Fri, 12 May 2017 13:48:28 +0000 (16:48 +0300)
committerPatrik Flykt <patrik.flykt@linux.intel.com>
Mon, 15 May 2017 11:49:50 +0000 (14:49 +0300)
Add initial code for handling prefixes in network configuration files.
Add hash map and list storing the information in systemd-networkd.

src/network/networkd-address.c
src/network/networkd-address.h
src/network/networkd-network.c
src/network/networkd-network.h

index 2e6c763..dba394b 100644 (file)
@@ -932,3 +932,83 @@ bool address_is_ready(const Address *a) {
 
         return !(a->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED));
 }
+
+void prefix_free(Prefix *prefix) {
+        if (!prefix)
+                return;
+
+        if (prefix->network) {
+                LIST_REMOVE(prefixes, prefix->network->static_prefixes, prefix);
+                assert(prefix->network->n_static_prefixes > 0);
+                prefix->network->n_static_prefixes--;
+
+                if (prefix->section)
+                        hashmap_remove(prefix->network->prefixes_by_section,
+                                       prefix->section);
+        }
+
+        free(prefix);
+}
+
+int prefix_new(Prefix **ret) {
+        Prefix *prefix = NULL;
+
+        prefix = new0(Prefix, 1);
+        if (!prefix)
+                return -ENOMEM;
+
+        *ret = prefix;
+        prefix = NULL;
+
+        return 0;
+}
+
+int prefix_new_static(Network *network, const char *filename,
+                      unsigned section_line, Prefix **ret) {
+        _cleanup_network_config_section_free_ NetworkConfigSection *n = NULL;
+        _cleanup_prefix_free_ Prefix *prefix = NULL;
+        int r;
+
+        assert(network);
+        assert(ret);
+        assert(!!filename == (section_line > 0));
+
+        if (filename) {
+                r = network_config_section_new(filename, section_line, &n);
+                if (r < 0)
+                        return r;
+
+                if (section_line) {
+                        prefix = hashmap_get(network->prefixes_by_section, n);
+                        if (prefix) {
+                                *ret = prefix;
+                                prefix = NULL;
+
+                                return 0;
+                        }
+                }
+        }
+
+        r = prefix_new(&prefix);
+        if (r < 0)
+                return r;
+
+        if (filename) {
+                prefix->section = n;
+                n = NULL;
+
+                r = hashmap_put(network->prefixes_by_section, prefix->section,
+                                prefix);
+                if (r < 0)
+                        return r;
+        }
+
+        prefix->network = network;
+        LIST_APPEND(prefixes, network->static_prefixes, prefix);
+        network->n_static_prefixes++;
+
+        *ret = prefix;
+        prefix = NULL;
+
+        return 0;
+}
index 71a07ea..fb79f7a 100644 (file)
@@ -25,6 +25,7 @@
 #include "in-addr-util.h"
 
 typedef struct Address Address;
+typedef struct Prefix Prefix;
 
 #include "networkd-link.h"
 #include "networkd-network.h"
@@ -35,6 +36,13 @@ typedef struct Network Network;
 typedef struct Link Link;
 typedef struct NetworkConfigSection NetworkConfigSection;
 
+struct Prefix {
+        Network *network;
+        NetworkConfigSection *section;
+
+        LIST_FIELDS(Prefix, prefixes);
+};
+
 struct Address {
         Network *network;
         NetworkConfigSection *section;
@@ -79,6 +87,14 @@ bool address_is_ready(const Address *a);
 DEFINE_TRIVIAL_CLEANUP_FUNC(Address*, address_free);
 #define _cleanup_address_free_ _cleanup_(address_freep)
 
+int prefix_new(Prefix **ret);
+void prefix_free(Prefix *prefix);
+int prefix_new_static(Network *network, const char *filename, unsigned section,
+                      Prefix **ret);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(Prefix*, prefix_free);
+#define _cleanup_prefix_free_ _cleanup_(prefix_freep)
+
 int config_parse_address(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_broadcast(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_label(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
index 3c26c86..43f62e2 100644 (file)
@@ -115,6 +115,7 @@ static int network_load_one(Manager *manager, const char *filename) {
         LIST_HEAD_INIT(network->static_fdb_entries);
         LIST_HEAD_INIT(network->ipv6_proxy_ndp_addresses);
         LIST_HEAD_INIT(network->address_labels);
+        LIST_HEAD_INIT(network->static_prefixes);
 
         network->stacked_netdevs = hashmap_new(&string_hash_ops);
         if (!network->stacked_netdevs)
@@ -134,6 +135,10 @@ static int network_load_one(Manager *manager, const char *filename) {
 
         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->filename = strdup(filename);
@@ -279,6 +284,7 @@ void network_free(Network *network) {
         FdbEntry *fdb_entry;
         IPv6ProxyNDPAddress *ipv6_proxy_ndp_address;
         AddressLabel *label;
+        Prefix *prefix;
         Iterator i;
 
         if (!network)
@@ -329,10 +335,14 @@ void network_free(Network *network) {
         while ((label = network->address_labels))
                 address_label_free(label);
 
+        while ((prefix = network->static_prefixes))
+                prefix_free(prefix);
+
         hashmap_free(network->addresses_by_section);
         hashmap_free(network->routes_by_section);
         hashmap_free(network->fdb_entries_by_section);
         hashmap_free(network->address_labels_by_section);
+        hashmap_free(network->prefixes_by_section);
 
         if (network->manager) {
                 if (network->manager->networks)
index c9326c7..a9d547b 100644 (file)
@@ -205,17 +205,20 @@ struct Network {
         LIST_HEAD(FdbEntry, static_fdb_entries);
         LIST_HEAD(IPv6ProxyNDPAddress, ipv6_proxy_ndp_addresses);
         LIST_HEAD(AddressLabel, address_labels);
+        LIST_HEAD(Prefix, static_prefixes);
 
         unsigned n_static_addresses;
         unsigned n_static_routes;
         unsigned n_static_fdb_entries;
         unsigned n_ipv6_proxy_ndp_addresses;
         unsigned n_address_labels;
+        unsigned n_static_prefixes;
 
         Hashmap *addresses_by_section;
         Hashmap *routes_by_section;
         Hashmap *fdb_entries_by_section;
         Hashmap *address_labels_by_section;
+        Hashmap *prefixes_by_section;
 
         struct in_addr_data *dns;
         unsigned n_dns;