summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2019-02-20 17:59:37 +0100
committerBeniamino Galvani <bgalvani@redhat.com>2019-02-20 19:18:52 +0100
commit787a18c467c41d1e5bd8ec05af4afc29df63ea3d (patch)
tree4c94970e5902190d11d3cceda53ca6693b226a92
parent209ff015e26f295bdb7c396962a4e9b4199398fb (diff)
parent62e6df1f1cd2b3588086dabd38172a30d1253901 (diff)
downloadNetworkManager-bg/systemd.tar.gz
systemd: merge branch systemd into masterbg/systemd
-rw-r--r--Makefile.am1
-rw-r--r--shared/systemd/src/basic/fileio.c4
-rw-r--r--shared/systemd/src/basic/hashmap.c5
-rw-r--r--shared/systemd/src/basic/hexdecoct.c7
-rw-r--r--shared/systemd/src/basic/time-util.c9
-rw-r--r--shared/systemd/src/basic/time-util.h1
-rw-r--r--shared/systemd/src/basic/util.h9
-rw-r--r--src/systemd/sd-adapt-core/device-util.h3
-rw-r--r--src/systemd/src/libsystemd-network/dhcp-network.c11
-rw-r--r--src/systemd/src/libsystemd-network/network-internal.c20
-rw-r--r--src/systemd/src/libsystemd-network/network-internal.h5
-rw-r--r--src/systemd/src/libsystemd-network/sd-dhcp-client.c24
-rw-r--r--src/systemd/src/libsystemd-network/sd-dhcp6-client.c9
13 files changed, 78 insertions, 30 deletions
diff --git a/Makefile.am b/Makefile.am
index b6602346c8..bbbb37de87 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1701,6 +1701,7 @@ src_libnm_systemd_core_la_SOURCES = \
src/systemd/nm-sd.h \
src/systemd/sd-adapt-core/condition.h \
src/systemd/sd-adapt-core/conf-parser.h \
+ src/systemd/sd-adapt-core/device-util.h \
src/systemd/sd-adapt-core/khash.h \
src/systemd/sd-adapt-core/nm-sd-adapt-core.c \
src/systemd/sd-adapt-core/nm-sd-adapt-core.h \
diff --git a/shared/systemd/src/basic/fileio.c b/shared/systemd/src/basic/fileio.c
index b172507b79..ee66190f72 100644
--- a/shared/systemd/src/basic/fileio.c
+++ b/shared/systemd/src/basic/fileio.c
@@ -215,7 +215,6 @@ int write_string_filef(
int read_one_line_file(const char *fn, char **line) {
_cleanup_fclose_ FILE *f = NULL;
- int r;
assert(fn);
assert(line);
@@ -226,8 +225,7 @@ int read_one_line_file(const char *fn, char **line) {
(void) __fsetlocking(f, FSETLOCKING_BYCALLER);
- r = read_line(f, LONG_LINE_MAX, line);
- return r < 0 ? r : 0;
+ return read_line(f, LONG_LINE_MAX, line);
}
int verify_file(const char *fn, const char *blob, bool accept_extra_nl) {
diff --git a/shared/systemd/src/basic/hashmap.c b/shared/systemd/src/basic/hashmap.c
index 9cb2f94865..c06558316e 100644
--- a/shared/systemd/src/basic/hashmap.c
+++ b/shared/systemd/src/basic/hashmap.c
@@ -1518,8 +1518,11 @@ void *internal_hashmap_first_key_and_value(HashmapBase *h, bool remove, void **r
unsigned idx;
idx = find_first_entry(h);
- if (idx == IDX_NIL)
+ if (idx == IDX_NIL) {
+ if (ret_key)
+ *ret_key = NULL;
return NULL;
+ }
e = bucket_at(h, idx);
key = (void*) e->key;
diff --git a/shared/systemd/src/basic/hexdecoct.c b/shared/systemd/src/basic/hexdecoct.c
index ffd9a8f60f..7c66cc6285 100644
--- a/shared/systemd/src/basic/hexdecoct.c
+++ b/shared/systemd/src/basic/hexdecoct.c
@@ -606,10 +606,11 @@ static int base64_append_width(
lines = DIV_ROUND_UP(len, width);
slen = strlen_ptr(sep);
- if (lines > (SSIZE_MAX - plen - 1 - slen) / (indent + width + 1))
+ if (plen >= SSIZE_MAX - 1 - slen ||
+ lines > (SSIZE_MAX - plen - 1 - slen) / (indent + width + 1))
return -ENOMEM;
- t = realloc(*prefix, plen + 1 + slen + (indent + width + 1) * lines);
+ t = realloc(*prefix, (ssize_t) plen + 1 + slen + (indent + width + 1) * lines);
if (!t)
return -ENOMEM;
@@ -644,7 +645,7 @@ int base64_append(
return base64_append_width(prefix, plen, "\n", indent, p, l, width - indent - 1);
else
/* leave plen on the left, keep last column free */
- return base64_append_width(prefix, plen, NULL, plen, p, l, width - plen - 1);
+ return base64_append_width(prefix, plen, " ", plen, p, l, width - plen - 1);
}
#endif /* NM_IGNORED */
diff --git a/shared/systemd/src/basic/time-util.c b/shared/systemd/src/basic/time-util.c
index 4e609a6476..9ea0380aaa 100644
--- a/shared/systemd/src/basic/time-util.c
+++ b/shared/systemd/src/basic/time-util.c
@@ -1036,6 +1036,15 @@ int parse_sec_fix_0(const char *t, usec_t *ret) {
return r;
}
+int parse_sec_def_infinity(const char *t, usec_t *ret) {
+ t += strspn(t, WHITESPACE);
+ if (isempty(t)) {
+ *ret = USEC_INFINITY;
+ return 0;
+ }
+ return parse_sec(t, ret);
+}
+
static const char* extract_nsec_multiplier(const char *p, nsec_t *multiplier) {
static const struct {
const char *suffix;
diff --git a/shared/systemd/src/basic/time-util.h b/shared/systemd/src/basic/time-util.h
index 5316305062..a238f6914d 100644
--- a/shared/systemd/src/basic/time-util.h
+++ b/shared/systemd/src/basic/time-util.h
@@ -112,6 +112,7 @@ int parse_timestamp(const char *t, usec_t *usec);
int parse_sec(const char *t, usec_t *usec);
int parse_sec_fix_0(const char *t, usec_t *usec);
+int parse_sec_def_infinity(const char *t, usec_t *usec);
int parse_time(const char *t, usec_t *usec, usec_t default_unit);
int parse_nsec(const char *t, nsec_t *nsec);
diff --git a/shared/systemd/src/basic/util.h b/shared/systemd/src/basic/util.h
index f009d37d4c..dc33d66067 100644
--- a/shared/systemd/src/basic/util.h
+++ b/shared/systemd/src/basic/util.h
@@ -174,12 +174,21 @@ static inline void *mempset(void *s, int c, size_t n) {
}
static inline void _reset_errno_(int *saved_errno) {
+ if (*saved_errno < 0) /* Invalidated by UNPROTECT_ERRNO? */
+ return;
+
errno = *saved_errno;
}
#define PROTECT_ERRNO \
_cleanup_(_reset_errno_) _unused_ int _saved_errno_ = errno
+#define UNPROTECT_ERRNO \
+ do { \
+ errno = _saved_errno_; \
+ _saved_errno_ = -1; \
+ } while (false)
+
static inline int negative_errno(void) {
/* This helper should be used to shut up gcc if you know 'errno' is
* negative. Instead of "return -errno;", use "return negative_errno();"
diff --git a/src/systemd/sd-adapt-core/device-util.h b/src/systemd/sd-adapt-core/device-util.h
new file mode 100644
index 0000000000..637892c2d6
--- /dev/null
+++ b/src/systemd/sd-adapt-core/device-util.h
@@ -0,0 +1,3 @@
+#pragma once
+
+/* dummy header */
diff --git a/src/systemd/src/libsystemd-network/dhcp-network.c b/src/systemd/src/libsystemd-network/dhcp-network.c
index 2eedd4dd4b..810a26339a 100644
--- a/src/systemd/src/libsystemd-network/dhcp-network.c
+++ b/src/systemd/src/libsystemd-network/dhcp-network.c
@@ -51,12 +51,16 @@ static int _bind_raw_socket(int ifindex, union sockaddr_union *link,
BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, dhcp.htype)), /* A <- DHCP header type */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, arp_type, 1, 0), /* header type == arp_type ? */
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
- BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, dhcp.hlen)), /* A <- MAC address length */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, dhcp_hlen, 1, 0), /* address length == dhcp_hlen ? */
- BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.xid)), /* A <- client identifier */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, xid, 1, 0), /* client identifier == xid ? */
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
+ BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, dhcp.hlen)), /* A <- MAC address length */
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, dhcp_hlen, 1, 0), /* address length == dhcp_hlen ? */
+ BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
+
+ /* We only support MAC address length to be either 0 or 6 (ETH_ALEN). Optionally
+ * compare chaddr for ETH_ALEN bytes. */
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETH_ALEN, 0, 12), /* A (the MAC address length) == ETH_ALEN ? */
BPF_STMT(BPF_LD + BPF_IMM, unaligned_read_be32(&eth_mac->ether_addr_octet[0])), /* A <- 4 bytes of client's MAC */
BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.chaddr)), /* A <- 4 bytes of MAC from dhcp.chaddr */
@@ -69,6 +73,7 @@ static int _bind_raw_socket(int ifindex, union sockaddr_union *link,
BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* A xor X */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 1, 0), /* A == 0 ? */
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
+
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.magic)), /* A <- DHCP magic cookie */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, DHCP_MAGIC_COOKIE, 1, 0), /* cookie == DHCP magic cookie ? */
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
diff --git a/src/systemd/src/libsystemd-network/network-internal.c b/src/systemd/src/libsystemd-network/network-internal.c
index 6e9888e804..f85db47b1f 100644
--- a/src/systemd/src/libsystemd-network/network-internal.c
+++ b/src/systemd/src/libsystemd-network/network-internal.c
@@ -12,6 +12,7 @@
#include "alloc-util.h"
#include "condition.h"
#include "conf-parser.h"
+#include "device-util.h"
#include "dhcp-lease-internal.h"
#include "ether-addr-util.h"
#include "hexdecoct.h"
@@ -43,31 +44,35 @@ const char *net_get_name(sd_device *device) {
int net_get_unique_predictable_data(sd_device *device, uint64_t *result) {
size_t l, sz = 0;
- const char *name = NULL;
+ const char *name;
int r;
uint8_t *v;
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)
- return -ENOENT;
+ (void) sd_device_get_sysname(device, &name);
+ if (!name)
+ return log_device_debug_errno(device, SYNTHETIC_ERRNO(ENODATA),
+ "No stable identifying information found");
+ log_device_debug(device, "Using \"%s\" as stable identifying information", name);
l = strlen(name);
sz = sizeof(sd_id128_t) + l;
v = newa(uint8_t, sz);
- /* fetch some persistent data unique to this machine */
+ /* Fetch some persistent data unique to this machine */
r = sd_id128_get_machine((sd_id128_t*) v);
if (r < 0)
return r;
memcpy(v + sizeof(sd_id128_t), name, l);
- /* Let's hash the machine ID plus the device name. We
- * use a fixed, but originally randomly created hash
- * key here. */
+ /* Let's hash the machine ID plus the device name. We use
+ * a fixed, but originally randomly created hash key here. */
*result = htole64(siphash24(v, sz, HASH_KEY.bytes));
-
return 0;
}
@@ -105,7 +110,6 @@ bool net_match_config(Set *match_mac,
Condition *match_arch,
const struct ether_addr *dev_mac,
const char *dev_path,
- const char *dev_parent_driver,
const char *dev_driver,
const char *dev_type,
const char *dev_name) {
diff --git a/src/systemd/src/libsystemd-network/network-internal.h b/src/systemd/src/libsystemd-network/network-internal.h
index b54680f416..9119d9a4ce 100644
--- a/src/systemd/src/libsystemd-network/network-internal.h
+++ b/src/systemd/src/libsystemd-network/network-internal.h
@@ -8,7 +8,9 @@
#include "condition.h"
#include "conf-parser.h"
+#include "def.h"
#include "set.h"
+#include "strv.h"
#define LINK_BRIDGE_PORT_PRIORITY_INVALID 128
#define LINK_BRIDGE_PORT_PRIORITY_MAX 63
@@ -25,7 +27,6 @@ bool net_match_config(Set *match_mac,
Condition *match_arch,
const struct ether_addr *dev_mac,
const char *dev_path,
- const char *dev_parent_driver,
const char *dev_driver,
const char *dev_type,
const char *dev_name);
@@ -60,3 +61,5 @@ int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t
/* It is not necessary to add deserialize_dhcp_option(). Use unhexmem() instead. */
int serialize_dhcp_option(FILE *f, const char *key, const void *data, size_t size);
+
+#define NETWORK_DIRS ((const char* const*) CONF_PATHS_STRV("systemd/network"))
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-client.c b/src/systemd/src/libsystemd-network/sd-dhcp-client.c
index 20429306bd..27f7963890 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp-client.c
@@ -1680,8 +1680,7 @@ static int client_receive_message_udp(
sd_dhcp_client *client = userdata;
_cleanup_free_ DHCPMessage *message = NULL;
- const struct ether_addr zero_mac = {};
- const struct ether_addr *expected_chaddr = NULL;
+ const uint8_t *expected_chaddr = NULL;
uint8_t expected_hlen = 0;
ssize_t len, buflen;
@@ -1689,6 +1688,12 @@ static int client_receive_message_udp(
assert(client);
buflen = next_datagram_size_fd(fd);
+ if (buflen == -ENETDOWN) {
+ /* the link is down. Don't return an error or the I/O event
+ source will be disconnected and we won't be able to receive
+ packets again when the link comes back. */
+ return 0;
+ }
if (buflen < 0)
return buflen;
@@ -1698,7 +1703,8 @@ static int client_receive_message_udp(
len = recv(fd, message, buflen, 0);
if (len < 0) {
- if (IN_SET(errno, EAGAIN, EINTR))
+ /* see comment above for why we shouldn't error out on ENETDOWN. */
+ if (IN_SET(errno, EAGAIN, EINTR, ENETDOWN))
return 0;
return log_dhcp_client_errno(client, errno,
@@ -1726,11 +1732,7 @@ static int client_receive_message_udp(
if (client->arp_type == ARPHRD_ETHER) {
expected_hlen = ETH_ALEN;
- expected_chaddr = (const struct ether_addr *) &client->mac_addr;
- } else {
- /* Non-Ethernet links expect zero chaddr */
- expected_hlen = 0;
- expected_chaddr = &zero_mac;
+ expected_chaddr = &client->mac_addr[0];
}
if (message->hlen != expected_hlen) {
@@ -1738,7 +1740,7 @@ static int client_receive_message_udp(
return 0;
}
- if (memcmp(&message->chaddr[0], expected_chaddr, ETH_ALEN)) {
+ if (expected_hlen > 0 && memcmp(&message->chaddr[0], expected_chaddr, expected_hlen)) {
log_dhcp_client(client, "Received chaddr does not match expected: ignoring");
return 0;
}
@@ -1780,6 +1782,8 @@ static int client_receive_message_raw(
assert(client);
buflen = next_datagram_size_fd(fd);
+ if (buflen == -ENETDOWN)
+ return 0;
if (buflen < 0)
return buflen;
@@ -1791,7 +1795,7 @@ static int client_receive_message_raw(
len = recvmsg(fd, &msg, 0);
if (len < 0) {
- if (IN_SET(errno, EAGAIN, EINTR))
+ if (IN_SET(errno, EAGAIN, EINTR, ENETDOWN))
return 0;
return log_dhcp_client_errno(client, errno,
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
index 39dc881a41..b72cd82d9e 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
@@ -1117,6 +1117,12 @@ static int client_receive_message(
assert(client->event);
buflen = next_datagram_size_fd(fd);
+ if (buflen == -ENETDOWN) {
+ /* the link is down. Don't return an error or the I/O event
+ source will be disconnected and we won't be able to receive
+ packets again when the link comes back. */
+ return 0;
+ }
if (buflen < 0)
return buflen;
@@ -1126,7 +1132,8 @@ static int client_receive_message(
len = recv(fd, message, buflen, 0);
if (len < 0) {
- if (IN_SET(errno, EAGAIN, EINTR))
+ /* see comment above for why we shouldn't error out on ENETDOWN. */
+ if (IN_SET(errno, EAGAIN, EINTR, ENETDOWN))
return 0;
return log_dhcp6_client_errno(client, errno, "Could not receive message from UDP socket: %m");