X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fnetwork%2Fnetworkd-address.c;h=0555d317a40549f86cbf501a11601ac1705be2c5;hp=0e582d626cebad8e2cbf6ab39e40bdc90d4ae1c6;hb=c166a070553511e402de5ad216d3fb62b49bdacb;hpb=71a6151083d842b2f5bf04e50239f0bf85d34d2e diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index 0e582d626..0555d317a 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -28,9 +28,20 @@ #include "conf-parser.h" #include "net-util.h" -int address_new(Network *network, Address **ret) { +int address_new(Network *network, unsigned section, Address **ret) { _cleanup_address_free_ Address *address = NULL; + if (section) { + uint64_t key = section; + address = hashmap_get(network->addresses_by_section, &key); + if (address) { + *ret = address; + address = NULL; + + return 0; + } + } + address = new0(Address, 1); if (!address) return -ENOMEM; @@ -39,6 +50,11 @@ int address_new(Network *network, Address **ret) { LIST_PREPEND(addresses, network->addresses, address); + if (section) { + address->section = section; + hashmap_put(network->addresses_by_section, &address->section, address); + } + *ret = address; address = NULL; @@ -51,7 +67,10 @@ void address_free(Address *address) { LIST_REMOVE(addresses, address->network->addresses, address); - free(address->label); + if (address->section) + hashmap_remove(address->network->addresses_by_section, + &address->section); + free(address); } @@ -60,7 +79,12 @@ int address_configure(Address *address, Link *link, _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req = NULL; int r; + assert(address); + assert(address->family == AF_INET || address->family == AF_INET6); + assert(link); + assert(link->ifindex > 0); assert(link->manager); + assert(link->manager->rtnl); r = sd_rtnl_message_addr_new(RTM_NEWADDR, link->ifindex, address->family, address->prefixlen, @@ -106,8 +130,6 @@ int address_configure(Address *address, Link *link, return r; } - link->rtnl_messages ++; - return 0; } @@ -121,17 +143,19 @@ int config_parse_address(const char *unit, const char *rvalue, void *data, void *userdata) { + Network *network = userdata; _cleanup_address_free_ Address *n = NULL; _cleanup_free_ char *address = NULL; const char *e; int r; assert(filename); + assert(section); assert(lvalue); assert(rvalue); assert(data); - r = address_new(userdata, &n); + r = address_new(network, section_line, &n); if (r < 0) return r; @@ -172,3 +196,53 @@ int config_parse_address(const char *unit, return 0; } + +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) { + Network *network = userdata; + _cleanup_address_free_ Address *n = NULL; + char *label; + int r; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + assert(data); + + r = address_new(network, section_line, &n); + if (r < 0) + return r; + + label = strdup(rvalue); + if (!label) + return log_oom(); + + if (!ascii_is_valid(label) || strlen(label) >= IFNAMSIZ) { + log_syntax(unit, LOG_ERR, filename, line, EINVAL, + "Interface label is not ASCII clean or is too" + " long, ignoring assignment: %s", rvalue); + free(label); + return 0; + } + + free(n->label); + if (*label) + n->label = label; + else { + free(label); + n->label = NULL; + } + + n = NULL; + + return 0; +}