Compare commits
4 Commits
a03cdb173e
...
c8966bffdd
Author | SHA1 | Date |
---|---|---|
Zbigniew Jędrzejewski-Szmek | c8966bffdd | |
RoadrunnerWMC | f0bad11fac | |
Yu Watanabe | 7acb7707ff | |
Susant Sahani | cb29c15605 |
|
@ -83,6 +83,9 @@ sensor:modalias:acpi:SMO8500:*:dmi:*Acer*:pnOneS1002*
|
|||
sensor:modalias:acpi:KIOX0009*:dmi:*:svnAcer:pnOneS1003:*
|
||||
ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1
|
||||
|
||||
sensor:modalias:acpi:BOSC0200*:dmi:*:svnAcer*:pnSwitchSW312-31:*
|
||||
ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1
|
||||
|
||||
#########################################
|
||||
# Archos
|
||||
#########################################
|
||||
|
|
|
@ -1609,6 +1609,15 @@
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>SendOptions=</varname></term>
|
||||
<listitem>
|
||||
<para>Send a raw option with value via DHCPv4 client. Takes a DHCP option and base64 encoded
|
||||
data separated with a colon (option:value). The option ranges [1-254]. This option can be
|
||||
specified multiple times. If an empty string is specified, then all options specified earlier
|
||||
are cleared. Defaults to unset.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
extern const struct hash_ops dhcp_option_hash_ops;
|
|
@ -3,6 +3,7 @@
|
|||
sources = files('''
|
||||
sd-dhcp-client.c
|
||||
sd-dhcp-server.c
|
||||
dhcp-client-internal.h
|
||||
dhcp-network.c
|
||||
dhcp-option.c
|
||||
dhcp-packet.c
|
||||
|
|
|
@ -35,6 +35,14 @@
|
|||
#define RESTART_AFTER_NAK_MIN_USEC (1 * USEC_PER_SEC)
|
||||
#define RESTART_AFTER_NAK_MAX_USEC (30 * USEC_PER_MINUTE)
|
||||
|
||||
struct sd_dhcp_option {
|
||||
unsigned n_ref;
|
||||
|
||||
uint8_t option;
|
||||
void *data;
|
||||
size_t length;
|
||||
};
|
||||
|
||||
struct sd_dhcp_client {
|
||||
unsigned n_ref;
|
||||
|
||||
|
@ -90,6 +98,7 @@ struct sd_dhcp_client {
|
|||
usec_t start_time;
|
||||
uint64_t attempt;
|
||||
uint64_t max_attempts;
|
||||
OrderedHashmap *options;
|
||||
usec_t request_sent;
|
||||
sd_event_source *timeout_t1;
|
||||
sd_event_source *timeout_t2;
|
||||
|
@ -530,6 +539,66 @@ int sd_dhcp_client_set_max_attempts(sd_dhcp_client *client, uint64_t max_attempt
|
|||
return 0;
|
||||
}
|
||||
|
||||
static sd_dhcp_option* dhcp_option_free(sd_dhcp_option *i) {
|
||||
if (!i)
|
||||
return NULL;
|
||||
|
||||
free(i->data);
|
||||
return mfree(i);
|
||||
}
|
||||
|
||||
int sd_dhcp_option_new(uint8_t option, void *data, size_t length, sd_dhcp_option **ret) {
|
||||
_cleanup_(sd_dhcp_option_unrefp) sd_dhcp_option *p = NULL;
|
||||
_cleanup_free_ void *q = NULL;
|
||||
|
||||
assert(ret);
|
||||
|
||||
q = memdup(data, length);
|
||||
if (!q)
|
||||
return -ENOMEM;
|
||||
|
||||
p = new(sd_dhcp_option, 1);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
*p = (sd_dhcp_option) {
|
||||
.n_ref = 1,
|
||||
.option = option,
|
||||
.length = length,
|
||||
.data = TAKE_PTR(q),
|
||||
};
|
||||
|
||||
*ret = TAKE_PTR(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_option, sd_dhcp_option, dhcp_option_free);
|
||||
DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
||||
dhcp_option_hash_ops,
|
||||
void,
|
||||
trivial_hash_func,
|
||||
trivial_compare_func,
|
||||
sd_dhcp_option,
|
||||
sd_dhcp_option_unref);
|
||||
|
||||
int sd_dhcp_client_set_dhcp_option(sd_dhcp_client *client, sd_dhcp_option *v) {
|
||||
int r;
|
||||
|
||||
assert_return(client, -EINVAL);
|
||||
assert_return(v, -EINVAL);
|
||||
|
||||
r = ordered_hashmap_ensure_allocated(&client->options, &dhcp_option_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = ordered_hashmap_put(client->options, UINT_TO_PTR(v->option), v);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
sd_dhcp_option_ref(v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) {
|
||||
assert_return(client, -EINVAL);
|
||||
|
||||
|
@ -791,6 +860,8 @@ static int dhcp_client_send_raw(
|
|||
static int client_send_discover(sd_dhcp_client *client) {
|
||||
_cleanup_free_ DHCPPacket *discover = NULL;
|
||||
size_t optoffset, optlen;
|
||||
sd_dhcp_option *j;
|
||||
Iterator i;
|
||||
int r;
|
||||
|
||||
assert(client);
|
||||
|
@ -852,6 +923,13 @@ static int client_send_discover(sd_dhcp_client *client) {
|
|||
return r;
|
||||
}
|
||||
|
||||
ORDERED_HASHMAP_FOREACH(j, client->options, i) {
|
||||
r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
|
||||
j->option, j->length, j->data);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
|
||||
SD_DHCP_OPTION_END, 0, NULL);
|
||||
if (r < 0)
|
||||
|
@ -1991,6 +2069,7 @@ static sd_dhcp_client *dhcp_client_free(sd_dhcp_client *client) {
|
|||
free(client->hostname);
|
||||
free(client->vendor_class_identifier);
|
||||
client->user_class = strv_free(client->user_class);
|
||||
ordered_hashmap_free(client->options);
|
||||
return mfree(client);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include <linux/if_arp.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "dhcp-client-internal.h"
|
||||
#include "hexdecoct.h"
|
||||
#include "hostname-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "network-internal.h"
|
||||
|
@ -1186,6 +1188,7 @@ int dhcp4_set_client_identifier(Link *link) {
|
|||
}
|
||||
|
||||
int dhcp4_configure(Link *link) {
|
||||
sd_dhcp_option *send_option;
|
||||
void *request_options;
|
||||
Iterator i;
|
||||
int r;
|
||||
|
@ -1292,6 +1295,12 @@ int dhcp4_configure(Link *link) {
|
|||
return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for '%u': %m", option);
|
||||
}
|
||||
|
||||
ORDERED_HASHMAP_FOREACH(send_option, link->network->dhcp_send_options, i) {
|
||||
r = sd_dhcp_client_set_dhcp_option(link->dhcp_client, send_option);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set send option: %m");
|
||||
}
|
||||
|
||||
r = dhcp4_set_hostname(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
@ -1557,6 +1566,90 @@ int config_parse_dhcp_request_options(
|
|||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_dhcp_send_options(
|
||||
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) {
|
||||
|
||||
_cleanup_(sd_dhcp_option_unrefp) sd_dhcp_option *opt = NULL, *old = NULL;
|
||||
_cleanup_free_ char *word = NULL;
|
||||
_cleanup_free_ void *q = NULL;
|
||||
Network *network = data;
|
||||
const char *p;
|
||||
uint8_t u;
|
||||
size_t sz;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
network->dhcp_send_options = ordered_hashmap_free(network->dhcp_send_options);
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = rvalue;
|
||||
r = extract_first_word(&p, &word, ":", 0);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r <= 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Invalid DHCP send option, ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = safe_atou8(word, &u);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Invalid DHCP send option, ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (u < 1 || u >= 255) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||
"Invalid DHCP send option, valid range is 1-254, ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = unbase64mem(p, (size_t) -1, &q, &sz);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to decode base64 data, ignoring assignment: %s", p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = sd_dhcp_option_new(u, q, sz, &opt);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to store DHCP send option '%s', ignoring assignment: %m", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = ordered_hashmap_ensure_allocated(&network->dhcp_send_options, &dhcp_option_hash_ops);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
/* Overwrite existing option */
|
||||
old = ordered_hashmap_remove(network->dhcp_send_options, UINT_TO_PTR(u));
|
||||
r = ordered_hashmap_put(network->dhcp_send_options, UINT_TO_PTR(u), opt);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to store DHCP send option '%s'", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TAKE_PTR(opt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char* const dhcp_client_identifier_table[_DHCP_CLIENT_ID_MAX] = {
|
||||
[DHCP_CLIENT_ID_MAC] = "mac",
|
||||
[DHCP_CLIENT_ID_DUID] = "duid",
|
||||
|
|
|
@ -27,3 +27,4 @@ CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_black_listed_ip_address);
|
|||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_max_attempts);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_user_class);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_request_options);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_send_options);
|
||||
|
|
|
@ -170,6 +170,7 @@ DHCPv4.ListenPort, config_parse_uint16,
|
|||
DHCPv4.SendRelease, config_parse_bool, 0, offsetof(Network, dhcp_send_release)
|
||||
DHCPv4.BlackList, config_parse_dhcp_black_listed_ip_address, 0, 0
|
||||
DHCPv4.IPServiceType, config_parse_ip_service_type, 0, offsetof(Network, ip_service_type)
|
||||
DHCPv4.SendOptions, config_parse_dhcp_send_options, 0, 0
|
||||
DHCPv6.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp6_use_dns)
|
||||
DHCPv6.UseNTP, config_parse_bool, 0, offsetof(Network, dhcp6_use_ntp)
|
||||
DHCPv6.RapidCommit, config_parse_bool, 0, offsetof(Network, rapid_commit)
|
||||
|
|
|
@ -630,6 +630,8 @@ static Network *network_free(Network *network) {
|
|||
|
||||
set_free_free(network->dnssec_negative_trust_anchors);
|
||||
|
||||
ordered_hashmap_free(network->dhcp_send_options);
|
||||
|
||||
return mfree(network);
|
||||
}
|
||||
|
||||
|
|
|
@ -87,10 +87,11 @@ struct Network {
|
|||
unsigned dhcp_route_metric;
|
||||
uint32_t dhcp_route_table;
|
||||
uint16_t dhcp_client_port;
|
||||
int dhcp_critical;
|
||||
int ip_service_type;
|
||||
bool dhcp_anonymize;
|
||||
bool dhcp_send_hostname;
|
||||
bool dhcp_broadcast;
|
||||
int dhcp_critical;
|
||||
bool dhcp_use_dns;
|
||||
bool dhcp_routes_to_dns;
|
||||
bool dhcp_use_ntp;
|
||||
|
@ -105,7 +106,7 @@ struct Network {
|
|||
DHCPUseDomains dhcp_use_domains;
|
||||
Set *dhcp_black_listed_ip;
|
||||
Set *dhcp_request_options;
|
||||
int ip_service_type;
|
||||
OrderedHashmap *dhcp_send_options;
|
||||
|
||||
/* DHCPv6 Client support*/
|
||||
bool dhcp6_use_dns;
|
||||
|
|
|
@ -99,6 +99,7 @@ enum {
|
|||
};
|
||||
|
||||
typedef struct sd_dhcp_client sd_dhcp_client;
|
||||
typedef struct sd_dhcp_option sd_dhcp_option;
|
||||
|
||||
typedef int (*sd_dhcp_client_callback_t)(sd_dhcp_client *client, int event, void *userdata);
|
||||
int sd_dhcp_client_set_callback(
|
||||
|
@ -178,6 +179,11 @@ int sd_dhcp_client_set_service_type(
|
|||
sd_dhcp_client *client,
|
||||
int type);
|
||||
|
||||
int sd_dhcp_option_new(uint8_t option, void *data, size_t length, sd_dhcp_option **ret);
|
||||
sd_dhcp_option* sd_dhcp_option_ref(sd_dhcp_option *i);
|
||||
sd_dhcp_option* sd_dhcp_option_unref(sd_dhcp_option *i);
|
||||
int sd_dhcp_client_set_dhcp_option(sd_dhcp_client *client, sd_dhcp_option *v);
|
||||
|
||||
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);
|
||||
|
@ -198,6 +204,7 @@ int sd_dhcp_client_detach_event(sd_dhcp_client *client);
|
|||
sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client);
|
||||
|
||||
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_client, sd_dhcp_client_unref);
|
||||
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_option, sd_dhcp_option_unref);
|
||||
|
||||
_SD_END_DECLARATIONS;
|
||||
|
||||
|
|
|
@ -94,6 +94,7 @@ RequestOptions=
|
|||
SendRelease=
|
||||
MaxAttempts=
|
||||
IPServiceType=
|
||||
SendOptions=
|
||||
[DHCPv6]
|
||||
UseNTP=
|
||||
UseDNS=
|
||||
|
|
|
@ -2,5 +2,6 @@
|
|||
Name=veth-peer
|
||||
|
||||
[Network]
|
||||
IPv6AcceptRA=no
|
||||
Address=2600::1/0
|
||||
Address=192.168.5.1/24
|
||||
|
|
|
@ -2,5 +2,6 @@
|
|||
Name=veth-peer
|
||||
|
||||
[Network]
|
||||
IPv6AcceptRA=no
|
||||
Address=192.168.0.1/24
|
||||
Address=192.168.5.1/24
|
||||
|
|
Loading…
Reference in New Issue