summaryrefslogtreecommitdiff
path: root/src/systemd
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2019-07-04 18:13:17 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2019-07-04 18:13:17 +0200
commit55c47d4efa5969db32499c769d89709ccef80887 (patch)
tree788f7f6c201c74410c9ee6b1aea03437aa5d6736 /src/systemd
parentf61a12ee200de63360b23d3f6c3dad2243e4fb69 (diff)
downloadNetworkManager-55c47d4efa5969db32499c769d89709ccef80887.tar.gz
systemd: update code from upstream (2019-07-04)
This is a direct dump from systemd git. ====== SYSTEMD_DIR=../systemd COMMIT=52d8bcd131e7f3c9b7629412302e1ea46ddb70ca ( cd "$SYSTEMD_DIR" git checkout "$COMMIT" git reset --hard git clean -fdx ) git ls-files -z :/src/systemd/src/ \ :/shared/systemd/src/ \ :/shared/nm-utils/unaligned.h | \ xargs -0 rm -f nm_copy_sd_shared() { mkdir -p "./shared/systemd/$(dirname "$1")" cp "$SYSTEMD_DIR/$1" "./shared/systemd/$1" } nm_copy_sd_core() { mkdir -p "./src/systemd/$(dirname "$1")" cp "$SYSTEMD_DIR/$1" "./src/systemd/$1" } nm_copy_sd_nmutils() { mkdir -p "./shared/nm-utils/" cp "$SYSTEMD_DIR/$1" "./shared/nm-utils/${1##*/}" } nm_copy_sd_core "src/libsystemd-network/arp-util.c" nm_copy_sd_core "src/libsystemd-network/arp-util.h" nm_copy_sd_core "src/libsystemd-network/dhcp-identifier.c" nm_copy_sd_core "src/libsystemd-network/dhcp-identifier.h" nm_copy_sd_core "src/libsystemd-network/dhcp-internal.h" nm_copy_sd_core "src/libsystemd-network/dhcp-lease-internal.h" nm_copy_sd_core "src/libsystemd-network/dhcp-network.c" nm_copy_sd_core "src/libsystemd-network/dhcp-option.c" nm_copy_sd_core "src/libsystemd-network/dhcp-packet.c" nm_copy_sd_core "src/libsystemd-network/dhcp-protocol.h" nm_copy_sd_core "src/libsystemd-network/dhcp6-internal.h" nm_copy_sd_core "src/libsystemd-network/dhcp6-lease-internal.h" nm_copy_sd_core "src/libsystemd-network/dhcp6-network.c" nm_copy_sd_core "src/libsystemd-network/dhcp6-option.c" nm_copy_sd_core "src/libsystemd-network/dhcp6-protocol.h" nm_copy_sd_core "src/libsystemd-network/lldp-internal.h" nm_copy_sd_core "src/libsystemd-network/lldp-neighbor.c" nm_copy_sd_core "src/libsystemd-network/lldp-neighbor.h" nm_copy_sd_core "src/libsystemd-network/lldp-network.c" nm_copy_sd_core "src/libsystemd-network/lldp-network.h" nm_copy_sd_core "src/libsystemd-network/network-internal.c" nm_copy_sd_core "src/libsystemd-network/network-internal.h" nm_copy_sd_core "src/libsystemd-network/sd-dhcp-client.c" nm_copy_sd_core "src/libsystemd-network/sd-dhcp-lease.c" nm_copy_sd_core "src/libsystemd-network/sd-dhcp6-client.c" nm_copy_sd_core "src/libsystemd-network/sd-dhcp6-lease.c" nm_copy_sd_core "src/libsystemd-network/sd-ipv4acd.c" nm_copy_sd_core "src/libsystemd-network/sd-ipv4ll.c" nm_copy_sd_core "src/libsystemd-network/sd-lldp.c" nm_copy_sd_core "src/libsystemd/sd-event/event-source.h" nm_copy_sd_core "src/libsystemd/sd-event/event-util.c" nm_copy_sd_core "src/libsystemd/sd-event/event-util.h" nm_copy_sd_core "src/libsystemd/sd-event/sd-event.c" nm_copy_sd_core "src/libsystemd/sd-id128/id128-util.c" nm_copy_sd_core "src/libsystemd/sd-id128/id128-util.h" nm_copy_sd_core "src/libsystemd/sd-id128/sd-id128.c" nm_copy_sd_core "src/shared/dns-domain.c" nm_copy_sd_core "src/shared/dns-domain.h" nm_copy_sd_core "src/systemd/_sd-common.h" nm_copy_sd_core "src/systemd/sd-dhcp-client.h" nm_copy_sd_core "src/systemd/sd-dhcp-lease.h" nm_copy_sd_core "src/systemd/sd-dhcp6-client.h" nm_copy_sd_core "src/systemd/sd-dhcp6-lease.h" nm_copy_sd_core "src/systemd/sd-event.h" nm_copy_sd_core "src/systemd/sd-id128.h" nm_copy_sd_core "src/systemd/sd-ipv4acd.h" nm_copy_sd_core "src/systemd/sd-ipv4ll.h" nm_copy_sd_core "src/systemd/sd-lldp.h" nm_copy_sd_core "src/systemd/sd-ndisc.h" nm_copy_sd_nmutils "src/basic/unaligned.h" nm_copy_sd_shared "src/basic/alloc-util.c" nm_copy_sd_shared "src/basic/alloc-util.h" nm_copy_sd_shared "src/basic/async.h" nm_copy_sd_shared "src/basic/env-file.c" nm_copy_sd_shared "src/basic/env-file.h" nm_copy_sd_shared "src/basic/env-util.c" nm_copy_sd_shared "src/basic/env-util.h" nm_copy_sd_shared "src/basic/errno-util.h" nm_copy_sd_shared "src/basic/escape.c" nm_copy_sd_shared "src/basic/escape.h" nm_copy_sd_shared "src/basic/ether-addr-util.c" nm_copy_sd_shared "src/basic/ether-addr-util.h" nm_copy_sd_shared "src/basic/extract-word.c" nm_copy_sd_shared "src/basic/extract-word.h" nm_copy_sd_shared "src/basic/fd-util.c" nm_copy_sd_shared "src/basic/fd-util.h" nm_copy_sd_shared "src/basic/fileio.c" nm_copy_sd_shared "src/basic/fileio.h" nm_copy_sd_shared "src/basic/format-util.c" nm_copy_sd_shared "src/basic/format-util.h" nm_copy_sd_shared "src/basic/fs-util.c" nm_copy_sd_shared "src/basic/fs-util.h" nm_copy_sd_shared "src/basic/hash-funcs.c" nm_copy_sd_shared "src/basic/hash-funcs.h" nm_copy_sd_shared "src/basic/hashmap.c" nm_copy_sd_shared "src/basic/hashmap.h" nm_copy_sd_shared "src/basic/hexdecoct.c" nm_copy_sd_shared "src/basic/hexdecoct.h" nm_copy_sd_shared "src/basic/hostname-util.c" nm_copy_sd_shared "src/basic/hostname-util.h" nm_copy_sd_shared "src/basic/in-addr-util.c" nm_copy_sd_shared "src/basic/in-addr-util.h" nm_copy_sd_shared "src/basic/io-util.c" nm_copy_sd_shared "src/basic/io-util.h" nm_copy_sd_shared "src/basic/list.h" nm_copy_sd_shared "src/basic/log.h" nm_copy_sd_shared "src/basic/macro.h" nm_copy_sd_shared "src/basic/memory-util.c" nm_copy_sd_shared "src/basic/memory-util.h" nm_copy_sd_shared "src/basic/mempool.c" nm_copy_sd_shared "src/basic/mempool.h" nm_copy_sd_shared "src/basic/missing_fcntl.h" nm_copy_sd_shared "src/basic/missing_socket.h" nm_copy_sd_shared "src/basic/missing_stat.h" nm_copy_sd_shared "src/basic/missing_type.h" nm_copy_sd_shared "src/basic/parse-util.c" nm_copy_sd_shared "src/basic/parse-util.h" nm_copy_sd_shared "src/basic/path-util.c" nm_copy_sd_shared "src/basic/path-util.h" nm_copy_sd_shared "src/basic/prioq.c" nm_copy_sd_shared "src/basic/prioq.h" nm_copy_sd_shared "src/basic/process-util.c" nm_copy_sd_shared "src/basic/process-util.h" nm_copy_sd_shared "src/basic/random-util.c" nm_copy_sd_shared "src/basic/random-util.h" nm_copy_sd_shared "src/basic/set.h" nm_copy_sd_shared "src/basic/signal-util.h" nm_copy_sd_shared "src/basic/siphash24.h" nm_copy_sd_shared "src/basic/socket-util.c" nm_copy_sd_shared "src/basic/socket-util.h" nm_copy_sd_shared "src/basic/sort-util.h" nm_copy_sd_shared "src/basic/sparse-endian.h" nm_copy_sd_shared "src/basic/stat-util.c" nm_copy_sd_shared "src/basic/stat-util.h" nm_copy_sd_shared "src/basic/stdio-util.h" nm_copy_sd_shared "src/basic/string-table.c" nm_copy_sd_shared "src/basic/string-table.h" nm_copy_sd_shared "src/basic/string-util.c" nm_copy_sd_shared "src/basic/string-util.h" nm_copy_sd_shared "src/basic/strv.c" nm_copy_sd_shared "src/basic/strv.h" nm_copy_sd_shared "src/basic/time-util.c" nm_copy_sd_shared "src/basic/time-util.h" nm_copy_sd_shared "src/basic/tmpfile-util.c" nm_copy_sd_shared "src/basic/tmpfile-util.h" nm_copy_sd_shared "src/basic/umask-util.h" nm_copy_sd_shared "src/basic/utf8.c" nm_copy_sd_shared "src/basic/utf8.h" nm_copy_sd_shared "src/basic/util.c" nm_copy_sd_shared "src/basic/util.h"
Diffstat (limited to 'src/systemd')
-rw-r--r--src/systemd/src/libsystemd-network/dhcp-identifier.c2
-rw-r--r--src/systemd/src/libsystemd-network/dhcp-option.c2
-rw-r--r--src/systemd/src/libsystemd-network/network-internal.c251
-rw-r--r--src/systemd/src/libsystemd-network/network-internal.h13
-rw-r--r--src/systemd/src/libsystemd-network/sd-dhcp-client.c25
-rw-r--r--src/systemd/src/libsystemd-network/sd-dhcp-lease.c2
6 files changed, 247 insertions, 48 deletions
diff --git a/src/systemd/src/libsystemd-network/dhcp-identifier.c b/src/systemd/src/libsystemd-network/dhcp-identifier.c
index 0c1ff34e5d..c01c1cf6d6 100644
--- a/src/systemd/src/libsystemd-network/dhcp-identifier.c
+++ b/src/systemd/src/libsystemd-network/dhcp-identifier.c
@@ -190,7 +190,7 @@ int dhcp_identifier_set_iaid(
/* device is under renaming */
return -EBUSY;
- name = net_get_name(device);
+ name = net_get_name_persistent(device);
}
}
diff --git a/src/systemd/src/libsystemd-network/dhcp-option.c b/src/systemd/src/libsystemd-network/dhcp-option.c
index a68de4ff98..0abb8fdef0 100644
--- a/src/systemd/src/libsystemd-network/dhcp-option.c
+++ b/src/systemd/src/libsystemd-network/dhcp-option.c
@@ -198,7 +198,7 @@ static int parse_options(const uint8_t options[], size_t buflen, uint8_t *overlo
if (memchr(option, 0, len - 1))
return -EINVAL;
- string = strndup((const char *) option, len);
+ string = memdup_suffix0((const char *) option, len);
if (!string)
return -ENOMEM;
diff --git a/src/systemd/src/libsystemd-network/network-internal.c b/src/systemd/src/libsystemd-network/network-internal.c
index a112b9f70f..1f2e5c7e65 100644
--- a/src/systemd/src/libsystemd-network/network-internal.c
+++ b/src/systemd/src/libsystemd-network/network-internal.c
@@ -12,6 +12,7 @@
#include "conf-parser.h"
#include "device-util.h"
#include "dhcp-lease-internal.h"
+#include "env-util.h"
#include "ether-addr-util.h"
#include "hexdecoct.h"
#include "log.h"
@@ -24,7 +25,7 @@
#include "utf8.h"
#include "util.h"
-const char *net_get_name(sd_device *device) {
+const char *net_get_name_persistent(sd_device *device) {
const char *name, *field;
assert(device);
@@ -39,7 +40,7 @@ const char *net_get_name(sd_device *device) {
#define HASH_KEY SD_ID128_MAKE(d3,1e,48,fa,90,fe,4b,4c,9d,af,d5,d7,a1,b1,2e,8a)
-int net_get_unique_predictable_data(sd_device *device, uint64_t *result) {
+int net_get_unique_predictable_data(sd_device *device, bool use_sysname, uint64_t *result) {
size_t l, sz = 0;
const char *name;
int r;
@@ -47,10 +48,10 @@ int net_get_unique_predictable_data(sd_device *device, uint64_t *result) {
assert(device);
- /* net_get_name() will return one of the device names based on stable information about the
- * device. If this is not available, we fall back to using the device name. */
- name = net_get_name(device);
- if (!name)
+ /* net_get_name_persistent() will return one of the device names based on stable information about
+ * the device. If this is not available, we fall back to using the actual device name. */
+ name = net_get_name_persistent(device);
+ if (!name && use_sysname)
(void) sd_device_get_sysname(device, &name);
if (!name)
return log_device_debug_errno(device, SYNTHETIC_ERRNO(ENODATA),
@@ -73,26 +74,66 @@ int net_get_unique_predictable_data(sd_device *device, uint64_t *result) {
return 0;
}
-static bool net_condition_test_strv(char * const *raw_patterns,
- const char *string) {
- if (strv_isempty(raw_patterns))
+static bool net_condition_test_strv(char * const *patterns, const char *string) {
+ char * const *p;
+ bool match = false, has_positive_rule = false;
+
+ if (strv_isempty(patterns))
return true;
- /* If the patterns begin with "!", edit it out and negate the test. */
- if (raw_patterns[0][0] == '!') {
- char **patterns;
- size_t i, length;
+ STRV_FOREACH(p, patterns) {
+ const char *q = *p;
+ bool invert;
+
+ invert = *q == '!';
+ q += invert;
+
+ if (!invert)
+ has_positive_rule = true;
+
+ if (string && fnmatch(q, string, 0) == 0) {
+ if (invert)
+ return false;
+ else
+ match = true;
+ }
+ }
+
+ return has_positive_rule ? match : true;
+}
+
+static int net_condition_test_property(char * const *match_property, sd_device *device) {
+ char * const *p;
+
+ if (strv_isempty(match_property))
+ return true;
+
+ STRV_FOREACH(p, match_property) {
+ _cleanup_free_ char *key = NULL;
+ const char *val, *dev_val;
+ bool invert, v;
+
+ invert = **p == '!';
+
+ val = strchr(*p + invert, '=');
+ if (!val)
+ return -EINVAL;
- length = strv_length(raw_patterns) + 1; /* Include the NULL. */
- patterns = newa(char*, length);
- patterns[0] = raw_patterns[0] + 1; /* Skip the "!". */
- for (i = 1; i < length; i++)
- patterns[i] = raw_patterns[i];
+ key = strndup(*p + invert, val - *p - invert);
+ if (!key)
+ return -ENOMEM;
+
+ val++;
- return !string || !strv_fnmatch(patterns, string, 0);
+ v = device &&
+ sd_device_get_property_value(device, key, &dev_val) >= 0 &&
+ fnmatch(val, dev_val, 0) == 0;
+
+ if (invert ? v : !v)
+ return false;
}
- return string && strv_fnmatch(raw_patterns, string, 0);
+ return true;
}
bool net_match_config(Set *match_mac,
@@ -100,12 +141,25 @@ bool net_match_config(Set *match_mac,
char * const *match_drivers,
char * const *match_types,
char * const *match_names,
+ char * const *match_property,
+ sd_device *device,
const struct ether_addr *dev_mac,
- const char *dev_path,
- const char *dev_driver,
- const char *dev_type,
const char *dev_name) {
+ const char *dev_path = NULL, *dev_driver = NULL, *dev_type = NULL, *mac_str;
+
+ if (device) {
+ (void) sd_device_get_property_value(device, "ID_PATH", &dev_path);
+ (void) sd_device_get_property_value(device, "ID_NET_DRIVER", &dev_driver);
+ (void) sd_device_get_devtype(device, &dev_type);
+
+ if (!dev_name)
+ (void) sd_device_get_sysname(device, &dev_name);
+ if (!dev_mac &&
+ sd_device_get_sysattr_value(device, "address", &mac_str) >= 0)
+ dev_mac = ether_aton(mac_str);
+ }
+
if (match_mac && (!dev_mac || !set_contains(match_mac, dev_mac)))
return false;
@@ -121,6 +175,9 @@ bool net_match_config(Set *match_mac,
if (!net_condition_test_strv(match_names, dev_name))
return false;
+ if (!net_condition_test_property(match_property, device))
+ return false;
+
return true;
}
@@ -164,7 +221,7 @@ int config_parse_net_condition(const char *unit,
return 0;
}
-int config_parse_ifnames(
+int config_parse_match_strv(
const char *unit,
const char *filename,
unsigned line,
@@ -176,7 +233,9 @@ int config_parse_ifnames(
void *data,
void *userdata) {
+ const char *p = rvalue;
char ***sv = data;
+ bool invert;
int r;
assert(filename);
@@ -184,30 +243,154 @@ int config_parse_ifnames(
assert(rvalue);
assert(data);
+ if (isempty(rvalue)) {
+ *sv = strv_free(*sv);
+ return 0;
+ }
+
+ invert = *p == '!';
+ p += invert;
+
for (;;) {
- _cleanup_free_ char *word = NULL;
+ _cleanup_free_ char *word = NULL, *k = NULL;
- r = extract_first_word(&rvalue, &word, NULL, 0);
+ r = extract_first_word(&p, &word, NULL, EXTRACT_UNQUOTE|EXTRACT_RETAIN_ESCAPE);
+ if (r == 0)
+ return 0;
+ if (r == -ENOMEM)
+ return log_oom();
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse interface name list: %s", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Invalid syntax, ignoring: %s", rvalue);
return 0;
}
+
+ if (invert) {
+ k = strjoin("!", word);
+ if (!k)
+ return log_oom();
+ } else
+ k = TAKE_PTR(word);
+
+ r = strv_consume(sv, TAKE_PTR(k));
+ if (r < 0)
+ return log_oom();
+ }
+}
+
+int config_parse_match_ifnames(
+ 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) {
+
+ const char *p = rvalue;
+ char ***sv = data;
+ bool invert;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ invert = *p == '!';
+ p += invert;
+
+ for (;;) {
+ _cleanup_free_ char *word = NULL, *k = NULL;
+
+ r = extract_first_word(&p, &word, NULL, 0);
if (r == 0)
- break;
+ return 0;
+ if (r == -ENOMEM)
+ return log_oom();
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Failed to parse interface name list: %s", rvalue);
+ return 0;
+ }
if (!ifname_valid(word)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Interface name is not valid or too long, ignoring assignment: %s", rvalue);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Interface name is not valid or too long, ignoring assignment: %s", word);
+ continue;
}
- r = strv_push(sv, word);
+ if (invert) {
+ k = strjoin("!", word);
+ if (!k)
+ return log_oom();
+ } else
+ k = TAKE_PTR(word);
+
+ r = strv_consume(sv, TAKE_PTR(k));
if (r < 0)
return log_oom();
-
- word = NULL;
}
+}
- return 0;
+int config_parse_match_property(
+ 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) {
+
+ const char *p = rvalue;
+ char ***sv = data;
+ bool invert;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ invert = *p == '!';
+ p += invert;
+
+ for (;;) {
+ _cleanup_free_ char *word = NULL, *k = NULL;
+
+ r = extract_first_word(&p, &word, NULL, EXTRACT_CUNESCAPE|EXTRACT_UNQUOTE);
+ if (r == 0)
+ return 0;
+ if (r == -ENOMEM)
+ return log_oom();
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Invalid syntax, ignoring: %s", rvalue);
+ return 0;
+ }
+
+ if (!env_assignment_is_valid(word)) {
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Invalid property or value, ignoring assignment: %s", word);
+ continue;
+ }
+
+ if (invert) {
+ k = strjoin("!", word);
+ if (!k)
+ return log_oom();
+ } else
+ k = TAKE_PTR(word);
+
+ r = strv_consume(sv, TAKE_PTR(k));
+ if (r < 0)
+ return log_oom();
+ }
}
int config_parse_ifalias(const char *unit,
diff --git a/src/systemd/src/libsystemd-network/network-internal.h b/src/systemd/src/libsystemd-network/network-internal.h
index 62f5a4a76c..7059c8ae45 100644
--- a/src/systemd/src/libsystemd-network/network-internal.h
+++ b/src/systemd/src/libsystemd-network/network-internal.h
@@ -19,21 +19,22 @@ bool net_match_config(Set *match_mac,
char * const *match_driver,
char * const *match_type,
char * const *match_name,
+ char * const *match_property,
+ sd_device *device,
const struct ether_addr *dev_mac,
- const char *dev_path,
- const char *dev_driver,
- const char *dev_type,
const char *dev_name);
CONFIG_PARSER_PROTOTYPE(config_parse_net_condition);
CONFIG_PARSER_PROTOTYPE(config_parse_hwaddr);
CONFIG_PARSER_PROTOTYPE(config_parse_hwaddrs);
-CONFIG_PARSER_PROTOTYPE(config_parse_ifnames);
+CONFIG_PARSER_PROTOTYPE(config_parse_match_strv);
+CONFIG_PARSER_PROTOTYPE(config_parse_match_ifnames);
+CONFIG_PARSER_PROTOTYPE(config_parse_match_property);
CONFIG_PARSER_PROTOTYPE(config_parse_ifalias);
CONFIG_PARSER_PROTOTYPE(config_parse_bridge_port_priority);
-int net_get_unique_predictable_data(sd_device *device, uint64_t *result);
-const char *net_get_name(sd_device *device);
+int net_get_unique_predictable_data(sd_device *device, bool use_sysname, uint64_t *result);
+const char *net_get_name_persistent(sd_device *device);
size_t serialize_in_addrs(FILE *f,
const struct in_addr *addresses,
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-client.c b/src/systemd/src/libsystemd-network/sd-dhcp-client.c
index 6e077c0860..b0f0f84937 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp-client.c
@@ -1385,6 +1385,23 @@ static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force,
return 0;
}
+static bool lease_equal(const sd_dhcp_lease *a, const sd_dhcp_lease *b) {
+ if (a->address != b->address)
+ return false;
+
+ if (a->subnet_mask != b->subnet_mask)
+ return false;
+
+ if (a->router_size != b->router_size)
+ return false;
+
+ for (size_t i = 0; i < a->router_size; i++)
+ if (a->router[i].s_addr != b->router[i].s_addr)
+ return false;
+
+ return true;
+}
+
static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack, size_t len) {
_cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL;
_cleanup_free_ char *error_message = NULL;
@@ -1437,12 +1454,10 @@ static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack, size_t le
r = SD_DHCP_CLIENT_EVENT_IP_ACQUIRE;
if (client->lease) {
- if (client->lease->address != lease->address ||
- client->lease->subnet_mask != lease->subnet_mask ||
- client->lease->router != lease->router) {
- r = SD_DHCP_CLIENT_EVENT_IP_CHANGE;
- } else
+ if (lease_equal(client->lease, lease))
r = SD_DHCP_CLIENT_EVENT_RENEW;
+ else
+ r = SD_DHCP_CLIENT_EVENT_IP_CHANGE;
client->lease = sd_dhcp_lease_unref(client->lease);
}
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-lease.c b/src/systemd/src/libsystemd-network/sd-dhcp-lease.c
index c089b4278b..17b2bb7aa4 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp-lease.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp-lease.c
@@ -333,7 +333,7 @@ static int lease_parse_string(const uint8_t *option, size_t len, char **ret) {
if (memchr(option, 0, len - 1))
return -EINVAL;
- string = strndup((const char *) option, len);
+ string = memdup_suffix0((const char *) option, len);
if (!string)
return -ENOMEM;