summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Gundersen <teg@jklm.no>2015-09-24 01:22:05 +0200
committerTom Gundersen <teg@jklm.no>2015-10-11 15:04:16 +0200
commit054f0db48775d566e4f55feb7cda0f721a9eb485 (patch)
tree9ca1fdb3320ff1690c1e72ff0965ab64f175bcfc
parentcf1d700da3fe04cd4c27980a292301694be3b05f (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.c17
-rw-r--r--src/network/networkd-address.h2
-rw-r--r--src/network/networkd-manager.c69
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: