From 057abfd88a827a3674bd77dab61927e9a031ecb8 Mon Sep 17 00:00:00 2001 From: Patrik Flykt Date: Fri, 12 May 2017 16:48:28 +0300 Subject: [PATCH] networkd: Add initial prefix handling for network configuration 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 | 80 ++++++++++++++++++++++++++++++++++++++++++ src/network/networkd-address.h | 16 +++++++++ src/network/networkd-network.c | 10 ++++++ src/network/networkd-network.h | 3 ++ 4 files changed, 109 insertions(+) diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index 2e6c763..dba394b 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -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; +} diff --git a/src/network/networkd-address.h b/src/network/networkd-address.h index 71a07ea..fb79f7a 100644 --- a/src/network/networkd-address.h +++ b/src/network/networkd-address.h @@ -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); diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 3c26c86..43f62e2 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -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) diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index c9326c7..a9d547b 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -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; -- 2.7.4