diff options
author | Tom Gundersen <teg@jklm.no> | 2015-09-24 01:22:05 +0200 |
---|---|---|
committer | Tom Gundersen <teg@jklm.no> | 2015-10-11 15:04:16 +0200 |
commit | 054f0db48775d566e4f55feb7cda0f721a9eb485 (patch) | |
tree | 9ca1fdb3320ff1690c1e72ff0965ab64f175bcfc | |
parent | cf1d700da3fe04cd4c27980a292301694be3b05f (diff) |
networkd: manager - avoid unnecessary memory allocation
Don't allocate Address objects only to free them again when processing
rtnl events.
-rw-r--r-- | src/network/networkd-address.c | 17 | ||||
-rw-r--r-- | src/network/networkd-address.h | 2 | ||||
-rw-r--r-- | src/network/networkd-manager.c | 69 |
3 files changed, 50 insertions, 38 deletions
diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index 9600b957fe..0414ced48a 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -198,11 +198,21 @@ bool address_equal(Address *a1, Address *a2) { return address_compare_func(a1, a2) == 0; } -int address_add(Link *link, Address *address) { +int address_add(Link *link, int family, const union in_addr_union *in_addr, unsigned char prefixlen, Address **ret) { + _cleanup_address_free_ Address *address = NULL; int r; assert(link); - assert(address); + assert(in_addr); + assert(ret); + + r = address_new(&address); + if (r < 0) + return r; + + address->family = family; + address->in_addr = *in_addr; + address->prefixlen = prefixlen; r = set_ensure_allocated(&link->addresses, &address_hash_ops); if (r < 0) @@ -214,6 +224,9 @@ int address_add(Link *link, Address *address) { address->link = link; + *ret = address; + address = NULL; + return 0; } diff --git a/src/network/networkd-address.h b/src/network/networkd-address.h index 0b5be02288..0d575de131 100644 --- a/src/network/networkd-address.h +++ b/src/network/networkd-address.h @@ -60,7 +60,7 @@ struct Address { int address_new_static(Network *network, unsigned section, Address **ret); int address_new(Address **ret); void address_free(Address *address); -int address_add(Link *link, Address *address); +int address_add(Link *link, int family, const union in_addr_union *in_addr, unsigned char prefixlen, Address **ret); int address_get(Link *link, int family, const union in_addr_union *in_addr, unsigned char prefixlen, Address **ret); int address_configure(Address *address, Link *link, sd_netlink_message_handler_t callback); int address_update(Address *address, Link *link, sd_netlink_message_handler_t callback); diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 30cb502bed..19527b6509 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -281,9 +281,13 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, Manager *m = userdata; Link *link = NULL; uint16_t type; - _cleanup_address_free_ Address *address = NULL; unsigned char flags; - Address *existing = NULL; + int family; + unsigned char prefixlen; + unsigned char scope; + union in_addr_union in_addr; + struct ifa_cacheinfo cinfo; + Address *address = NULL; char buf[INET6_ADDRSTRLEN], valid_buf[FORMAT_TIMESPAN_MAX]; const char *valid_str = NULL; int r, ifindex; @@ -327,23 +331,19 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, } } - r = address_new(&address); - if (r < 0) - return r; - - r = sd_rtnl_message_addr_get_family(message, &address->family); - if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) { + r = sd_rtnl_message_addr_get_family(message, &family); + if (r < 0 || !IN_SET(family, AF_INET, AF_INET6)) { log_link_warning(link, "rtnl: received address with invalid family, ignoring."); return 0; } - r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen); + r = sd_rtnl_message_addr_get_prefixlen(message, &prefixlen); if (r < 0) { log_link_warning_errno(link, r, "rtnl: received address with invalid prefixlen, ignoring: %m"); return 0; } - r = sd_rtnl_message_addr_get_scope(message, &address->scope); + r = sd_rtnl_message_addr_get_scope(message, &scope); if (r < 0) { log_link_warning_errno(link, r, "rtnl: received address with invalid scope, ignoring: %m"); return 0; @@ -354,11 +354,10 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, log_link_warning_errno(link, r, "rtnl: received address with invalid flags, ignoring: %m"); return 0; } - address->flags = flags; - switch (address->family) { + switch (family) { case AF_INET: - r = sd_netlink_message_read_in_addr(message, IFA_LOCAL, &address->in_addr.in); + r = sd_netlink_message_read_in_addr(message, IFA_LOCAL, &in_addr.in); if (r < 0) { log_link_warning_errno(link, r, "rtnl: received address without valid address, ignoring: %m"); return 0; @@ -367,7 +366,7 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, break; case AF_INET6: - r = sd_netlink_message_read_in6_addr(message, IFA_ADDRESS, &address->in_addr.in6); + r = sd_netlink_message_read_in6_addr(message, IFA_ADDRESS, &in_addr.in6); if (r < 0) { log_link_warning_errno(link, r, "rtnl: received address without valid address, ignoring: %m"); return 0; @@ -379,46 +378,46 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, assert_not_reached("invalid address family"); } - if (!inet_ntop(address->family, &address->in_addr, buf, INET6_ADDRSTRLEN)) { + if (!inet_ntop(family, &in_addr, buf, INET6_ADDRSTRLEN)) { log_link_warning(link, "Could not print address"); return 0; } - r = sd_netlink_message_read_cache_info(message, IFA_CACHEINFO, &address->cinfo); + r = sd_netlink_message_read_cache_info(message, IFA_CACHEINFO, &cinfo); if (r >= 0) { - if (address->cinfo.ifa_valid == CACHE_INFO_INFINITY_LIFE_TIME) + if (cinfo.ifa_valid == CACHE_INFO_INFINITY_LIFE_TIME) valid_str = "ever"; else valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX, - address->cinfo.ifa_valid * USEC_PER_SEC, + cinfo.ifa_valid * USEC_PER_SEC, USEC_PER_SEC); } - address_get(link, address->family, &address->in_addr, address->prefixlen, &existing); + address_get(link, family, &in_addr, prefixlen, &address); switch (type) { case RTM_NEWADDR: - if (existing) { - log_link_debug(link, "Updating address: %s/%u (valid for %s)", buf, address->prefixlen, valid_str); + if (address) { + log_link_debug(link, "Updating address: %s/%u (valid for %s)", buf, prefixlen, valid_str); - - existing->scope = address->scope; - existing->flags = address->flags; - existing->cinfo = address->cinfo; + address->scope = scope; + address->flags = flags; + address->cinfo = cinfo; } else { - r = address_add(link, address); + r = address_add(link, family, &in_addr, prefixlen, &address); if (r < 0) { - log_link_warning_errno(link, r, "Failed to add address %s/%u: %m", buf, address->prefixlen); + log_link_warning_errno(link, r, "Failed to add address %s/%u: %m", buf, prefixlen); return 0; } else - log_link_debug(link, "Adding address: %s/%u (valid for %s)", buf, address->prefixlen, valid_str); + log_link_debug(link, "Adding address: %s/%u (valid for %s)", buf, prefixlen, valid_str); + address->scope = scope; + address->flags = flags; + address->cinfo = cinfo; address_establish(address, link); - address = NULL; - link_save(link); } @@ -426,12 +425,12 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, case RTM_DELADDR: - if (existing) { - log_link_debug(link, "Removing address: %s/%u (valid for %s)", buf, address->prefixlen, valid_str); - address_release(existing, link); - address_free(existing); + if (address) { + log_link_debug(link, "Removing address: %s/%u (valid for %s)", buf, prefixlen, valid_str); + address_release(address, link); + address_free(address); } else - log_link_warning(link, "Removing non-existent address: %s/%u (valid for %s)", buf, address->prefixlen, valid_str); + log_link_warning(link, "Removing non-existent address: %s/%u (valid for %s)", buf, prefixlen, valid_str); break; default: |