Add initial code for handling prefixes in network configuration files.
Add hash map and list storing the information in systemd-networkd.
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;
+}
#include "in-addr-util.h"
typedef struct Address Address;
+typedef struct Prefix Prefix;
#include "networkd-link.h"
#include "networkd-network.h"
typedef struct Link Link;
typedef struct NetworkConfigSection NetworkConfigSection;
+struct Prefix {
+ Network *network;
+ NetworkConfigSection *section;
+
+ LIST_FIELDS(Prefix, prefixes);
+};
+
struct Address {
Network *network;
NetworkConfigSection *section;
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);
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)
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);
FdbEntry *fdb_entry;
IPv6ProxyNDPAddress *ipv6_proxy_ndp_address;
AddressLabel *label;
+ Prefix *prefix;
Iterator i;
if (!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)
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;