summaryrefslogtreecommitdiff
path: root/src/systemd
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-09-25 09:10:44 +0200
committerThomas Haller <thaller@redhat.com>2019-09-25 09:14:30 +0200
commit85bdf421129262357484d681be3af21ebc72c15d (patch)
tree3a34a82b88383734694097d1a55503647a9b53ec /src/systemd
parent43b7e669482822edec3dbf1d410825eb4ce02abe (diff)
parent503b5f441e7b696fb8e7b077d0e7b4c9e2991b6e (diff)
downloadNetworkManager-85bdf421129262357484d681be3af21ebc72c15d.tar.gz
systemd: merge branch systemd into master
Diffstat (limited to 'src/systemd')
-rw-r--r--src/systemd/src/libsystemd-network/dhcp-lease-internal.h3
-rw-r--r--src/systemd/src/libsystemd-network/dhcp-option.c71
-rw-r--r--src/systemd/src/libsystemd-network/network-internal.c2
-rw-r--r--src/systemd/src/libsystemd-network/sd-dhcp-client.c18
-rw-r--r--src/systemd/src/libsystemd-network/sd-dhcp-lease.c65
-rw-r--r--src/systemd/src/libsystemd-network/sd-dhcp6-client.c24
-rw-r--r--src/systemd/src/systemd/sd-dhcp-client.h2
-rw-r--r--src/systemd/src/systemd/sd-dhcp-lease.h1
-rw-r--r--src/systemd/src/systemd/sd-dhcp6-client.h1
9 files changed, 154 insertions, 33 deletions
diff --git a/src/systemd/src/libsystemd-network/dhcp-lease-internal.h b/src/systemd/src/libsystemd-network/dhcp-lease-internal.h
index 122042ab58..a2d0f8bd5e 100644
--- a/src/systemd/src/libsystemd-network/dhcp-lease-internal.h
+++ b/src/systemd/src/libsystemd-network/dhcp-lease-internal.h
@@ -58,6 +58,9 @@ struct sd_dhcp_lease {
struct in_addr *ntp;
size_t ntp_size;
+ struct in_addr *sip;
+ size_t sip_size;
+
struct sd_dhcp_route *static_route;
size_t static_route_size, static_route_allocated;
diff --git a/src/systemd/src/libsystemd-network/dhcp-option.c b/src/systemd/src/libsystemd-network/dhcp-option.c
index 50238b0a56..7690449194 100644
--- a/src/systemd/src/libsystemd-network/dhcp-option.c
+++ b/src/systemd/src/libsystemd-network/dhcp-option.c
@@ -29,7 +29,7 @@ static int option_append(uint8_t options[], size_t size, size_t *offset,
case SD_DHCP_OPTION_PAD:
case SD_DHCP_OPTION_END:
- if (size < *offset + 1)
+ if (*offset + 1 > size)
return -ENOBUFS;
options[*offset] = code;
@@ -37,42 +37,57 @@ static int option_append(uint8_t options[], size_t size, size_t *offset,
break;
case SD_DHCP_OPTION_USER_CLASS: {
- size_t len = 0;
+ size_t total = 0;
char **s;
- STRV_FOREACH(s, (char **) optval)
- len += strlen(*s) + 1;
+ STRV_FOREACH(s, (char **) optval) {
+ size_t len = strlen(*s);
+
+ if (len > 255)
+ return -ENAMETOOLONG;
+
+ total += 1 + len;
+ }
- if (size < *offset + len + 2)
+ if (*offset + 2 + total > size)
return -ENOBUFS;
options[*offset] = code;
- options[*offset + 1] = len;
+ options[*offset + 1] = total;
*offset += 2;
STRV_FOREACH(s, (char **) optval) {
- len = strlen(*s);
-
- if (len > 255)
- return -ENAMETOOLONG;
+ size_t len = strlen(*s);
options[*offset] = len;
- memcpy_safe(&options[*offset + 1], *s, len);
- *offset += len + 1;
+ memcpy(&options[*offset + 1], *s, len);
+ *offset += 1 + len;
}
break;
}
+ case SD_DHCP_OPTION_SIP_SERVER:
+ if (*offset + 3 + optlen > size)
+ return -ENOBUFS;
+
+ options[*offset] = code;
+ options[*offset + 1] = optlen + 1;
+ options[*offset + 2] = 1;
+
+ memcpy_safe(&options[*offset + 3], optval, optlen);
+ *offset += 3 + optlen;
+
+ break;
default:
- if (size < *offset + optlen + 2)
+ if (*offset + 2 + optlen > size)
return -ENOBUFS;
options[*offset] = code;
options[*offset + 1] = optlen;
memcpy_safe(&options[*offset + 2], optval, optlen);
- *offset += optlen + 2;
+ *offset += 2 + optlen;
break;
}
@@ -83,22 +98,25 @@ static int option_append(uint8_t options[], size_t size, size_t *offset,
int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset,
uint8_t overload,
uint8_t code, size_t optlen, const void *optval) {
- size_t file_offset = 0, sname_offset =0;
- bool file, sname;
+ const bool use_file = overload & DHCP_OVERLOAD_FILE;
+ const bool use_sname = overload & DHCP_OVERLOAD_SNAME;
int r;
assert(message);
assert(offset);
- file = overload & DHCP_OVERLOAD_FILE;
- sname = overload & DHCP_OVERLOAD_SNAME;
+ /* If *offset is in range [0, size), we are writing to ->options,
+ * if *offset is in range [size, size + sizeof(message->file)) and use_file, we are writing to ->file,
+ * if *offset is in range [size + use_file*sizeof(message->file), size + use_file*sizeof(message->file) + sizeof(message->sname))
+ * and use_sname, we are writing to ->sname.
+ */
if (*offset < size) {
/* still space in the options array */
r = option_append(message->options, size, offset, code, optlen, optval);
if (r >= 0)
return 0;
- else if (r == -ENOBUFS && (file || sname)) {
+ else if (r == -ENOBUFS && (use_file || use_sname)) {
/* did not fit, but we have more buffers to try
close the options array and move the offset to its end */
r = option_append(message->options, size, offset, SD_DHCP_OPTION_END, 0, NULL);
@@ -110,8 +128,8 @@ int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset,
return r;
}
- if (overload & DHCP_OVERLOAD_FILE) {
- file_offset = *offset - size;
+ if (use_file) {
+ size_t file_offset = *offset - size;
if (file_offset < sizeof(message->file)) {
/* still space in the 'file' array */
@@ -119,7 +137,7 @@ int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset,
if (r >= 0) {
*offset = size + file_offset;
return 0;
- } else if (r == -ENOBUFS && sname) {
+ } else if (r == -ENOBUFS && use_sname) {
/* did not fit, but we have more buffers to try
close the file array and move the offset to its end */
r = option_append(message->options, size, offset, SD_DHCP_OPTION_END, 0, NULL);
@@ -132,19 +150,18 @@ int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset,
}
}
- if (overload & DHCP_OVERLOAD_SNAME) {
- sname_offset = *offset - size - (file ? sizeof(message->file) : 0);
+ if (use_sname) {
+ size_t sname_offset = *offset - size - use_file*sizeof(message->file);
if (sname_offset < sizeof(message->sname)) {
/* still space in the 'sname' array */
r = option_append(message->sname, sizeof(message->sname), &sname_offset, code, optlen, optval);
if (r >= 0) {
- *offset = size + (file ? sizeof(message->file) : 0) + sname_offset;
+ *offset = size + use_file*sizeof(message->file) + sname_offset;
return 0;
- } else {
+ } else
/* no space, or other error, give up */
return r;
- }
}
}
diff --git a/src/systemd/src/libsystemd-network/network-internal.c b/src/systemd/src/libsystemd-network/network-internal.c
index 209ce88439..07d459f6fe 100644
--- a/src/systemd/src/libsystemd-network/network-internal.c
+++ b/src/systemd/src/libsystemd-network/network-internal.c
@@ -257,7 +257,7 @@ int config_parse_match_strv(
for (;;) {
_cleanup_free_ char *word = NULL, *k = NULL;
- r = extract_first_word(&p, &word, NULL, EXTRACT_UNQUOTE);
+ r = extract_first_word(&p, &word, NULL, EXTRACT_UNQUOTE|EXTRACT_RETAIN_ESCAPE);
if (r == 0)
return 0;
if (r == -ENOMEM)
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-client.c b/src/systemd/src/libsystemd-network/sd-dhcp-client.c
index 2f531bc7b2..cbea676dd7 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp-client.c
@@ -1000,15 +1000,14 @@ static int client_send_request(sd_dhcp_client *client) {
if (r < 0)
return r;
- if (client->state == DHCP_STATE_RENEWING) {
+ if (client->state == DHCP_STATE_RENEWING)
r = dhcp_network_send_udp_socket(client->fd,
client->lease->server_address,
DHCP_PORT_SERVER,
&request->dhcp,
sizeof(DHCPMessage) + optoffset);
- } else {
+ else
r = dhcp_client_send_raw(client, request, sizeof(DHCPPacket) + optoffset);
- }
if (r < 0)
return r;
@@ -1216,7 +1215,7 @@ static int client_initialize_time_events(sd_dhcp_client *client) {
assert(client);
assert(client->event);
- if (client->start_delay) {
+ if (client->start_delay > 0) {
assert_se(sd_event_now(client->event, clock_boottime_or_monotonic(), &usec) >= 0);
usec += client->start_delay;
}
@@ -1887,6 +1886,17 @@ static int client_receive_message_raw(
return client_handle_message(client, &packet->dhcp, len);
}
+int sd_dhcp_client_send_renew(sd_dhcp_client *client) {
+ assert_return(client, -EINVAL);
+ assert_return(client->fd >= 0, -EINVAL);
+
+ client->start_delay = 0;
+ client->attempt = 1;
+ client->state = DHCP_STATE_RENEWING;
+
+ return client_initialize_time_events(client);
+}
+
int sd_dhcp_client_start(sd_dhcp_client *client) {
int r;
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-lease.c b/src/systemd/src/libsystemd-network/sd-dhcp-lease.c
index 7559d06696..3bf9c02064 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp-lease.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp-lease.c
@@ -122,6 +122,17 @@ int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr) {
return (int) lease->ntp_size;
}
+int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr) {
+ assert_return(lease, -EINVAL);
+ assert_return(addr, -EINVAL);
+
+ if (lease->sip_size <= 0)
+ return -ENODATA;
+
+ *addr = lease->sip;
+ return (int) lease->sip_size;
+}
+
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname) {
assert_return(lease, -EINVAL);
assert_return(domainname, -EINVAL);
@@ -271,6 +282,7 @@ static sd_dhcp_lease *dhcp_lease_free(sd_dhcp_lease *lease) {
free(lease->domainname);
free(lease->dns);
free(lease->ntp);
+ free(lease->sip);
free(lease->static_route);
free(lease->client_id);
free(lease->vendor_specific);
@@ -404,6 +416,36 @@ static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_add
return 0;
}
+static int lease_parse_sip_server(const uint8_t *option, size_t len, struct in_addr **ret, size_t *n_ret) {
+ assert(option);
+ assert(ret);
+ assert(n_ret);
+
+ if (len <= 0) {
+ *ret = mfree(*ret);
+ *n_ret = 0;
+ } else {
+ size_t n_addresses;
+ struct in_addr *addresses;
+ int l = len - 1;
+
+ if (l % 4 != 0)
+ return -EINVAL;
+
+ n_addresses = l / 4;
+
+ addresses = newdup(struct in_addr, option + 1, n_addresses);
+ if (!addresses)
+ return -ENOMEM;
+
+ free(*ret);
+ *ret = addresses;
+ *n_ret = n_addresses;
+ }
+
+ return 0;
+}
+
static int lease_parse_routes(
const uint8_t *option, size_t len,
struct sd_dhcp_route **routes, size_t *routes_size, size_t *routes_allocated) {
@@ -557,6 +599,12 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
log_debug_errno(r, "Failed to parse NTP server, ignoring: %m");
break;
+ case SD_DHCP_OPTION_SIP_SERVER:
+ r = lease_parse_sip_server(option, len, &lease->sip, &lease->sip_size);
+ if (r < 0)
+ log_debug_errno(r, "Failed to parse SIP server, ignoring: %m");
+ break;
+
case SD_DHCP_OPTION_STATIC_ROUTE:
r = lease_parse_routes(option, len, &lease->static_route, &lease->static_route_size, &lease->static_route_allocated);
if (r < 0)
@@ -895,6 +943,13 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
fputc('\n', f);
}
+ r = sd_dhcp_lease_get_sip(lease, &addresses);
+ if (r > 0) {
+ fputs("SIP=", f);
+ serialize_in_addrs(f, addresses, r, false, NULL);
+ fputc('\n', f);
+ }
+
r = sd_dhcp_lease_get_domainname(lease, &string);
if (r >= 0)
fprintf(f, "DOMAINNAME=%s\n", string);
@@ -985,6 +1040,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
*broadcast = NULL,
*dns = NULL,
*ntp = NULL,
+ *sip = NULL,
*mtu = NULL,
*routes = NULL,
*domains = NULL,
@@ -1013,6 +1069,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
"BROADCAST", &broadcast,
"DNS", &dns,
"NTP", &ntp,
+ "SIP", &sip,
"MTU", &mtu,
"DOMAINNAME", &lease->domainname,
"HOSTNAME", &lease->hostname,
@@ -1117,6 +1174,14 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
lease->ntp_size = r;
}
+ if (sip) {
+ r = deserialize_in_addrs(&lease->sip, sip);
+ if (r < 0)
+ log_debug_errno(r, "Failed to deserialize SIP servers %s, ignoring: %m", sip);
+ else
+ lease->ntp_size = r;
+ }
+
if (mtu) {
r = safe_atou16(mtu, &lease->mtu);
if (r < 0)
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
index f67a45bd2a..f5b5ce6b94 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
@@ -31,6 +31,9 @@
#define MAX_MAC_ADDR_LEN INFINIBAND_ALEN
+#define IRT_DEFAULT (1 * USEC_PER_DAY)
+#define IRT_MINIMUM (600 * USEC_PER_SEC)
+
/* what to request from the server, addresses (IA_NA) and/or prefixes (IA_PD) */
enum {
DHCP6_REQUEST_IA_NA = 1,
@@ -73,6 +76,8 @@ struct sd_dhcp6_client {
void *userdata;
struct duid duid;
size_t duid_len;
+ usec_t information_request_time_usec;
+ usec_t information_refresh_time_usec;
};
static const uint16_t default_req_opts[] = {
@@ -826,6 +831,7 @@ static int client_parse_message(
uint32_t lt_t1 = ~0, lt_t2 = ~0;
bool clientid = false;
size_t pos = 0;
+ usec_t irt = IRT_DEFAULT;
int r;
assert(client);
@@ -1000,6 +1006,13 @@ static int client_parse_message(
return r;
break;
+
+ case SD_DHCP6_OPTION_INFORMATION_REFRESH_TIME:
+ if (optlen != 4)
+ return -EINVAL;
+
+ irt = unaligned_read_be32((be32_t *) optval) * USEC_PER_SEC;
+ break;
}
pos += offsetof(DHCP6Option, data) + optlen;
@@ -1031,6 +1044,8 @@ static int client_parse_message(
}
}
+ client->information_refresh_time_usec = MAX(irt, IRT_MINIMUM);
+
return 0;
}
@@ -1431,8 +1446,15 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client) {
client->fd = r;
}
- if (client->information_request)
+ if (client->information_request) {
+ usec_t t = now(CLOCK_MONOTONIC);
+
+ if (t < usec_add(client->information_request_time_usec, client->information_refresh_time_usec))
+ return 0;
+
+ client->information_request_time_usec = t;
state = DHCP6_STATE_INFORMATION_REQUEST;
+ }
log_dhcp6_client(client, "Started in %s mode",
client->information_request? "Information request":
diff --git a/src/systemd/src/systemd/sd-dhcp-client.h b/src/systemd/src/systemd/sd-dhcp-client.h
index ab62368e9c..d2d74b2b4c 100644
--- a/src/systemd/src/systemd/sd-dhcp-client.h
+++ b/src/systemd/src/systemd/sd-dhcp-client.h
@@ -87,6 +87,7 @@ enum {
SD_DHCP_OPTION_NEW_POSIX_TIMEZONE = 100,
SD_DHCP_OPTION_NEW_TZDB_TIMEZONE = 101,
SD_DHCP_OPTION_DOMAIN_SEARCH_LIST = 119,
+ SD_DHCP_OPTION_SIP_SERVER = 120,
SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121,
SD_DHCP_OPTION_PRIVATE_BASE = 224,
/* Windows 10 option to send when Anonymize=true */
@@ -177,6 +178,7 @@ int sd_dhcp_client_get_lease(
int sd_dhcp_client_stop(sd_dhcp_client *client);
int sd_dhcp_client_start(sd_dhcp_client *client);
int sd_dhcp_client_send_release(sd_dhcp_client *client);
+int sd_dhcp_client_send_renew(sd_dhcp_client *client);
sd_dhcp_client *sd_dhcp_client_ref(sd_dhcp_client *client);
sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client);
diff --git a/src/systemd/src/systemd/sd-dhcp-lease.h b/src/systemd/src/systemd/sd-dhcp-lease.h
index d299c79121..b80d607fea 100644
--- a/src/systemd/src/systemd/sd-dhcp-lease.h
+++ b/src/systemd/src/systemd/sd-dhcp-lease.h
@@ -44,6 +44,7 @@ int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr);
int sd_dhcp_lease_get_server_identifier(sd_dhcp_lease *lease, struct in_addr *addr);
int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr);
+int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu);
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname);
int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains);
diff --git a/src/systemd/src/systemd/sd-dhcp6-client.h b/src/systemd/src/systemd/sd-dhcp6-client.h
index 43d38f5c7d..3aac3f14fe 100644
--- a/src/systemd/src/systemd/sd-dhcp6-client.h
+++ b/src/systemd/src/systemd/sd-dhcp6-client.h
@@ -66,6 +66,7 @@ enum {
SD_DHCP6_OPTION_IA_PD_PREFIX = 26, /* RFC 3633, prefix delegation */
SD_DHCP6_OPTION_SNTP_SERVERS = 31, /* RFC 4075, deprecated */
+ SD_DHCP6_OPTION_INFORMATION_REFRESH_TIME = 32, /* RFC 8415, sec. 21.23 */
/* option code 35 is unassigned */